From 14ceb8472f7d24d60809909b54bd5fbc5ce3fc4b Mon Sep 17 00:00:00 2001 From: Jack Wilsdon Date: Thu, 28 Mar 2019 02:58:52 +0000 Subject: [PATCH] Return percentage information in Alexa Smart Home response (#22440) --- homeassistant/components/alexa/smart_home.py | 26 +++++++++ tests/components/alexa/test_smart_home.py | 57 ++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/homeassistant/components/alexa/smart_home.py b/homeassistant/components/alexa/smart_home.py index c87b2c3f624..e16a1d45ab7 100644 --- a/homeassistant/components/alexa/smart_home.py +++ b/homeassistant/components/alexa/smart_home.py @@ -65,6 +65,12 @@ API_THERMOSTAT_MODES = OrderedDict([ (climate.STATE_DRY, 'OFF'), ]) +PERCENTAGE_FAN_MAP = { + fan.SPEED_LOW: 33, + fan.SPEED_MEDIUM: 66, + fan.SPEED_HIGH: 100, +} + SMART_HOME_HTTP_ENDPOINT = '/api/alexa/smart_home' CONF_DESCRIPTION = 'description' @@ -580,6 +586,26 @@ class _AlexaPercentageController(_AlexaInterface): def name(self): return 'Alexa.PercentageController' + def properties_supported(self): + return [{'name': 'percentage'}] + + def properties_retrievable(self): + return True + + def get_property(self, name): + if name != 'percentage': + raise _UnsupportedProperty(name) + + if self.entity.domain == fan.DOMAIN: + speed = self.entity.attributes.get(fan.ATTR_SPEED) + + return PERCENTAGE_FAN_MAP.get(speed, 0) + + if self.entity.domain == cover.DOMAIN: + return self.entity.attributes.get(cover.ATTR_CURRENT_POSITION, 0) + + return 0 + class _AlexaSpeaker(_AlexaInterface): """Implements Alexa.Speaker. diff --git a/tests/components/alexa/test_smart_home.py b/tests/components/alexa/test_smart_home.py index 845e59295ac..924a568dea2 100644 --- a/tests/components/alexa/test_smart_home.py +++ b/tests/components/alexa/test_smart_home.py @@ -1490,6 +1490,63 @@ async def test_report_colored_temp_light_state(hass): 'colorTemperatureInKelvin', 0) +async def test_report_fan_speed_state(hass): + """Test PercentageController reports fan speed correctly.""" + hass.states.async_set( + 'fan.off', 'off', {'friendly_name': "Off fan", + 'speed': "off", + 'supported_features': 1}) + hass.states.async_set( + 'fan.low_speed', 'on', {'friendly_name': "Low speed fan", + 'speed': "low", + 'supported_features': 1}) + hass.states.async_set( + 'fan.medium_speed', 'on', {'friendly_name': "Medium speed fan", + 'speed': "medium", + 'supported_features': 1}) + hass.states.async_set( + 'fan.high_speed', 'on', {'friendly_name': "High speed fan", + 'speed': "high", + 'supported_features': 1}) + + properties = await reported_properties(hass, 'fan.off') + properties.assert_equal('Alexa.PercentageController', 'percentage', 0) + + properties = await reported_properties(hass, 'fan.low_speed') + properties.assert_equal('Alexa.PercentageController', 'percentage', 33) + + properties = await reported_properties(hass, 'fan.medium_speed') + properties.assert_equal('Alexa.PercentageController', 'percentage', 66) + + properties = await reported_properties(hass, 'fan.high_speed') + properties.assert_equal('Alexa.PercentageController', 'percentage', 100) + + +async def test_report_cover_percentage_state(hass): + """Test PercentageController reports cover percentage correctly.""" + hass.states.async_set( + 'cover.fully_open', 'open', {'friendly_name': "Fully open cover", + 'current_position': 100, + 'supported_features': 15}) + hass.states.async_set( + 'cover.half_open', 'open', {'friendly_name': "Half open cover", + 'current_position': 50, + 'supported_features': 15}) + hass.states.async_set( + 'cover.closed', 'closed', {'friendly_name': "Closed cover", + 'current_position': 0, + 'supported_features': 15}) + + properties = await reported_properties(hass, 'cover.fully_open') + properties.assert_equal('Alexa.PercentageController', 'percentage', 100) + + properties = await reported_properties(hass, 'cover.half_open') + properties.assert_equal('Alexa.PercentageController', 'percentage', 50) + + properties = await reported_properties(hass, 'cover.closed') + properties.assert_equal('Alexa.PercentageController', 'percentage', 0) + + async def reported_properties(hass, endpoint): """Use ReportState to get properties and return them.