Skip to content
Snippets Groups Projects
Unverified Commit 64f06b2b authored by Allen Porter's avatar Allen Porter Committed by GitHub
Browse files

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

parent e477e94d
No related branches found
No related tags found
No related merge requests found
...@@ -46,7 +46,6 @@ THERMOSTAT_MODE_MAP = { ...@@ -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 = { ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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:
return None if ThermostatEcoTrait.NAME in self._device.traits:
trait_name = THERMOSTAT_SETPOINT_TRAIT_MAP[self.hvac_mode] return self._device.traits[ThermostatEcoTrait.NAME]
if trait_name not in self._device.traits: if ThermostatTemperatureSetpointTrait.NAME in self._device.traits:
return None return self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
return self._device.traits[trait_name] return None
@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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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 ( ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment