diff --git a/homeassistant/components/alexa/capabilities.py b/homeassistant/components/alexa/capabilities.py index 22022250cc6..46f421963ca 100644 --- a/homeassistant/components/alexa/capabilities.py +++ b/homeassistant/components/alexa/capabilities.py @@ -48,6 +48,7 @@ from .const import ( API_THERMOSTAT_MODES, API_THERMOSTAT_PRESETS, DATE_FORMAT, + PRESET_MODE_NA, Inputs, ) from .errors import UnsupportedProperty @@ -391,6 +392,8 @@ class AlexaPowerController(AlexaCapability): if self.entity.domain == climate.DOMAIN: is_on = self.entity.state != climate.HVAC_MODE_OFF + elif self.entity.domain == fan.DOMAIN: + is_on = self.entity.state == fan.STATE_ON elif self.entity.domain == vacuum.DOMAIN: is_on = self.entity.state == vacuum.STATE_CLEANING elif self.entity.domain == timer.DOMAIN: @@ -1155,9 +1158,6 @@ class AlexaPowerLevelController(AlexaCapability): if name != "powerLevel": raise UnsupportedProperty(name) - if self.entity.domain == fan.DOMAIN: - return self.entity.attributes.get(fan.ATTR_PERCENTAGE) or 0 - class AlexaSecurityPanelController(AlexaCapability): """Implements Alexa.SecurityPanelController. @@ -1354,10 +1354,17 @@ class AlexaModeController(AlexaCapability): self._resource = AlexaModeResource( [AlexaGlobalCatalog.SETTING_PRESET], False ) - for preset_mode in self.entity.attributes.get(fan.ATTR_PRESET_MODES, []): + preset_modes = self.entity.attributes.get(fan.ATTR_PRESET_MODES, []) + for preset_mode in preset_modes: self._resource.add_mode( f"{fan.ATTR_PRESET_MODE}.{preset_mode}", [preset_mode] ) + # Fans with a single preset_mode completely break Alexa discovery, add a + # fake preset (see issue #53832). + if len(preset_modes) == 1: + self._resource.add_mode( + f"{fan.ATTR_PRESET_MODE}.{PRESET_MODE_NA}", [PRESET_MODE_NA] + ) return self._resource.serialize_capability_resources() # Cover Position Resources @@ -1491,6 +1498,13 @@ class AlexaRangeController(AlexaCapability): if self.instance == f"{cover.DOMAIN}.tilt": return self.entity.attributes.get(cover.ATTR_CURRENT_TILT_POSITION) + # Fan speed percentage + if self.instance == f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}": + supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + if supported and fan.SUPPORT_SET_SPEED: + return self.entity.attributes.get(fan.ATTR_PERCENTAGE) + return 100 if self.entity.state == fan.STATE_ON else 0 + # Input Number Value if self.instance == f"{input_number.DOMAIN}.{input_number.ATTR_VALUE}": return float(self.entity.state) @@ -1517,28 +1531,16 @@ class AlexaRangeController(AlexaCapability): def capability_resources(self): """Return capabilityResources object.""" - # Fan Speed Resources - if self.instance == f"{fan.DOMAIN}.{fan.ATTR_SPEED}": - speed_list = self.entity.attributes[fan.ATTR_SPEED_LIST] - max_value = len(speed_list) - 1 + # Fan Speed Percentage Resources + if self.instance == f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}": + percentage_step = self.entity.attributes.get(fan.ATTR_PERCENTAGE_STEP) self._resource = AlexaPresetResource( - labels=[AlexaGlobalCatalog.SETTING_FAN_SPEED], + labels=["Percentage", AlexaGlobalCatalog.SETTING_FAN_SPEED], min_value=0, - max_value=max_value, - precision=1, + max_value=100, + precision=percentage_step if percentage_step else 100, + unit=AlexaGlobalCatalog.UNIT_PERCENT, ) - for index, speed in enumerate(speed_list): - labels = [] - if isinstance(speed, str): - labels.append(speed.replace("_", " ")) - if index == 1: - labels.append(AlexaGlobalCatalog.VALUE_MINIMUM) - if index == max_value: - labels.append(AlexaGlobalCatalog.VALUE_MAXIMUM) - - if len(labels) > 0: - self._resource.add_preset(value=index, labels=labels) - return self._resource.serialize_capability_resources() # Cover Position Resources @@ -1651,6 +1653,20 @@ class AlexaRangeController(AlexaCapability): ) return self._semantics.serialize_semantics() + # Fan Speed Percentage + if self.instance == f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}": + lower_labels = [AlexaSemantics.ACTION_LOWER] + raise_labels = [AlexaSemantics.ACTION_RAISE] + self._semantics = AlexaSemantics() + + self._semantics.add_action_to_directive( + lower_labels, "SetRangeValue", {"rangeValue": 0} + ) + self._semantics.add_action_to_directive( + raise_labels, "SetRangeValue", {"rangeValue": 100} + ) + return self._semantics.serialize_semantics() + return None diff --git a/homeassistant/components/alexa/const.py b/homeassistant/components/alexa/const.py index de8a4a6fdc4..0532c85dac1 100644 --- a/homeassistant/components/alexa/const.py +++ b/homeassistant/components/alexa/const.py @@ -78,6 +78,9 @@ API_THERMOSTAT_MODES = OrderedDict( API_THERMOSTAT_MODES_CUSTOM = {climate.HVAC_MODE_DRY: "DEHUMIDIFY"} API_THERMOSTAT_PRESETS = {climate.PRESET_ECO: "ECO"} +# AlexaModeController does not like a single mode for the fan preset, we add PRESET_MODE_NA if a fan has only one preset_mode +PRESET_MODE_NA = "-" + class Cause: """Possible causes for property changes. diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index 9a8e56d3551..d74f9329812 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -60,11 +60,9 @@ from .capabilities import ( AlexaLockController, AlexaModeController, AlexaMotionSensor, - AlexaPercentageController, AlexaPlaybackController, AlexaPlaybackStateReporter, AlexaPowerController, - AlexaPowerLevelController, AlexaRangeController, AlexaSceneController, AlexaSecurityPanelController, @@ -530,23 +528,32 @@ class FanCapabilities(AlexaEntity): def interfaces(self): """Yield the supported interfaces.""" yield AlexaPowerController(self.entity) - + force_range_controller = True supported = self.entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) - if supported & fan.SUPPORT_SET_SPEED: - yield AlexaPercentageController(self.entity) - yield AlexaPowerLevelController(self.entity) if supported & fan.SUPPORT_OSCILLATE: yield AlexaToggleController( self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_OSCILLATING}" ) + force_range_controller = False if supported & fan.SUPPORT_PRESET_MODE: yield AlexaModeController( self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_PRESET_MODE}" ) + force_range_controller = False if supported & fan.SUPPORT_DIRECTION: yield AlexaModeController( self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_DIRECTION}" ) + force_range_controller = False + + # AlexaRangeController controls the Fan Speed Percentage. + # For fans which only support on/off, no controller is added. This makes the + # fan impossible to turn on or off through Alexa, most likely due 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.SUPPORT_SET_SPEED: + yield AlexaRangeController( + self.entity, instance=f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}" + ) yield AlexaEndpointHealth(self.hass, self.entity) yield Alexa(self.hass) diff --git a/homeassistant/components/alexa/handlers.py b/homeassistant/components/alexa/handlers.py index 192da955e3f..5a23f5d1bc2 100644 --- a/homeassistant/components/alexa/handlers.py +++ b/homeassistant/components/alexa/handlers.py @@ -55,6 +55,7 @@ from .const import ( API_THERMOSTAT_MODES_CUSTOM, API_THERMOSTAT_PRESETS, DATE_FORMAT, + PRESET_MODE_NA, Cause, Inputs, ) @@ -123,6 +124,8 @@ async def async_api_turn_on(hass, config, directive, context): service = SERVICE_TURN_ON if domain == cover.DOMAIN: service = cover.SERVICE_OPEN_COVER + elif domain == fan.DOMAIN: + service = fan.SERVICE_TURN_ON elif domain == vacuum.DOMAIN: supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) if not supported & vacuum.SUPPORT_TURN_ON and supported & vacuum.SUPPORT_START: @@ -157,6 +160,8 @@ async def async_api_turn_off(hass, config, directive, context): service = SERVICE_TURN_OFF if entity.domain == cover.DOMAIN: service = cover.SERVICE_CLOSE_COVER + elif domain == fan.DOMAIN: + service = fan.SERVICE_TURN_OFF elif domain == vacuum.DOMAIN: supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) if ( @@ -826,48 +831,6 @@ async def async_api_reportstate(hass, config, directive, context): return directive.response(name="StateReport") -@HANDLERS.register(("Alexa.PowerLevelController", "SetPowerLevel")) -async def async_api_set_power_level(hass, config, directive, context): - """Process a SetPowerLevel request.""" - entity = directive.entity - service = None - data = {ATTR_ENTITY_ID: entity.entity_id} - - if entity.domain == fan.DOMAIN: - service = fan.SERVICE_SET_PERCENTAGE - percentage = int(directive.payload["powerLevel"]) - data[fan.ATTR_PERCENTAGE] = percentage - - await hass.services.async_call( - entity.domain, service, data, blocking=False, context=context - ) - - return directive.response() - - -@HANDLERS.register(("Alexa.PowerLevelController", "AdjustPowerLevel")) -async def async_api_adjust_power_level(hass, config, directive, context): - """Process an AdjustPowerLevel request.""" - entity = directive.entity - percentage_delta = int(directive.payload["powerLevelDelta"]) - service = None - data = {ATTR_ENTITY_ID: entity.entity_id} - - if entity.domain == fan.DOMAIN: - service = fan.SERVICE_SET_PERCENTAGE - current = entity.attributes.get(fan.ATTR_PERCENTAGE) or 0 - - # set percentage - percentage = min(100, max(0, percentage_delta + current)) - data[fan.ATTR_PERCENTAGE] = percentage - - await hass.services.async_call( - entity.domain, service, data, blocking=False, context=context - ) - - return directive.response() - - @HANDLERS.register(("Alexa.SecurityPanelController", "Arm")) async def async_api_arm(hass, config, directive, context): """Process a Security Panel Arm request.""" @@ -962,7 +925,9 @@ async def async_api_set_mode(hass, config, directive, context): # Fan preset_mode elif instance == f"{fan.DOMAIN}.{fan.ATTR_PRESET_MODE}": preset_mode = mode.split(".")[1] - if preset_mode in entity.attributes.get(fan.ATTR_PRESET_MODES): + if preset_mode != PRESET_MODE_NA and preset_mode in entity.attributes.get( + fan.ATTR_PRESET_MODES + ): service = fan.SERVICE_SET_PRESET_MODE data[fan.ATTR_PRESET_MODE] = preset_mode else: @@ -1114,6 +1079,19 @@ async def async_api_set_range(hass, config, directive, context): service = cover.SERVICE_SET_COVER_TILT_POSITION data[cover.ATTR_TILT_POSITION] = range_value + # Fan Speed + elif instance == f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}": + range_value = int(range_value) + if range_value == 0: + service = fan.SERVICE_TURN_OFF + else: + supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) + if supported and fan.SUPPORT_SET_SPEED: + service = fan.SERVICE_SET_PERCENTAGE + data[fan.ATTR_PERCENTAGE] = range_value + else: + service = fan.SERVICE_TURN_ON + # Input Number Value elif instance == f"{input_number.DOMAIN}.{input_number.ATTR_VALUE}": range_value = float(range_value) @@ -1201,6 +1179,25 @@ async def async_api_adjust_range(hass, config, directive, context): else: data[cover.ATTR_TILT_POSITION] = tilt_position + # Fan speed percentage + elif instance == f"{fan.DOMAIN}.{fan.ATTR_PERCENTAGE}": + percentage_step = entity.attributes.get(fan.ATTR_PERCENTAGE_STEP) or 20 + range_delta = ( + int(range_delta * percentage_step) + if range_delta_default + else int(range_delta) + ) + service = fan.SERVICE_SET_PERCENTAGE + current = entity.attributes.get(fan.ATTR_PERCENTAGE) + if not current: + msg = f"Unable to determine {entity.entity_id} current fan speed" + raise AlexaInvalidValueError(msg) + percentage = response_value = min(100, max(0, range_delta + current)) + if percentage: + data[fan.ATTR_PERCENTAGE] = percentage + else: + service = fan.SERVICE_TURN_OFF + # Input Number Value elif instance == f"{input_number.DOMAIN}.{input_number.ATTR_VALUE}": range_delta = float(range_delta) diff --git a/tests/components/alexa/test_capabilities.py b/tests/components/alexa/test_capabilities.py index bdc19bc792f..d4d6bec62a9 100644 --- a/tests/components/alexa/test_capabilities.py +++ b/tests/components/alexa/test_capabilities.py @@ -383,22 +383,39 @@ async def test_report_fan_speed_state(hass): "percentage": 100, }, ) - + hass.states.async_set( + "fan.speed_less_on", + "on", + { + "friendly_name": "Speedless fan on", + "supported_features": 0, + }, + ) + hass.states.async_set( + "fan.speed_less_off", + "off", + { + "friendly_name": "Speedless fan off", + "supported_features": 0, + }, + ) properties = await reported_properties(hass, "fan.off") - properties.assert_equal("Alexa.PercentageController", "percentage", 0) - properties.assert_equal("Alexa.PowerLevelController", "powerLevel", 0) + properties.assert_equal("Alexa.RangeController", "rangeValue", 0) properties = await reported_properties(hass, "fan.low_speed") - properties.assert_equal("Alexa.PercentageController", "percentage", 33) - properties.assert_equal("Alexa.PowerLevelController", "powerLevel", 33) + properties.assert_equal("Alexa.RangeController", "rangeValue", 33) properties = await reported_properties(hass, "fan.medium_speed") - properties.assert_equal("Alexa.PercentageController", "percentage", 66) - properties.assert_equal("Alexa.PowerLevelController", "powerLevel", 66) + properties.assert_equal("Alexa.RangeController", "rangeValue", 66) properties = await reported_properties(hass, "fan.high_speed") - properties.assert_equal("Alexa.PercentageController", "percentage", 100) - properties.assert_equal("Alexa.PowerLevelController", "powerLevel", 100) + properties.assert_equal("Alexa.RangeController", "rangeValue", 100) + + properties = await reported_properties(hass, "fan.speed_less_on") + properties.assert_equal("Alexa.RangeController", "rangeValue", 100) + + properties = await reported_properties(hass, "fan.speed_less_off") + properties.assert_equal("Alexa.RangeController", "rangeValue", 0) async def test_report_fan_preset_mode(hass): @@ -442,6 +459,18 @@ async def test_report_fan_preset_mode(hass): properties = await reported_properties(hass, "fan.preset_mode") properties.assert_equal("Alexa.ModeController", "mode", "preset_mode.whoosh") + hass.states.async_set( + "fan.preset_mode", + "whoosh", + { + "friendly_name": "one preset mode fan", + "supported_features": 8, + "preset_mode": "auto", + "preset_modes": ["auto"], + }, + ) + properties = await reported_properties(hass, "fan.preset_mode") + async def test_report_fan_oscillating(hass): """Test ToggleController reports fan oscillating correctly.""" diff --git a/tests/components/alexa/test_smart_home.py b/tests/components/alexa/test_smart_home.py index 998be054186..71123ca27ba 100644 --- a/tests/components/alexa/test_smart_home.py +++ b/tests/components/alexa/test_smart_home.py @@ -365,14 +365,42 @@ async def test_fan(hass): assert appliance["endpointId"] == "fan#test_1" assert appliance["displayCategories"][0] == "FAN" assert appliance["friendlyName"] == "Test fan 1" + # Alexa.RangeController is added to make a van controllable when no other controllers are available capabilities = assert_endpoint_capabilities( - appliance, "Alexa.PowerController", "Alexa.EndpointHealth", "Alexa" + appliance, + "Alexa.RangeController", + "Alexa.PowerController", + "Alexa.EndpointHealth", + "Alexa", ) power_capability = get_capability(capabilities, "Alexa.PowerController") assert "capabilityResources" not in power_capability assert "configuration" not in power_capability + await assert_power_controller_works( + "fan#test_1", "fan.turn_on", "fan.turn_off", hass + ) + + await assert_request_calls_service( + "Alexa.RangeController", + "SetRangeValue", + "fan#test_1", + "fan.turn_on", + hass, + payload={"rangeValue": "100"}, + instance="fan.percentage", + ) + await assert_request_calls_service( + "Alexa.RangeController", + "SetRangeValue", + "fan#test_1", + "fan.turn_off", + hass, + payload={"rangeValue": "0"}, + instance="fan.percentage", + ) + async def test_variable_fan(hass): """Test fan discovery. @@ -396,103 +424,133 @@ async def test_variable_fan(hass): capabilities = assert_endpoint_capabilities( appliance, - "Alexa.PercentageController", + "Alexa.RangeController", "Alexa.PowerController", - "Alexa.PowerLevelController", "Alexa.EndpointHealth", "Alexa", ) - capability = get_capability(capabilities, "Alexa.PercentageController") + capability = get_capability(capabilities, "Alexa.RangeController") assert capability is not None capability = get_capability(capabilities, "Alexa.PowerController") assert capability is not None - capability = get_capability(capabilities, "Alexa.PowerLevelController") - assert capability is not None - call, _ = await assert_request_calls_service( - "Alexa.PercentageController", - "SetPercentage", + "Alexa.RangeController", + "SetRangeValue", "fan#test_2", "fan.set_percentage", hass, - payload={"percentage": "50"}, + payload={"rangeValue": "50"}, + instance="fan.percentage", ) assert call.data["percentage"] == 50 call, _ = await assert_request_calls_service( - "Alexa.PercentageController", - "SetPercentage", + "Alexa.RangeController", + "SetRangeValue", "fan#test_2", "fan.set_percentage", hass, - payload={"percentage": "33"}, + payload={"rangeValue": "33"}, + instance="fan.percentage", ) assert call.data["percentage"] == 33 call, _ = await assert_request_calls_service( - "Alexa.PercentageController", - "SetPercentage", + "Alexa.RangeController", + "SetRangeValue", "fan#test_2", "fan.set_percentage", hass, - payload={"percentage": "100"}, + payload={"rangeValue": "100"}, + instance="fan.percentage", ) assert call.data["percentage"] == 100 - await assert_percentage_changes( + await assert_range_changes( hass, - [(95, "-5"), (100, "5"), (20, "-80"), (66, "-34")], - "Alexa.PercentageController", - "AdjustPercentage", + [ + (95, -5, False), + (100, 5, False), + (20, -80, False), + (66, -34, False), + (80, -1, True), + (20, -4, True), + ], + "Alexa.RangeController", + "AdjustRangeValue", "fan#test_2", - "percentageDelta", "fan.set_percentage", "percentage", + "fan.percentage", + ) + await assert_range_changes( + hass, + [ + (0, -100, False), + ], + "Alexa.RangeController", + "AdjustRangeValue", + "fan#test_2", + "fan.turn_off", + None, + "fan.percentage", ) - call, _ = await assert_request_calls_service( - "Alexa.PowerLevelController", - "SetPowerLevel", - "fan#test_2", - "fan.set_percentage", - hass, - payload={"powerLevel": "20"}, - ) - assert call.data["percentage"] == 20 - call, _ = await assert_request_calls_service( - "Alexa.PowerLevelController", - "SetPowerLevel", - "fan#test_2", - "fan.set_percentage", - hass, - payload={"powerLevel": "50"}, - ) - assert call.data["percentage"] == 50 +async def test_variable_fan_no_current_speed(hass, caplog): + """Test fan discovery. - call, _ = await assert_request_calls_service( - "Alexa.PowerLevelController", - "SetPowerLevel", - "fan#test_2", - "fan.set_percentage", - hass, - payload={"powerLevel": "99"}, + This one has variable speed, but no current speed. + """ + device = ( + "fan.test_3", + "off", + { + "friendly_name": "Test fan 3", + "supported_features": 1, + "percentage": None, + }, ) - assert call.data["percentage"] == 99 + appliance = await discovery_test(device, hass) - await assert_percentage_changes( - hass, - [(95, "-5"), (50, "-50"), (20, "-80")], - "Alexa.PowerLevelController", - "AdjustPowerLevel", - "fan#test_2", - "powerLevelDelta", - "fan.set_percentage", - "percentage", + assert appliance["endpointId"] == "fan#test_3" + assert appliance["displayCategories"][0] == "FAN" + assert appliance["friendlyName"] == "Test fan 3" + # Alexa.RangeController is added to make a van controllable when no other controllers are available + capabilities = assert_endpoint_capabilities( + appliance, + "Alexa.RangeController", + "Alexa.PowerController", + "Alexa.EndpointHealth", + "Alexa", ) + capability = get_capability(capabilities, "Alexa.RangeController") + assert capability is not None + + capability = get_capability(capabilities, "Alexa.PowerController") + assert capability is not None + + with pytest.raises(AssertionError): + await assert_range_changes( + hass, + [ + (20, -5, False), + ], + "Alexa.RangeController", + "AdjustRangeValue", + "fan#test_3", + "fan.set_percentage", + "percentage", + "fan.percentage", + ) + assert ( + "Request Alexa.RangeController/AdjustRangeValue error INVALID_VALUE: Unable to determine fan.test_3 current fan speed" + in caplog.text + ) + caplog.clear() async def test_oscillating_fan(hass): @@ -742,6 +800,78 @@ async def test_preset_mode_fan(hass, caplog): caplog.clear() +async def test_single_preset_mode_fan(hass, caplog): + """Test fan discovery. + + This one has only preset mode. + """ + device = ( + "fan.test_8", + "off", + { + "friendly_name": "Test fan 8", + "supported_features": 8, + "preset_modes": ["auto"], + "preset_mode": "auto", + }, + ) + appliance = await discovery_test(device, hass) + + assert appliance["endpointId"] == "fan#test_8" + assert appliance["displayCategories"][0] == "FAN" + assert appliance["friendlyName"] == "Test fan 8" + + capabilities = assert_endpoint_capabilities( + appliance, + "Alexa.EndpointHealth", + "Alexa.ModeController", + "Alexa.PowerController", + "Alexa", + ) + + range_capability = get_capability(capabilities, "Alexa.ModeController") + assert range_capability is not None + assert range_capability["instance"] == "fan.preset_mode" + + properties = range_capability["properties"] + assert properties["nonControllable"] is False + assert {"name": "mode"} in properties["supported"] + + capability_resources = range_capability["capabilityResources"] + assert capability_resources is not None + assert { + "@type": "asset", + "value": {"assetId": "Alexa.Setting.Preset"}, + } in capability_resources["friendlyNames"] + + configuration = range_capability["configuration"] + assert configuration is not None + + call, _ = await assert_request_calls_service( + "Alexa.ModeController", + "SetMode", + "fan#test_8", + "fan.set_preset_mode", + hass, + payload={"mode": "preset_mode.auto"}, + instance="fan.preset_mode", + ) + assert call.data["preset_mode"] == "auto" + + with pytest.raises(AssertionError): + await assert_request_calls_service( + "Alexa.ModeController", + "SetMode", + "fan#test_8", + "fan.set_preset_mode", + hass, + payload={"mode": "preset_mode.-"}, + instance="fan.preset_mode", + ) + assert "Entity 'fan.test_8' does not support Preset '-'" in caplog.text + caplog.clear() + + async def test_lock(hass): """Test lock discovery.""" device = ("lock.test", "off", {"friendly_name": "Test lock"}) @@ -1615,7 +1745,8 @@ async def assert_range_changes( call, _ = await assert_request_calls_service( namespace, name, endpoint, service, hass, payload=payload, instance=instance ) - assert call.data[changed_parameter] == result_range + if changed_parameter: + assert call.data[changed_parameter] == result_range async def test_temp_sensor(hass): diff --git a/tests/components/alexa/test_state_report.py b/tests/components/alexa/test_state_report.py index 729d9d6e467..bd91dc8f846 100644 --- a/tests/components/alexa/test_state_report.py +++ b/tests/components/alexa/test_state_report.py @@ -97,15 +97,12 @@ async def test_report_state_instance(hass, aioclient_mock): assert report["instance"] == "fan.preset_mode" assert report["namespace"] == "Alexa.ModeController" checks += 1 - if report["name"] == "percentage": + if report["name"] == "rangeValue": assert report["value"] == 90 - assert report["namespace"] == "Alexa.PercentageController" + assert report["instance"] == "fan.percentage" + assert report["namespace"] == "Alexa.RangeController" checks += 1 - if report["name"] == "powerLevel": - assert report["value"] == 90 - assert report["namespace"] == "Alexa.PowerLevelController" - checks += 1 - assert checks == 4 + assert checks == 3 assert call_json["event"]["endpoint"]["endpointId"] == "fan#test_fan"