Code styling tweaks to the Alexa integration (#86121)

This commit is contained in:
Franck Nijhof 2023-01-18 00:01:30 +01:00 committed by GitHub
parent b722a7e05b
commit 91aaca6471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 139 additions and 79 deletions

View File

@ -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"}]

View File

@ -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}"

View File

@ -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(

View File

@ -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
""" """

View File

@ -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"}
) )

View File

@ -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

View File

@ -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"},

View File

@ -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()

View File

@ -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