From d37d1ce4ad2109a79c33be2452b056e5153d894e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 13 Jul 2019 01:27:50 -0700 Subject: [PATCH] Simplify Alexa/Google for new climate turn_on/off (#25115) --- homeassistant/components/alexa/entities.py | 4 +- .../components/google_assistant/trait.py | 50 ++++++++----------- tests/components/alexa/test_smart_home.py | 1 + .../components/google_assistant/test_trait.py | 12 ++--- 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index 2a6498fdcaf..c7f4fd9b7ea 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -249,8 +249,8 @@ class ClimateCapabilities(AlexaEntity): def interfaces(self): """Yield the supported interfaces.""" # If we support two modes, one being off, we allow turning on too. - if len([v for v in self.entity.attributes[climate.ATTR_HVAC_MODES] - if v != climate.HVAC_MODE_OFF]) == 1: + if (climate.HVAC_MODE_OFF in + self.entity.attributes[climate.ATTR_HVAC_MODES]): yield AlexaPowerController(self.entity) yield AlexaThermostatController(self.hass, self.entity) diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 1d36f6f53b4..2d7b7edd6ba 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -580,16 +580,6 @@ class TemperatureSettingTrait(_Trait): return modes - @property - def climate_on_mode(self): - """Return the mode that should be considered on.""" - modes = [m for m in self.climate_google_modes if m != 'off'] - - if len(modes) == 1: - return modes[0] - - return None - def sync_attributes(self): """Return temperature point and modes attributes for a sync request.""" response = {} @@ -605,8 +595,8 @@ class TemperatureSettingTrait(_Trait): elif domain == climate.DOMAIN: modes = self.climate_google_modes - on_mode = self.climate_on_mode - if on_mode is not None: + if 'off' in modes and any(mode in modes for mode + in ('heatcool', 'heat', 'cool')): modes.append('on') response['availableThermostatModes'] = ','.join(modes) @@ -761,6 +751,26 @@ class TemperatureSettingTrait(_Trait): target_mode = params['thermostatMode'] supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES) + if target_mode == 'on': + await self.hass.services.async_call( + climate.DOMAIN, SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: self.state.entity_id + }, + blocking=True, context=data.context + ) + return + + if target_mode == 'off': + await self.hass.services.async_call( + climate.DOMAIN, SERVICE_TURN_OFF, + { + ATTR_ENTITY_ID: self.state.entity_id + }, + blocking=True, context=data.context + ) + return + if target_mode in self.google_to_preset: await self.hass.services.async_call( climate.DOMAIN, climate.SERVICE_SET_PRESET_MODE, @@ -773,22 +783,6 @@ class TemperatureSettingTrait(_Trait): ) return - if target_mode == 'on': - # When targetting 'on', we're going to try best effort. - modes = [m for m in self.climate_google_modes - if m != climate.HVAC_MODE_OFF] - - if len(modes) == 1: - target_mode = modes[0] - elif 'auto' in modes: - target_mode = 'auto' - elif 'heatcool' in modes: - target_mode = 'heatcool' - else: - raise SmartHomeError( - ERR_FUNCTION_NOT_SUPPORTED, - "Unable to translate 'on' to a HVAC mode.") - await self.hass.services.async_call( climate.DOMAIN, climate.SERVICE_SET_HVAC_MODE, { ATTR_ENTITY_ID: self.state.entity_id, diff --git a/tests/components/alexa/test_smart_home.py b/tests/components/alexa/test_smart_home.py index 62dbbfdc693..59a5a5e858e 100644 --- a/tests/components/alexa/test_smart_home.py +++ b/tests/components/alexa/test_smart_home.py @@ -855,6 +855,7 @@ async def test_thermostat(hass): assert_endpoint_capabilities( appliance, + 'Alexa.PowerController', 'Alexa.ThermostatController', 'Alexa.TemperatureSensor', 'Alexa.EndpointHealth', diff --git a/tests/components/google_assistant/test_trait.py b/tests/components/google_assistant/test_trait.py index 1cbece2b057..5fa71632da9 100644 --- a/tests/components/google_assistant/test_trait.py +++ b/tests/components/google_assistant/test_trait.py @@ -627,24 +627,22 @@ async def test_temperature_setting_climate_onoff(hass): climate.ATTR_MAX_TEMP: None, }), BASIC_CONFIG) assert trt.sync_attributes() == { - 'availableThermostatModes': 'off,cool,heat,heatcool', + 'availableThermostatModes': 'off,cool,heat,heatcool,on', 'thermostatTemperatureUnit': 'F', } assert trt.can_execute(trait.COMMAND_THERMOSTAT_SET_MODE, {}) - calls = async_mock_service( - hass, climate.DOMAIN, climate.SERVICE_SET_HVAC_MODE) + calls = async_mock_service(hass, climate.DOMAIN, SERVICE_TURN_ON) await trt.execute(trait.COMMAND_THERMOSTAT_SET_MODE, BASIC_DATA, { 'thermostatMode': 'on', }, {}) assert len(calls) == 1 - assert calls[0].data[climate.ATTR_HVAC_MODE] == climate.HVAC_MODE_HEAT_COOL + calls = async_mock_service(hass, climate.DOMAIN, SERVICE_TURN_OFF) await trt.execute(trait.COMMAND_THERMOSTAT_SET_MODE, BASIC_DATA, { 'thermostatMode': 'off', }, {}) - assert len(calls) == 2 - assert calls[1].data[climate.ATTR_HVAC_MODE] == climate.HVAC_MODE_OFF + assert len(calls) == 1 async def test_temperature_setting_climate_range(hass): @@ -671,7 +669,7 @@ async def test_temperature_setting_climate_range(hass): climate.ATTR_MAX_TEMP: 80 }), BASIC_CONFIG) assert trt.sync_attributes() == { - 'availableThermostatModes': 'off,cool,heat,auto', + 'availableThermostatModes': 'off,cool,heat,auto,on', 'thermostatTemperatureUnit': 'F', } assert trt.query_attributes() == {