Allow setting climate devices to AUTO mode via Google Assistant (#11923)

* Allow setting climate devices to AUTO mode via Google Assistant

* Remove cast to lower

* Clarify const name
This commit is contained in:
Paulus Schoutsen 2018-01-26 03:37:06 -08:00
parent 280c1601a2
commit 07b2f38046
4 changed files with 29 additions and 22 deletions

View file

@ -10,7 +10,7 @@ import voluptuous as vol
from homeassistant.components.nest import DATA_NEST from homeassistant.components.nest import DATA_NEST
from homeassistant.components.climate import ( from homeassistant.components.climate import (
STATE_AUTO, STATE_COOL, STATE_HEAT, ClimateDevice, STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_ECO, ClimateDevice,
PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW,
ATTR_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE, ATTR_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE,
SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW, SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW,
@ -27,8 +27,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.All(vol.Coerce(int), vol.Range(min=1)), vol.All(vol.Coerce(int), vol.Range(min=1)),
}) })
STATE_ECO = 'eco' NEST_MODE_HEAT_COOL = 'heat-cool'
STATE_HEAT_COOL = 'heat-cool'
SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH | SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH |
SUPPORT_TARGET_TEMPERATURE_LOW | SUPPORT_OPERATION_MODE | SUPPORT_TARGET_TEMPERATURE_LOW | SUPPORT_OPERATION_MODE |
@ -118,14 +117,14 @@ class NestThermostat(ClimateDevice):
"""Return current operation ie. heat, cool, idle.""" """Return current operation ie. heat, cool, idle."""
if self._mode in [STATE_HEAT, STATE_COOL, STATE_OFF, STATE_ECO]: if self._mode in [STATE_HEAT, STATE_COOL, STATE_OFF, STATE_ECO]:
return self._mode return self._mode
elif self._mode == STATE_HEAT_COOL: elif self._mode == NEST_MODE_HEAT_COOL:
return STATE_AUTO return STATE_AUTO
return STATE_UNKNOWN return STATE_UNKNOWN
@property @property
def target_temperature(self): def target_temperature(self):
"""Return the temperature we try to reach.""" """Return the temperature we try to reach."""
if self._mode != STATE_HEAT_COOL and not self.is_away_mode_on: if self._mode != NEST_MODE_HEAT_COOL and not self.is_away_mode_on:
return self._target_temperature return self._target_temperature
return None return None
@ -136,7 +135,7 @@ class NestThermostat(ClimateDevice):
self._eco_temperature[0]: self._eco_temperature[0]:
# eco_temperature is always a low, high tuple # eco_temperature is always a low, high tuple
return self._eco_temperature[0] return self._eco_temperature[0]
if self._mode == STATE_HEAT_COOL: if self._mode == NEST_MODE_HEAT_COOL:
return self._target_temperature[0] return self._target_temperature[0]
return None return None
@ -147,7 +146,7 @@ class NestThermostat(ClimateDevice):
self._eco_temperature[1]: self._eco_temperature[1]:
# eco_temperature is always a low, high tuple # eco_temperature is always a low, high tuple
return self._eco_temperature[1] return self._eco_temperature[1]
if self._mode == STATE_HEAT_COOL: if self._mode == NEST_MODE_HEAT_COOL:
return self._target_temperature[1] return self._target_temperature[1]
return None return None
@ -160,7 +159,7 @@ class NestThermostat(ClimateDevice):
"""Set new target temperature.""" """Set new target temperature."""
target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW) target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH) target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
if self._mode == STATE_HEAT_COOL: if self._mode == NEST_MODE_HEAT_COOL:
if target_temp_low is not None and target_temp_high is not None: if target_temp_low is not None and target_temp_high is not None:
temp = (target_temp_low, target_temp_high) temp = (target_temp_low, target_temp_high)
else: else:
@ -173,7 +172,7 @@ class NestThermostat(ClimateDevice):
if operation_mode in [STATE_HEAT, STATE_COOL, STATE_OFF, STATE_ECO]: if operation_mode in [STATE_HEAT, STATE_COOL, STATE_OFF, STATE_ECO]:
device_mode = operation_mode device_mode = operation_mode
elif operation_mode == STATE_AUTO: elif operation_mode == STATE_AUTO:
device_mode = STATE_HEAT_COOL device_mode = NEST_MODE_HEAT_COOL
self.device.mode = device_mode self.device.mode = device_mode
@property @property

View file

@ -18,7 +18,8 @@ DEFAULT_EXPOSE_BY_DEFAULT = True
DEFAULT_EXPOSED_DOMAINS = [ DEFAULT_EXPOSED_DOMAINS = [
'switch', 'light', 'group', 'media_player', 'fan', 'cover', 'climate' 'switch', 'light', 'group', 'media_player', 'fan', 'cover', 'climate'
] ]
CLIMATE_SUPPORTED_MODES = {'heat', 'cool', 'off', 'on', 'heatcool'} CLIMATE_MODE_HEATCOOL = 'heatcool'
CLIMATE_SUPPORTED_MODES = {'heat', 'cool', 'off', 'on', CLIMATE_MODE_HEATCOOL}
PREFIX_TRAITS = 'action.devices.traits.' PREFIX_TRAITS = 'action.devices.traits.'
TRAIT_ONOFF = PREFIX_TRAITS + 'OnOff' TRAIT_ONOFF = PREFIX_TRAITS + 'OnOff'

View file

@ -33,7 +33,7 @@ from .const import (
TRAIT_ONOFF, TRAIT_BRIGHTNESS, TRAIT_COLOR_TEMP, TRAIT_ONOFF, TRAIT_BRIGHTNESS, TRAIT_COLOR_TEMP,
TRAIT_RGB_COLOR, TRAIT_SCENE, TRAIT_TEMPERATURE_SETTING, TRAIT_RGB_COLOR, TRAIT_SCENE, TRAIT_TEMPERATURE_SETTING,
TYPE_LIGHT, TYPE_SCENE, TYPE_SWITCH, TYPE_THERMOSTAT, TYPE_LIGHT, TYPE_SCENE, TYPE_SWITCH, TYPE_THERMOSTAT,
CONF_ALIASES, CLIMATE_SUPPORTED_MODES CONF_ALIASES, CLIMATE_SUPPORTED_MODES, CLIMATE_MODE_HEATCOOL
) )
HANDLERS = Registry() HANDLERS = Registry()
@ -147,12 +147,15 @@ def entity_to_device(entity: Entity, config: Config, units: UnitSystem):
entity.attributes.get(light.ATTR_MIN_MIREDS)))) entity.attributes.get(light.ATTR_MIN_MIREDS))))
if entity.domain == climate.DOMAIN: if entity.domain == climate.DOMAIN:
modes = ','.join( modes = []
m.lower() for m in entity.attributes.get( for mode in entity.attributes.get(climate.ATTR_OPERATION_LIST, []):
climate.ATTR_OPERATION_LIST, []) if mode in CLIMATE_SUPPORTED_MODES:
if m.lower() in CLIMATE_SUPPORTED_MODES) modes.append(mode)
elif mode == climate.STATE_AUTO:
modes.append(CLIMATE_MODE_HEATCOOL)
device['attributes'] = { device['attributes'] = {
'availableThermostatModes': modes, 'availableThermostatModes': ','.join(modes),
'thermostatTemperatureUnit': 'thermostatTemperatureUnit':
'F' if units.temperature_unit == TEMP_FAHRENHEIT else 'C', 'F' if units.temperature_unit == TEMP_FAHRENHEIT else 'C',
} }
@ -323,9 +326,9 @@ def determine_service(
# special climate handling # special climate handling
if domain == climate.DOMAIN: if domain == climate.DOMAIN:
if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT: if command == COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT:
service_data['temperature'] = units.temperature( service_data['temperature'] = \
params.get('thermostatTemperatureSetpoint', 25), units.temperature(
TEMP_CELSIUS) params['thermostatTemperatureSetpoint'], TEMP_CELSIUS)
return (climate.SERVICE_SET_TEMPERATURE, service_data) return (climate.SERVICE_SET_TEMPERATURE, service_data)
if command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE: if command == COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE:
service_data['target_temp_high'] = units.temperature( service_data['target_temp_high'] = units.temperature(
@ -336,8 +339,12 @@ def determine_service(
TEMP_CELSIUS) TEMP_CELSIUS)
return (climate.SERVICE_SET_TEMPERATURE, service_data) return (climate.SERVICE_SET_TEMPERATURE, service_data)
if command == COMMAND_THERMOSTAT_SET_MODE: if command == COMMAND_THERMOSTAT_SET_MODE:
service_data['operation_mode'] = params.get( mode = params['thermostatMode']
'thermostatMode', 'off')
if mode == CLIMATE_MODE_HEATCOOL:
mode = climate.STATE_AUTO
service_data['operation_mode'] = mode
return (climate.SERVICE_SET_OPERATION_MODE, service_data) return (climate.SERVICE_SET_OPERATION_MODE, service_data)
if command == COMMAND_BRIGHTNESS: if command == COMMAND_BRIGHTNESS:

View file

@ -211,7 +211,7 @@ DEMO_DEVICES = [{
'type': 'action.devices.types.THERMOSTAT', 'type': 'action.devices.types.THERMOSTAT',
'willReportState': False, 'willReportState': False,
'attributes': { 'attributes': {
'availableThermostatModes': 'heat,cool,off', 'availableThermostatModes': 'heat,cool,heatcool,off',
'thermostatTemperatureUnit': 'C', 'thermostatTemperatureUnit': 'C',
}, },
}, { }, {