mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Code styling tweaks to the Alexa integration (#86121)
This commit is contained in:
parent
b722a7e05b
commit
91aaca6471
@ -135,16 +135,16 @@ class AlexaCapability:
|
|||||||
def configuration(self):
|
def configuration(self):
|
||||||
"""Return the configuration object.
|
"""Return the configuration object.
|
||||||
|
|
||||||
Applicable to the ThermostatController, SecurityControlPanel, ModeController, RangeController,
|
Applicable to the ThermostatController, SecurityControlPanel, ModeController,
|
||||||
and EventDetectionSensor.
|
RangeController, and EventDetectionSensor.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def configurations(self):
|
def configurations(self):
|
||||||
"""Return the configurations object.
|
"""Return the configurations object.
|
||||||
|
|
||||||
The plural configurations object is different that the singular configuration object.
|
The plural configurations object is different that the singular configuration
|
||||||
Applicable to EqualizerController interface.
|
object. Applicable to EqualizerController interface.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -196,7 +196,8 @@ class AlexaCapability:
|
|||||||
if configuration := self.configuration():
|
if configuration := self.configuration():
|
||||||
result["configuration"] = configuration
|
result["configuration"] = configuration
|
||||||
|
|
||||||
# The plural configurations object is different than the singular configuration object above.
|
# The plural configurations object is different than the singular
|
||||||
|
# configuration object above.
|
||||||
if configurations := self.configurations():
|
if configurations := self.configurations():
|
||||||
result["configurations"] = configurations
|
result["configurations"] = configurations
|
||||||
|
|
||||||
@ -757,7 +758,8 @@ class AlexaPlaybackController(AlexaCapability):
|
|||||||
def supported_operations(self):
|
def supported_operations(self):
|
||||||
"""Return the supportedOperations object.
|
"""Return the supportedOperations object.
|
||||||
|
|
||||||
Supported Operations: FastForward, Next, Pause, Play, Previous, Rewind, StartOver, Stop
|
Supported Operations: FastForward, Next, Pause, Play, Previous, Rewind,
|
||||||
|
StartOver, Stop
|
||||||
"""
|
"""
|
||||||
supported_features = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
supported_features = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||||
|
|
||||||
@ -1117,7 +1119,9 @@ class AlexaThermostatController(AlexaCapability):
|
|||||||
def configuration(self):
|
def configuration(self):
|
||||||
"""Return configuration object.
|
"""Return configuration object.
|
||||||
|
|
||||||
Translates climate HVAC_MODES and PRESETS to supported Alexa ThermostatMode Values.
|
Translates climate HVAC_MODES and PRESETS to supported Alexa
|
||||||
|
ThermostatMode Values.
|
||||||
|
|
||||||
ThermostatMode Value must be AUTO, COOL, HEAT, ECO, OFF, or CUSTOM.
|
ThermostatMode Value must be AUTO, COOL, HEAT, ECO, OFF, or CUSTOM.
|
||||||
"""
|
"""
|
||||||
supported_modes = []
|
supported_modes = []
|
||||||
@ -1133,7 +1137,8 @@ class AlexaThermostatController(AlexaCapability):
|
|||||||
if thermostat_mode:
|
if thermostat_mode:
|
||||||
supported_modes.append(thermostat_mode)
|
supported_modes.append(thermostat_mode)
|
||||||
|
|
||||||
# Return False for supportsScheduling until supported with event listener in handler.
|
# Return False for supportsScheduling until supported with event
|
||||||
|
# listener in handler.
|
||||||
configuration = {"supportsScheduling": False}
|
configuration = {"supportsScheduling": False}
|
||||||
|
|
||||||
if supported_modes:
|
if supported_modes:
|
||||||
@ -1270,12 +1275,15 @@ class AlexaSecurityPanelController(AlexaCapability):
|
|||||||
class AlexaModeController(AlexaCapability):
|
class AlexaModeController(AlexaCapability):
|
||||||
"""Implements Alexa.ModeController.
|
"""Implements Alexa.ModeController.
|
||||||
|
|
||||||
The instance property must be unique across ModeController, RangeController, ToggleController within the same device.
|
The instance property must be unique across ModeController, RangeController,
|
||||||
The instance property should be a concatenated string of device domain period and single word.
|
ToggleController within the same device.
|
||||||
e.g. fan.speed & fan.direction.
|
|
||||||
|
|
||||||
The instance property must not contain words from other instance property strings within the same device.
|
The instance property should be a concatenated string of device domain period
|
||||||
e.g. Instance property cover.position & cover.tilt_position will cause the Alexa.Discovery directive to fail.
|
and single word. e.g. fan.speed & fan.direction.
|
||||||
|
|
||||||
|
The instance property must not contain words from other instance property
|
||||||
|
strings within the same device. e.g. Instance property cover.position &
|
||||||
|
cover.tilt_position will cause the Alexa.Discovery directive to fail.
|
||||||
|
|
||||||
An instance property string value may be reused for different devices.
|
An instance property string value may be reused for different devices.
|
||||||
|
|
||||||
@ -1408,8 +1416,8 @@ class AlexaModeController(AlexaCapability):
|
|||||||
modes = self.entity.attributes.get(humidifier.ATTR_AVAILABLE_MODES, [])
|
modes = self.entity.attributes.get(humidifier.ATTR_AVAILABLE_MODES, [])
|
||||||
for mode in modes:
|
for mode in modes:
|
||||||
self._resource.add_mode(f"{humidifier.ATTR_MODE}.{mode}", [mode])
|
self._resource.add_mode(f"{humidifier.ATTR_MODE}.{mode}", [mode])
|
||||||
# Humidifiers or Fans with a single mode completely break Alexa discovery, add a
|
# Humidifiers or Fans with a single mode completely break Alexa discovery,
|
||||||
# fake preset (see issue #53832).
|
# add a fake preset (see issue #53832).
|
||||||
if len(modes) == 1:
|
if len(modes) == 1:
|
||||||
self._resource.add_mode(
|
self._resource.add_mode(
|
||||||
f"{humidifier.ATTR_MODE}.{PRESET_MODE_NA}", [PRESET_MODE_NA]
|
f"{humidifier.ATTR_MODE}.{PRESET_MODE_NA}", [PRESET_MODE_NA]
|
||||||
@ -1479,12 +1487,15 @@ class AlexaModeController(AlexaCapability):
|
|||||||
class AlexaRangeController(AlexaCapability):
|
class AlexaRangeController(AlexaCapability):
|
||||||
"""Implements Alexa.RangeController.
|
"""Implements Alexa.RangeController.
|
||||||
|
|
||||||
The instance property must be unique across ModeController, RangeController, ToggleController within the same device.
|
The instance property must be unique across ModeController, RangeController,
|
||||||
The instance property should be a concatenated string of device domain period and single word.
|
ToggleController within the same device.
|
||||||
e.g. fan.speed & fan.direction.
|
|
||||||
|
|
||||||
The instance property must not contain words from other instance property strings within the same device.
|
The instance property should be a concatenated string of device domain period
|
||||||
e.g. Instance property cover.position & cover.tilt_position will cause the Alexa.Discovery directive to fail.
|
and single word. e.g. fan.speed & fan.direction.
|
||||||
|
|
||||||
|
The instance property must not contain words from other instance property
|
||||||
|
strings within the same device. e.g. Instance property cover.position &
|
||||||
|
cover.tilt_position will cause the Alexa.Discovery directive to fail.
|
||||||
|
|
||||||
An instance property string value may be reused for different devices.
|
An instance property string value may be reused for different devices.
|
||||||
|
|
||||||
@ -1538,7 +1549,8 @@ class AlexaRangeController(AlexaCapability):
|
|||||||
raise UnsupportedProperty(name)
|
raise UnsupportedProperty(name)
|
||||||
|
|
||||||
# Return None for unavailable and unknown states.
|
# Return None for unavailable and unknown states.
|
||||||
# Allows the Alexa.EndpointHealth Interface to handle the unavailable state in a stateReport.
|
# Allows the Alexa.EndpointHealth Interface to handle the unavailable
|
||||||
|
# state in a stateReport.
|
||||||
if self.entity.state in (STATE_UNAVAILABLE, STATE_UNKNOWN, None):
|
if self.entity.state in (STATE_UNAVAILABLE, STATE_UNKNOWN, None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -1760,12 +1772,15 @@ class AlexaRangeController(AlexaCapability):
|
|||||||
class AlexaToggleController(AlexaCapability):
|
class AlexaToggleController(AlexaCapability):
|
||||||
"""Implements Alexa.ToggleController.
|
"""Implements Alexa.ToggleController.
|
||||||
|
|
||||||
The instance property must be unique across ModeController, RangeController, ToggleController within the same device.
|
The instance property must be unique across ModeController, RangeController,
|
||||||
The instance property should be a concatenated string of device domain period and single word.
|
ToggleController within the same device.
|
||||||
e.g. fan.speed & fan.direction.
|
|
||||||
|
|
||||||
The instance property must not contain words from other instance property strings within the same device.
|
The instance property should be a concatenated string of device domain period
|
||||||
e.g. Instance property cover.position & cover.tilt_position will cause the Alexa.Discovery directive to fail.
|
and single word. e.g. fan.speed & fan.direction.
|
||||||
|
|
||||||
|
The instance property must not contain words from other instance property
|
||||||
|
strings within the same device. e.g. Instance property cover.position
|
||||||
|
& cover.tilt_position will cause the Alexa.Discovery directive to fail.
|
||||||
|
|
||||||
An instance property string value may be reused for different devices.
|
An instance property string value may be reused for different devices.
|
||||||
|
|
||||||
@ -2021,7 +2036,8 @@ class AlexaEventDetectionSensor(AlexaCapability):
|
|||||||
state = self.entity.state
|
state = self.entity.state
|
||||||
|
|
||||||
# Return None for unavailable and unknown states.
|
# Return None for unavailable and unknown states.
|
||||||
# Allows the Alexa.EndpointHealth Interface to handle the unavailable state in a stateReport.
|
# Allows the Alexa.EndpointHealth Interface to handle the unavailable
|
||||||
|
# state in a stateReport.
|
||||||
if state in (STATE_UNAVAILABLE, STATE_UNKNOWN, None):
|
if state in (STATE_UNAVAILABLE, STATE_UNKNOWN, None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -2089,7 +2105,8 @@ class AlexaEqualizerController(AlexaCapability):
|
|||||||
def properties_supported(self):
|
def properties_supported(self):
|
||||||
"""Return what properties this entity supports.
|
"""Return what properties this entity supports.
|
||||||
|
|
||||||
Either bands, mode or both can be specified. Only mode is supported at this time.
|
Either bands, mode or both can be specified. Only mode is supported
|
||||||
|
at this time.
|
||||||
"""
|
"""
|
||||||
return [{"name": "mode"}]
|
return [{"name": "mode"}]
|
||||||
|
|
||||||
|
@ -103,7 +103,8 @@ class DisplayCategory:
|
|||||||
# Indicates a device that cools the air in interior spaces.
|
# Indicates a device that cools the air in interior spaces.
|
||||||
AIR_CONDITIONER = "AIR_CONDITIONER"
|
AIR_CONDITIONER = "AIR_CONDITIONER"
|
||||||
|
|
||||||
# Indicates a device that emits pleasant odors and masks unpleasant odors in interior spaces.
|
# Indicates a device that emits pleasant odors and masks unpleasant
|
||||||
|
# odors in interior spaces.
|
||||||
AIR_FRESHENER = "AIR_FRESHENER"
|
AIR_FRESHENER = "AIR_FRESHENER"
|
||||||
|
|
||||||
# Indicates a device that improves the quality of air in interior spaces.
|
# Indicates a device that improves the quality of air in interior spaces.
|
||||||
@ -143,7 +144,8 @@ class DisplayCategory:
|
|||||||
GAME_CONSOLE = "GAME_CONSOLE"
|
GAME_CONSOLE = "GAME_CONSOLE"
|
||||||
|
|
||||||
# Indicates a garage door.
|
# Indicates a garage door.
|
||||||
# Garage doors must implement the ModeController interface to open and close the door.
|
# Garage doors must implement the ModeController interface to
|
||||||
|
# open and close the door.
|
||||||
GARAGE_DOOR = "GARAGE_DOOR"
|
GARAGE_DOOR = "GARAGE_DOOR"
|
||||||
|
|
||||||
# Indicates a wearable device that transmits audio directly into the ear.
|
# Indicates a wearable device that transmits audio directly into the ear.
|
||||||
@ -206,8 +208,8 @@ class DisplayCategory:
|
|||||||
# Indicates a security system.
|
# Indicates a security system.
|
||||||
SECURITY_SYSTEM = "SECURITY_SYSTEM"
|
SECURITY_SYSTEM = "SECURITY_SYSTEM"
|
||||||
|
|
||||||
# Indicates an electric cooking device that sits on a countertop, cooks at low temperatures,
|
# Indicates an electric cooking device that sits on a countertop,
|
||||||
# and is often shaped like a cooking pot.
|
# cooks at low temperatures, and is often shaped like a cooking pot.
|
||||||
SLOW_COOKER = "SLOW_COOKER"
|
SLOW_COOKER = "SLOW_COOKER"
|
||||||
|
|
||||||
# Indicates an endpoint that locks.
|
# Indicates an endpoint that locks.
|
||||||
@ -243,7 +245,8 @@ class DisplayCategory:
|
|||||||
# Indicates a vacuum cleaner.
|
# Indicates a vacuum cleaner.
|
||||||
VACUUM_CLEANER = "VACUUM_CLEANER"
|
VACUUM_CLEANER = "VACUUM_CLEANER"
|
||||||
|
|
||||||
# Indicates a network-connected wearable device, such as an Apple Watch, Fitbit, or Samsung Gear.
|
# Indicates a network-connected wearable device, such as an Apple Watch,
|
||||||
|
# Fitbit, or Samsung Gear.
|
||||||
WEARABLE = "WEARABLE"
|
WEARABLE = "WEARABLE"
|
||||||
|
|
||||||
|
|
||||||
@ -574,9 +577,10 @@ class FanCapabilities(AlexaEntity):
|
|||||||
force_range_controller = False
|
force_range_controller = False
|
||||||
|
|
||||||
# AlexaRangeController controls the Fan Speed Percentage.
|
# AlexaRangeController controls the Fan Speed Percentage.
|
||||||
# For fans which only support on/off, no controller is added. This makes the
|
# For fans which only support on/off, no controller is added. This makes
|
||||||
# fan impossible to turn on or off through Alexa, most likely due to a bug in Alexa.
|
# the fan impossible to turn on or off through Alexa, most likely due
|
||||||
# As a workaround, we add a range controller which can only be set to 0% or 100%.
|
# to a bug in Alexa. As a workaround, we add a range controller which
|
||||||
|
# can only be set to 0% or 100%.
|
||||||
if force_range_controller or supported & fan.FanEntityFeature.SET_SPEED:
|
if force_range_controller or supported & fan.FanEntityFeature.SET_SPEED:
|
||||||
yield AlexaRangeController(
|
yield AlexaRangeController(
|
||||||
self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}"
|
self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}"
|
||||||
|
@ -613,9 +613,10 @@ async def async_api_adjust_volume_step(
|
|||||||
"""Process an adjust volume step request."""
|
"""Process an adjust volume step request."""
|
||||||
# media_player volume up/down service does not support specifying steps
|
# media_player volume up/down service does not support specifying steps
|
||||||
# each component handles it differently e.g. via config.
|
# each component handles it differently e.g. via config.
|
||||||
# This workaround will simply call the volume up/Volume down the amount of steps asked for
|
# This workaround will simply call the volume up/Volume down the amount of
|
||||||
# When no steps are called in the request, Alexa sends a default of 10 steps which for most
|
# steps asked for. When no steps are called in the request, Alexa sends
|
||||||
# purposes is too high. The default is set 1 in this case.
|
# a default of 10 steps which for most purposes is too high. The default
|
||||||
|
# is set 1 in this case.
|
||||||
entity = directive.entity
|
entity = directive.entity
|
||||||
volume_int = int(directive.payload["volumeSteps"])
|
volume_int = int(directive.payload["volumeSteps"])
|
||||||
is_default = bool(directive.payload["volumeStepsDefault"])
|
is_default = bool(directive.payload["volumeStepsDefault"])
|
||||||
@ -1020,8 +1021,9 @@ async def async_api_disarm(
|
|||||||
data = {ATTR_ENTITY_ID: entity.entity_id}
|
data = {ATTR_ENTITY_ID: entity.entity_id}
|
||||||
response = directive.response()
|
response = directive.response()
|
||||||
|
|
||||||
# Per Alexa Documentation: If you receive a Disarm directive, and the system is already disarmed,
|
# Per Alexa Documentation: If you receive a Disarm directive, and the
|
||||||
# respond with a success response, not an error response.
|
# system is already disarmed, respond with a success response,
|
||||||
|
# not an error response.
|
||||||
if entity.state == STATE_ALARM_DISARMED:
|
if entity.state == STATE_ALARM_DISARMED:
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@ -1136,7 +1138,8 @@ async def async_api_adjust_mode(
|
|||||||
Only supportedModes with ordered=True support the adjustMode directive.
|
Only supportedModes with ordered=True support the adjustMode directive.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Currently no supportedModes are configured with ordered=True to support this request.
|
# Currently no supportedModes are configured with ordered=True
|
||||||
|
# to support this request.
|
||||||
raise AlexaInvalidDirectiveError(DIRECTIVE_NOT_SUPPORTED)
|
raise AlexaInvalidDirectiveError(DIRECTIVE_NOT_SUPPORTED)
|
||||||
|
|
||||||
|
|
||||||
@ -1483,7 +1486,9 @@ async def async_api_changechannel(
|
|||||||
data = {
|
data = {
|
||||||
ATTR_ENTITY_ID: entity.entity_id,
|
ATTR_ENTITY_ID: entity.entity_id,
|
||||||
media_player.const.ATTR_MEDIA_CONTENT_ID: channel,
|
media_player.const.ATTR_MEDIA_CONTENT_ID: channel,
|
||||||
media_player.const.ATTR_MEDIA_CONTENT_TYPE: media_player.const.MEDIA_TYPE_CHANNEL,
|
media_player.const.ATTR_MEDIA_CONTENT_TYPE: (
|
||||||
|
media_player.const.MEDIA_TYPE_CHANNEL
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
|
@ -6,12 +6,15 @@ class AlexaGlobalCatalog:
|
|||||||
|
|
||||||
https://developer.amazon.com/docs/device-apis/resources-and-assets.html#global-alexa-catalog
|
https://developer.amazon.com/docs/device-apis/resources-and-assets.html#global-alexa-catalog
|
||||||
|
|
||||||
You can use the global Alexa catalog for pre-defined names of devices, settings, values, and units.
|
You can use the global Alexa catalog for pre-defined names of devices, settings,
|
||||||
This catalog is localized into all the languages that Alexa supports.
|
values, and units.
|
||||||
|
|
||||||
|
This catalog is localized into all the languages that Alexa supports.
|
||||||
You can reference the following catalog of pre-defined friendly names.
|
You can reference the following catalog of pre-defined friendly names.
|
||||||
Each item in the following list is an asset identifier followed by its supported friendly names.
|
|
||||||
The first friendly name for each identifier is the one displayed in the Alexa mobile app.
|
Each item in the following list is an asset identifier followed by its
|
||||||
|
supported friendly names. The first friendly name for each identifier is
|
||||||
|
the one displayed in the Alexa mobile app.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Air Purifier, Air Cleaner,Clean Air Machine
|
# Air Purifier, Air Cleaner,Clean Air Machine
|
||||||
@ -23,7 +26,8 @@ class AlexaGlobalCatalog:
|
|||||||
# Router, Internet Router, Network Router, Wifi Router, Net Router
|
# Router, Internet Router, Network Router, Wifi Router, Net Router
|
||||||
DEVICE_NAME_ROUTER = "Alexa.DeviceName.Router"
|
DEVICE_NAME_ROUTER = "Alexa.DeviceName.Router"
|
||||||
|
|
||||||
# Shade, Blind, Curtain, Roller, Shutter, Drape, Awning, Window shade, Interior blind
|
# Shade, Blind, Curtain, Roller, Shutter, Drape, Awning,
|
||||||
|
# Window shade, Interior blind
|
||||||
DEVICE_NAME_SHADE = "Alexa.DeviceName.Shade"
|
DEVICE_NAME_SHADE = "Alexa.DeviceName.Shade"
|
||||||
|
|
||||||
# Shower
|
# Shower
|
||||||
@ -190,10 +194,13 @@ class AlexaGlobalCatalog:
|
|||||||
|
|
||||||
|
|
||||||
class AlexaCapabilityResource:
|
class AlexaCapabilityResource:
|
||||||
"""Base class for Alexa capabilityResources, modeResources, and presetResources objects.
|
"""Base class for Alexa capabilityResources, modeResources, and presetResources.
|
||||||
|
|
||||||
|
Resources objects labels must be unique across all modeResources and
|
||||||
|
presetResources within the same device. To provide support for all
|
||||||
|
supported locales, include one label from the AlexaGlobalCatalog in the
|
||||||
|
labels array.
|
||||||
|
|
||||||
Resources objects labels must be unique across all modeResources and presetResources within the same device.
|
|
||||||
To provide support for all supported locales, include one label from the AlexaGlobalCatalog in the labels array.
|
|
||||||
You cannot use any words from the following list as friendly names:
|
You cannot use any words from the following list as friendly names:
|
||||||
https://developer.amazon.com/docs/alexa/device-apis/resources-and-assets.html#names-you-cannot-use
|
https://developer.amazon.com/docs/alexa/device-apis/resources-and-assets.html#names-you-cannot-use
|
||||||
|
|
||||||
@ -211,11 +218,17 @@ class AlexaCapabilityResource:
|
|||||||
return self.serialize_labels(self._resource_labels)
|
return self.serialize_labels(self._resource_labels)
|
||||||
|
|
||||||
def serialize_configuration(self):
|
def serialize_configuration(self):
|
||||||
"""Return ModeResources, PresetResources friendlyNames serialized for an API response."""
|
"""Return serialized configuration for an API response.
|
||||||
|
|
||||||
|
Return ModeResources, PresetResources friendlyNames serialized.
|
||||||
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def serialize_labels(self, resources):
|
def serialize_labels(self, resources):
|
||||||
"""Return resource label objects for friendlyNames serialized for an API response."""
|
"""Return serialized labels for an API response.
|
||||||
|
|
||||||
|
Returns resource label objects for friendlyNames serialized.
|
||||||
|
"""
|
||||||
labels = []
|
labels = []
|
||||||
for label in resources:
|
for label in resources:
|
||||||
if label in AlexaGlobalCatalog.__dict__.values():
|
if label in AlexaGlobalCatalog.__dict__.values():
|
||||||
@ -245,7 +258,10 @@ class AlexaModeResource(AlexaCapabilityResource):
|
|||||||
self._supported_modes.append({"value": value, "labels": labels})
|
self._supported_modes.append({"value": value, "labels": labels})
|
||||||
|
|
||||||
def serialize_configuration(self):
|
def serialize_configuration(self):
|
||||||
"""Return configuration for ModeResources friendlyNames serialized for an API response."""
|
"""Return serialized configuration for an API response.
|
||||||
|
|
||||||
|
Returns configuration for ModeResources friendlyNames serialized.
|
||||||
|
"""
|
||||||
mode_resources = []
|
mode_resources = []
|
||||||
for mode in self._supported_modes:
|
for mode in self._supported_modes:
|
||||||
result = {
|
result = {
|
||||||
@ -260,7 +276,8 @@ class AlexaModeResource(AlexaCapabilityResource):
|
|||||||
class AlexaPresetResource(AlexaCapabilityResource):
|
class AlexaPresetResource(AlexaCapabilityResource):
|
||||||
"""Implements Alexa PresetResources.
|
"""Implements Alexa PresetResources.
|
||||||
|
|
||||||
Use presetResources with RangeController to provide a set of friendlyNames for each RangeController preset.
|
Use presetResources with RangeController to provide a set of
|
||||||
|
friendlyNamesfor each RangeController preset.
|
||||||
|
|
||||||
https://developer.amazon.com/docs/device-apis/resources-and-assets.html#presetresources
|
https://developer.amazon.com/docs/device-apis/resources-and-assets.html#presetresources
|
||||||
"""
|
"""
|
||||||
@ -281,7 +298,10 @@ class AlexaPresetResource(AlexaCapabilityResource):
|
|||||||
self._presets.append({"value": value, "labels": labels})
|
self._presets.append({"value": value, "labels": labels})
|
||||||
|
|
||||||
def serialize_configuration(self):
|
def serialize_configuration(self):
|
||||||
"""Return configuration for PresetResources friendlyNames serialized for an API response."""
|
"""Return serialized configuration for an API response.
|
||||||
|
|
||||||
|
Returns configuration for PresetResources friendlyNames serialized.
|
||||||
|
"""
|
||||||
configuration = {
|
configuration = {
|
||||||
"supportedRange": {
|
"supportedRange": {
|
||||||
"minimumValue": self._minimum_value,
|
"minimumValue": self._minimum_value,
|
||||||
@ -309,18 +329,23 @@ class AlexaPresetResource(AlexaCapabilityResource):
|
|||||||
class AlexaSemantics:
|
class AlexaSemantics:
|
||||||
"""Class for Alexa Semantics Object.
|
"""Class for Alexa Semantics Object.
|
||||||
|
|
||||||
You can optionally enable additional utterances by using semantics. When you use semantics,
|
You can optionally enable additional utterances by using semantics. When
|
||||||
you manually map the phrases "open", "close", "raise", and "lower" to directives.
|
you use semantics, you manually map the phrases "open", "close", "raise",
|
||||||
|
and "lower" to directives.
|
||||||
|
|
||||||
Semantics is supported for the following interfaces only: ModeController, RangeController, and ToggleController.
|
Semantics is supported for the following interfaces only: ModeController,
|
||||||
|
RangeController, and ToggleController.
|
||||||
|
|
||||||
Semantics stateMappings are only supported for one interface of the same type on the same device. If a device has
|
Semantics stateMappings are only supported for one interface of the same
|
||||||
multiple RangeControllers only one interface may use stateMappings otherwise discovery will fail.
|
type on the same device. If a device has multiple RangeControllers only
|
||||||
|
one interface may use stateMappings otherwise discovery will fail.
|
||||||
|
|
||||||
You can support semantics actionMappings on different controllers for the same device, however each controller must
|
You can support semantics actionMappings on different controllers for the
|
||||||
support different phrases. For example, you can support "raise" on a RangeController, and "open" on a ModeController,
|
same device, however each controller must support different phrases.
|
||||||
but you can't support "open" on both RangeController and ModeController. Semantics stateMappings are only supported
|
For example, you can support "raise" on a RangeController, and "open"
|
||||||
for one interface on the same device.
|
on a ModeController, but you can't support "open" on both RangeController
|
||||||
|
and ModeController. Semantics stateMappings are only supported for one
|
||||||
|
interface on the same device.
|
||||||
|
|
||||||
https://developer.amazon.com/docs/device-apis/alexa-discovery.html#semantics-object
|
https://developer.amazon.com/docs/device-apis/alexa-discovery.html#semantics-object
|
||||||
"""
|
"""
|
||||||
|
@ -412,7 +412,7 @@ async def test_report_fan_speed_state(hass):
|
|||||||
|
|
||||||
|
|
||||||
async def test_report_humidifier_humidity_state(hass):
|
async def test_report_humidifier_humidity_state(hass):
|
||||||
"""Test PercentageController, PowerLevelController reports humidifier humidity correctly."""
|
"""Test PercentageController, PowerLevelController humidifier humidity reporting."""
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
"humidifier.dry",
|
"humidifier.dry",
|
||||||
"on",
|
"on",
|
||||||
@ -934,7 +934,10 @@ async def test_report_image_processing(hass):
|
|||||||
|
|
||||||
@pytest.mark.parametrize("domain", ["button", "input_button"])
|
@pytest.mark.parametrize("domain", ["button", "input_button"])
|
||||||
async def test_report_button_pressed(hass, domain):
|
async def test_report_button_pressed(hass, domain):
|
||||||
"""Test button presses report human presence detection events to trigger routines."""
|
"""Test button presses report human presence detection events.
|
||||||
|
|
||||||
|
For use to trigger routines.
|
||||||
|
"""
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
f"{domain}.test_button", "now", {"friendly_name": "Test button"}
|
f"{domain}.test_button", "now", {"friendly_name": "Test button"}
|
||||||
)
|
)
|
||||||
|
@ -114,6 +114,6 @@ async def test_serialize_discovery_recovers(hass, caplog):
|
|||||||
|
|
||||||
assert "Alexa.PowerController" not in interfaces
|
assert "Alexa.PowerController" not in interfaces
|
||||||
assert (
|
assert (
|
||||||
f"Error serializing Alexa.PowerController discovery for {hass.states.get('switch.bla')}"
|
f"Error serializing Alexa.PowerController discovery"
|
||||||
in caplog.text
|
f" for {hass.states.get('switch.bla')}"
|
||||||
)
|
) in caplog.text
|
||||||
|
@ -193,7 +193,9 @@ async def test_intent_launch_request_not_configured(alexa_client):
|
|||||||
"new": True,
|
"new": True,
|
||||||
"sessionId": SESSION_ID,
|
"sessionId": SESSION_ID,
|
||||||
"application": {
|
"application": {
|
||||||
"applicationId": "amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00000"
|
"applicationId": (
|
||||||
|
"amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00000"
|
||||||
|
),
|
||||||
},
|
},
|
||||||
"attributes": {},
|
"attributes": {},
|
||||||
"user": {"userId": "amzn1.account.AM3B00000000000000000000000"},
|
"user": {"userId": "amzn1.account.AM3B00000000000000000000000"},
|
||||||
|
@ -410,7 +410,8 @@ async def test_fan(hass):
|
|||||||
assert appliance["endpointId"] == "fan#test_1"
|
assert appliance["endpointId"] == "fan#test_1"
|
||||||
assert appliance["displayCategories"][0] == "FAN"
|
assert appliance["displayCategories"][0] == "FAN"
|
||||||
assert appliance["friendlyName"] == "Test fan 1"
|
assert appliance["friendlyName"] == "Test fan 1"
|
||||||
# Alexa.RangeController is added to make a fan controllable when no other controllers are available
|
# Alexa.RangeController is added to make a fan controllable when
|
||||||
|
# no other controllers are available.
|
||||||
capabilities = assert_endpoint_capabilities(
|
capabilities = assert_endpoint_capabilities(
|
||||||
appliance,
|
appliance,
|
||||||
"Alexa.RangeController",
|
"Alexa.RangeController",
|
||||||
@ -466,7 +467,8 @@ async def test_fan2(hass):
|
|||||||
assert appliance["endpointId"] == "fan#test_2"
|
assert appliance["endpointId"] == "fan#test_2"
|
||||||
assert appliance["displayCategories"][0] == "FAN"
|
assert appliance["displayCategories"][0] == "FAN"
|
||||||
assert appliance["friendlyName"] == "Test fan 2"
|
assert appliance["friendlyName"] == "Test fan 2"
|
||||||
# Alexa.RangeController is added to make a fan controllable when no other controllers are available
|
# Alexa.RangeController is added to make a fan controllable
|
||||||
|
# when no other controllers are available
|
||||||
capabilities = assert_endpoint_capabilities(
|
capabilities = assert_endpoint_capabilities(
|
||||||
appliance,
|
appliance,
|
||||||
"Alexa.RangeController",
|
"Alexa.RangeController",
|
||||||
@ -597,7 +599,8 @@ async def test_variable_fan_no_current_speed(hass, caplog):
|
|||||||
assert appliance["endpointId"] == "fan#test_3"
|
assert appliance["endpointId"] == "fan#test_3"
|
||||||
assert appliance["displayCategories"][0] == "FAN"
|
assert appliance["displayCategories"][0] == "FAN"
|
||||||
assert appliance["friendlyName"] == "Test fan 3"
|
assert appliance["friendlyName"] == "Test fan 3"
|
||||||
# Alexa.RangeController is added to make a van controllable when no other controllers are available
|
# Alexa.RangeController is added to make a van controllable
|
||||||
|
# when no other controllers are available
|
||||||
capabilities = assert_endpoint_capabilities(
|
capabilities = assert_endpoint_capabilities(
|
||||||
appliance,
|
appliance,
|
||||||
"Alexa.RangeController",
|
"Alexa.RangeController",
|
||||||
@ -625,9 +628,9 @@ async def test_variable_fan_no_current_speed(hass, caplog):
|
|||||||
"fan.percentage",
|
"fan.percentage",
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
"Request Alexa.RangeController/AdjustRangeValue error INVALID_VALUE: Unable to determine fan.test_3 current fan speed"
|
"Request Alexa.RangeController/AdjustRangeValue error "
|
||||||
in caplog.text
|
"INVALID_VALUE: Unable to determine fan.test_3 current fan speed"
|
||||||
)
|
) in caplog.text
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
|
|
||||||
|
@ -527,8 +527,9 @@ async def test_doorbell_event_fail(hass, aioclient_mock, caplog):
|
|||||||
|
|
||||||
# Check we log the entity id of the failing entity
|
# Check we log the entity id of the failing entity
|
||||||
assert (
|
assert (
|
||||||
"Error when sending DoorbellPress event for binary_sensor.test_doorbell to Alexa: "
|
"Error when sending DoorbellPress event for binary_sensor.test_doorbell"
|
||||||
"THROTTLING_EXCEPTION: Request could not be processed due to throttling"
|
" to Alexa: THROTTLING_EXCEPTION: Request could not be processed"
|
||||||
|
" due to throttling"
|
||||||
) in caplog.text
|
) in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user