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:
parent
280c1601a2
commit
07b2f38046
4 changed files with 29 additions and 22 deletions
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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',
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue