Update nest SDM climate simplifying support for eco mode (#42955)

This commit is contained in:
Allen Porter 2020-11-09 02:35:38 -08:00 committed by GitHub
parent e477e94ddd
commit 64f06b2b00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 34 deletions

View File

@ -46,7 +46,6 @@ THERMOSTAT_MODE_MAP = {
"HEAT": HVAC_MODE_HEAT,
"COOL": HVAC_MODE_COOL,
"HEATCOOL": HVAC_MODE_HEAT_COOL,
"MANUAL_ECO": HVAC_MODE_AUTO,
}
THERMOSTAT_INV_MODE_MAP = {v: k for k, v in THERMOSTAT_MODE_MAP.items()}
@ -60,14 +59,6 @@ THERMOSTAT_HVAC_STATUS_MAP = {
"COOLING": CURRENT_HVAC_COOL,
}
# Mapping to determine the trait that supports the target temperatures
# based on the current HVAC mode
THERMOSTAT_SETPOINT_TRAIT_MAP = {
HVAC_MODE_COOL: ThermostatTemperatureSetpointTrait.NAME,
HVAC_MODE_HEAT: ThermostatTemperatureSetpointTrait.NAME,
HVAC_MODE_HEAT_COOL: ThermostatTemperatureSetpointTrait.NAME,
HVAC_MODE_AUTO: ThermostatEcoTrait.NAME,
}
THERMOSTAT_RANGE_MODES = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO]
PRESET_MODE_MAP = {
@ -170,7 +161,7 @@ class ThermostatEntity(ClimateEntity):
@property
def target_temperature_high(self):
"""Return the upper bound target temperature."""
if self.hvac_mode not in THERMOSTAT_RANGE_MODES:
if self.hvac_mode != HVAC_MODE_HEAT_COOL:
return None
trait = self._target_temperature_trait
if not trait:
@ -180,7 +171,7 @@ class ThermostatEntity(ClimateEntity):
@property
def target_temperature_low(self):
"""Return the lower bound target temperature."""
if self.hvac_mode not in THERMOSTAT_RANGE_MODES:
if self.hvac_mode != HVAC_MODE_HEAT_COOL:
return None
trait = self._target_temperature_trait
if not trait:
@ -192,20 +183,16 @@ class ThermostatEntity(ClimateEntity):
"""Return the correct trait with a target temp depending on mode."""
if not self.hvac_mode:
return None
if self.hvac_mode not in THERMOSTAT_SETPOINT_TRAIT_MAP:
return None
trait_name = THERMOSTAT_SETPOINT_TRAIT_MAP[self.hvac_mode]
if trait_name not in self._device.traits:
return None
return self._device.traits[trait_name]
if self.preset_mode == PRESET_ECO:
if ThermostatEcoTrait.NAME in self._device.traits:
return self._device.traits[ThermostatEcoTrait.NAME]
if ThermostatTemperatureSetpointTrait.NAME in self._device.traits:
return self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
return None
@property
def hvac_mode(self):
"""Return the current operation (e.g. heat, cool, idle)."""
if ThermostatEcoTrait.NAME in self._device.traits:
trait = self._device.traits[ThermostatEcoTrait.NAME]
if trait.mode == THERMOSTAT_ECO_MODE:
return HVAC_MODE_AUTO
if ThermostatModeTrait.NAME in self._device.traits:
trait = self._device.traits[ThermostatModeTrait.NAME]
if trait.mode in THERMOSTAT_MODE_MAP:
@ -228,9 +215,6 @@ class ThermostatEntity(ClimateEntity):
if ThermostatModeTrait.NAME in self._device.traits:
trait = self._device.traits[ThermostatModeTrait.NAME]
modes.extend(trait.available_modes)
if ThermostatEcoTrait.NAME in self._device.traits:
trait = self._device.traits[ThermostatEcoTrait.NAME]
modes.extend(trait.available_modes)
return set(modes)
@property
@ -274,7 +258,7 @@ class ThermostatEntity(ClimateEntity):
def fan_modes(self):
"""Return the list of available fan modes."""
if FanTrait.NAME in self._device.traits:
return list(FAN_INV_MODE_MAP.keys())
return list(FAN_INV_MODE_MAP)
return []
@property
@ -285,7 +269,7 @@ class ThermostatEntity(ClimateEntity):
def _get_supported_features(self):
"""Compute the bitmap of supported features from the current state."""
features = 0
if HVAC_MODE_HEAT_COOL in self.hvac_modes or HVAC_MODE_AUTO in self.hvac_modes:
if HVAC_MODE_HEAT_COOL in self.hvac_modes:
features |= SUPPORT_TARGET_TEMPERATURE_RANGE
if HVAC_MODE_HEAT in self.hvac_modes or HVAC_MODE_COOL in self.hvac_modes:
features |= SUPPORT_TARGET_TEMPERATURE
@ -320,11 +304,11 @@ class ThermostatEntity(ClimateEntity):
trait = self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
if self.preset_mode == PRESET_ECO or self.hvac_mode == HVAC_MODE_HEAT_COOL:
if low_temp and high_temp:
return await trait.set_range(low_temp, high_temp)
await trait.set_range(low_temp, high_temp)
elif self.hvac_mode == HVAC_MODE_COOL and temp:
return await trait.set_cool(temp)
await trait.set_cool(temp)
elif self.hvac_mode == HVAC_MODE_HEAT and temp:
return await trait.set_heat(temp)
await trait.set_heat(temp)
async def async_set_preset_mode(self, preset_mode):
"""Set new target preset mode."""

View File

@ -23,7 +23,6 @@ from homeassistant.components.climate.const import (
CURRENT_HVAC_OFF,
FAN_OFF,
FAN_ON,
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_HEAT,
HVAC_MODE_HEAT_COOL,
@ -267,7 +266,6 @@ async def test_thermostat_eco_off(hass):
HVAC_MODE_HEAT,
HVAC_MODE_COOL,
HVAC_MODE_HEAT_COOL,
HVAC_MODE_AUTO,
HVAC_MODE_OFF,
}
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 22.0
@ -308,14 +306,13 @@ async def test_thermostat_eco_on(hass):
assert len(hass.states.async_all()) == 1
thermostat = hass.states.get("climate.my_thermostat")
assert thermostat is not None
assert thermostat.state == HVAC_MODE_AUTO
assert thermostat.state == HVAC_MODE_HEAT_COOL
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_COOL
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
HVAC_MODE_HEAT,
HVAC_MODE_COOL,
HVAC_MODE_HEAT_COOL,
HVAC_MODE_AUTO,
HVAC_MODE_OFF,
}
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 21.0
@ -325,6 +322,48 @@ async def test_thermostat_eco_on(hass):
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
async def test_thermostat_eco_heat_only(hass):
"""Test a thermostat in eco mode that only supports heat."""
await setup_climate(
hass,
{
"sdm.devices.traits.ThermostatHvac": {
"status": "OFF",
},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "OFF"],
"mode": "HEAT",
},
"sdm.devices.traits.ThermostatEco": {
"availableModes": ["MANUAL_ECO", "OFF"],
"mode": "MANUAL_ECO",
"heatCelsius": 21.0,
"coolCelsius": 29.0,
},
"sdm.devices.traits.Temperature": {
"ambientTemperatureCelsius": 29.9,
},
"sdm.devices.traits.ThermostatTemperatureSetpoint": {},
},
)
assert len(hass.states.async_all()) == 1
thermostat = hass.states.get("climate.my_thermostat")
assert thermostat is not None
assert thermostat.state == HVAC_MODE_HEAT
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
}
assert thermostat.attributes[ATTR_TEMPERATURE] == 21.0
assert ATTR_TARGET_TEMP_LOW not in thermostat.attributes
assert ATTR_TARGET_TEMP_HIGH not in thermostat.attributes
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
class FakeAuth:
"""A fake implementation of the auth class that records requests."""
@ -498,7 +537,7 @@ async def test_thermostat_set_eco_preset(hass):
thermostat = hass.states.get("climate.my_thermostat")
assert thermostat is not None
assert thermostat.state == HVAC_MODE_AUTO
assert thermostat.state == HVAC_MODE_OFF
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO