mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 12:47:08 +00:00
Update nest SDM climate simplifying support for eco mode (#42955)
This commit is contained in:
parent
e477e94ddd
commit
64f06b2b00
@ -46,7 +46,6 @@ THERMOSTAT_MODE_MAP = {
|
|||||||
"HEAT": HVAC_MODE_HEAT,
|
"HEAT": HVAC_MODE_HEAT,
|
||||||
"COOL": HVAC_MODE_COOL,
|
"COOL": HVAC_MODE_COOL,
|
||||||
"HEATCOOL": HVAC_MODE_HEAT_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()}
|
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,
|
"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]
|
THERMOSTAT_RANGE_MODES = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO]
|
||||||
|
|
||||||
PRESET_MODE_MAP = {
|
PRESET_MODE_MAP = {
|
||||||
@ -170,7 +161,7 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
@property
|
@property
|
||||||
def target_temperature_high(self):
|
def target_temperature_high(self):
|
||||||
"""Return the upper bound target temperature."""
|
"""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
|
return None
|
||||||
trait = self._target_temperature_trait
|
trait = self._target_temperature_trait
|
||||||
if not trait:
|
if not trait:
|
||||||
@ -180,7 +171,7 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
@property
|
@property
|
||||||
def target_temperature_low(self):
|
def target_temperature_low(self):
|
||||||
"""Return the lower bound target temperature."""
|
"""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
|
return None
|
||||||
trait = self._target_temperature_trait
|
trait = self._target_temperature_trait
|
||||||
if not trait:
|
if not trait:
|
||||||
@ -192,20 +183,16 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
"""Return the correct trait with a target temp depending on mode."""
|
"""Return the correct trait with a target temp depending on mode."""
|
||||||
if not self.hvac_mode:
|
if not self.hvac_mode:
|
||||||
return None
|
return None
|
||||||
if self.hvac_mode not in THERMOSTAT_SETPOINT_TRAIT_MAP:
|
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
|
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]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hvac_mode(self):
|
def hvac_mode(self):
|
||||||
"""Return the current operation (e.g. heat, cool, idle)."""
|
"""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:
|
if ThermostatModeTrait.NAME in self._device.traits:
|
||||||
trait = self._device.traits[ThermostatModeTrait.NAME]
|
trait = self._device.traits[ThermostatModeTrait.NAME]
|
||||||
if trait.mode in THERMOSTAT_MODE_MAP:
|
if trait.mode in THERMOSTAT_MODE_MAP:
|
||||||
@ -228,9 +215,6 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
if ThermostatModeTrait.NAME in self._device.traits:
|
if ThermostatModeTrait.NAME in self._device.traits:
|
||||||
trait = self._device.traits[ThermostatModeTrait.NAME]
|
trait = self._device.traits[ThermostatModeTrait.NAME]
|
||||||
modes.extend(trait.available_modes)
|
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)
|
return set(modes)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -274,7 +258,7 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
def fan_modes(self):
|
def fan_modes(self):
|
||||||
"""Return the list of available fan modes."""
|
"""Return the list of available fan modes."""
|
||||||
if FanTrait.NAME in self._device.traits:
|
if FanTrait.NAME in self._device.traits:
|
||||||
return list(FAN_INV_MODE_MAP.keys())
|
return list(FAN_INV_MODE_MAP)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -285,7 +269,7 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
def _get_supported_features(self):
|
def _get_supported_features(self):
|
||||||
"""Compute the bitmap of supported features from the current state."""
|
"""Compute the bitmap of supported features from the current state."""
|
||||||
features = 0
|
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
|
features |= SUPPORT_TARGET_TEMPERATURE_RANGE
|
||||||
if HVAC_MODE_HEAT in self.hvac_modes or HVAC_MODE_COOL in self.hvac_modes:
|
if HVAC_MODE_HEAT in self.hvac_modes or HVAC_MODE_COOL in self.hvac_modes:
|
||||||
features |= SUPPORT_TARGET_TEMPERATURE
|
features |= SUPPORT_TARGET_TEMPERATURE
|
||||||
@ -320,11 +304,11 @@ class ThermostatEntity(ClimateEntity):
|
|||||||
trait = self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
|
trait = self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
|
||||||
if self.preset_mode == PRESET_ECO or self.hvac_mode == HVAC_MODE_HEAT_COOL:
|
if self.preset_mode == PRESET_ECO or self.hvac_mode == HVAC_MODE_HEAT_COOL:
|
||||||
if low_temp and high_temp:
|
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:
|
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:
|
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):
|
async def async_set_preset_mode(self, preset_mode):
|
||||||
"""Set new target preset mode."""
|
"""Set new target preset mode."""
|
||||||
|
@ -23,7 +23,6 @@ from homeassistant.components.climate.const import (
|
|||||||
CURRENT_HVAC_OFF,
|
CURRENT_HVAC_OFF,
|
||||||
FAN_OFF,
|
FAN_OFF,
|
||||||
FAN_ON,
|
FAN_ON,
|
||||||
HVAC_MODE_AUTO,
|
|
||||||
HVAC_MODE_COOL,
|
HVAC_MODE_COOL,
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
@ -267,7 +266,6 @@ async def test_thermostat_eco_off(hass):
|
|||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
HVAC_MODE_COOL,
|
HVAC_MODE_COOL,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
HVAC_MODE_AUTO,
|
|
||||||
HVAC_MODE_OFF,
|
HVAC_MODE_OFF,
|
||||||
}
|
}
|
||||||
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 22.0
|
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
|
assert len(hass.states.async_all()) == 1
|
||||||
thermostat = hass.states.get("climate.my_thermostat")
|
thermostat = hass.states.get("climate.my_thermostat")
|
||||||
assert thermostat is not None
|
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_HVAC_ACTION] == CURRENT_HVAC_COOL
|
||||||
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
assert thermostat.attributes[ATTR_CURRENT_TEMPERATURE] == 29.9
|
||||||
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
assert set(thermostat.attributes[ATTR_HVAC_MODES]) == {
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
HVAC_MODE_COOL,
|
HVAC_MODE_COOL,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
HVAC_MODE_AUTO,
|
|
||||||
HVAC_MODE_OFF,
|
HVAC_MODE_OFF,
|
||||||
}
|
}
|
||||||
assert thermostat.attributes[ATTR_TARGET_TEMP_LOW] == 21.0
|
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]
|
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:
|
class FakeAuth:
|
||||||
"""A fake implementation of the auth class that records requests."""
|
"""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")
|
thermostat = hass.states.get("climate.my_thermostat")
|
||||||
assert thermostat is not None
|
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_HVAC_ACTION] == CURRENT_HVAC_OFF
|
||||||
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_ECO
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user