diff --git a/homeassistant/components/thermostat/__init__.py b/homeassistant/components/thermostat/__init__.py index 7610070b1f0..d92a71ba1f6 100644 --- a/homeassistant/components/thermostat/__init__.py +++ b/homeassistant/components/thermostat/__init__.py @@ -27,6 +27,7 @@ SCAN_INTERVAL = 60 SERVICE_SET_AWAY_MODE = "set_away_mode" SERVICE_SET_TEMPERATURE = "set_temperature" +SERVICE_SET_FAN_MODE = "set_fan_mode" STATE_HEAT = "heat" STATE_COOL = "cool" @@ -34,6 +35,7 @@ STATE_IDLE = "idle" ATTR_CURRENT_TEMPERATURE = "current_temperature" ATTR_AWAY_MODE = "away_mode" +ATTR_FAN = "fan" ATTR_MAX_TEMP = "max_temp" ATTR_MIN_TEMP = "min_temp" ATTR_TEMPERATURE_LOW = "target_temp_low" @@ -69,59 +71,100 @@ def set_temperature(hass, temperature, entity_id=None): hass.services.call(DOMAIN, SERVICE_SET_TEMPERATURE, data) +def set_fan_mode(hass, fan_mode, entity_id=None): + """ Turn all or specified thermostat fan mode on. """ + data = { + ATTR_FAN: fan_mode + } + + if entity_id: + data[ATTR_ENTITY_ID] = entity_id + + hass.services.call(DOMAIN, SERVICE_SET_FAN_MODE, data) + + +# pylint: disable=too-many-branches def setup(hass, config): """ Setup thermostats. """ component = EntityComponent(_LOGGER, DOMAIN, hass, SCAN_INTERVAL, DISCOVERY_PLATFORMS) component.setup(config) - def thermostat_service(service): - """ Handles calls to the services. """ - - # Convert the entity ids to valid light ids - target_thermostats = component.extract_from_service(service) - - if service.service == SERVICE_SET_AWAY_MODE: - away_mode = service.data.get(ATTR_AWAY_MODE) - - if away_mode is None: - _LOGGER.error( - "Received call to %s without attribute %s", - SERVICE_SET_AWAY_MODE, ATTR_AWAY_MODE) - - elif away_mode: - for thermostat in target_thermostats: - thermostat.turn_away_mode_on() - else: - for thermostat in target_thermostats: - thermostat.turn_away_mode_off() - - elif service.service == SERVICE_SET_TEMPERATURE: - temperature = util.convert( - service.data.get(ATTR_TEMPERATURE), float) - - if temperature is None: - return - - for thermostat in target_thermostats: - thermostat.set_temperature(convert( - temperature, hass.config.temperature_unit, - thermostat.unit_of_measurement)) - - for thermostat in target_thermostats: - thermostat.update_ha_state(True) - descriptions = load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) - hass.services.register( - DOMAIN, SERVICE_SET_AWAY_MODE, thermostat_service, - descriptions.get(SERVICE_SET_AWAY_MODE)) + def away_mode_set_service(service): + """ Set away mode on target thermostats """ + + target_thermostats = component.extract_from_service(service) + + away_mode = service.data.get(ATTR_AWAY_MODE) + + if away_mode is None: + _LOGGER.error( + "Received call to %s without attribute %s", + SERVICE_SET_AWAY_MODE, ATTR_AWAY_MODE) + return + + for thermostat in target_thermostats: + if away_mode: + thermostat.turn_away_mode_on() + else: + thermostat.turn_away_mode_off() + + thermostat.update_ha_state(True) hass.services.register( - DOMAIN, SERVICE_SET_TEMPERATURE, thermostat_service, + DOMAIN, SERVICE_SET_AWAY_MODE, away_mode_set_service, + descriptions.get(SERVICE_SET_AWAY_MODE)) + + def temperature_set_service(service): + """ Set temperature on the target thermostats """ + + target_thermostats = component.extract_from_service(service) + + temperature = util.convert( + service.data.get(ATTR_TEMPERATURE), float) + + if temperature is None: + return + + for thermostat in target_thermostats: + thermostat.set_temperature(convert( + temperature, hass.config.temperature_unit, + thermostat.unit_of_measurement)) + + thermostat.update_ha_state(True) + + hass.services.register( + DOMAIN, SERVICE_SET_TEMPERATURE, temperature_set_service, descriptions.get(SERVICE_SET_TEMPERATURE)) + def fan_mode_set_service(service): + """ Set fan mode on target thermostats """ + + target_thermostats = component.extract_from_service(service) + + fan_mode = service.data.get(ATTR_FAN) + + if fan_mode is None: + _LOGGER.error( + "Received call to %s without attribute %s", + SERVICE_SET_FAN_MODE, ATTR_FAN) + return + + for thermostat in target_thermostats: + if fan_mode: + thermostat.turn_fan_on() + else: + thermostat.turn_fan_off() + + thermostat.update_ha_state(True) + + hass.services.register( + DOMAIN, SERVICE_SET_FAN_MODE, fan_mode_set_service, + descriptions.get(SERVICE_SET_FAN_MODE)) + return True @@ -164,6 +207,10 @@ class ThermostatDevice(Entity): if is_away is not None: data[ATTR_AWAY_MODE] = STATE_ON if is_away else STATE_OFF + is_fan_on = self.is_fan_on + if is_fan_on is not None: + data[ATTR_FAN] = STATE_ON if is_fan_on else STATE_OFF + device_attr = self.device_state_attributes if device_attr is not None: @@ -209,6 +256,14 @@ class ThermostatDevice(Entity): """ return None + @property + def is_fan_on(self): + """ + Returns if the fan is on + Return None if not available. + """ + return None + def set_temperate(self, temperature): """ Set new target temperature. """ pass @@ -221,6 +276,14 @@ class ThermostatDevice(Entity): """ Turns away mode off. """ pass + def turn_fan_on(self): + """ Turns fan on. """ + pass + + def turn_fan_off(self): + """ Turns fan off. """ + pass + @property def min_temp(self): """ Return minimum temperature. """ diff --git a/homeassistant/components/thermostat/nest.py b/homeassistant/components/thermostat/nest.py index 423a3195976..e0e1f74cdbc 100644 --- a/homeassistant/components/thermostat/nest.py +++ b/homeassistant/components/thermostat/nest.py @@ -66,7 +66,6 @@ class NestThermostat(ThermostatDevice): return { "humidity": self.device.humidity, "target_humidity": self.device.target_humidity, - "fan": self.device.fan, "mode": self.device.mode } @@ -143,6 +142,19 @@ class NestThermostat(ThermostatDevice): """ Turns away off. """ self.structure.away = False + @property + def is_fan_on(self): + """ Returns whether the fan is on """ + return self.device.fan + + def turn_fan_on(self): + """ Turns fan on """ + self.device.fan = True + + def turn_fan_off(self): + """ Turns fan off """ + self.device.fan = False + @property def min_temp(self): """ Identifies min_temp in Nest API or defaults if not available. """ diff --git a/homeassistant/components/thermostat/services.yaml b/homeassistant/components/thermostat/services.yaml index 0d4f4726204..3592dfce75d 100644 --- a/homeassistant/components/thermostat/services.yaml +++ b/homeassistant/components/thermostat/services.yaml @@ -22,3 +22,15 @@ set_temperature: temperature: description: New target temperature for thermostat example: 25 + +set_fan_mode: + description: Turn fan on/off for a thermostat + + fields: + entity_id: + description: Name(s) of entities to change + example: 'thermostat.nest' + + fan: + description: New value of fan mode + example: true