mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Handle unknown preset mode in generic thermostat (#55588)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
f5a543b220
commit
c81a319346
@ -182,14 +182,17 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self._temp_lock = asyncio.Lock()
|
self._temp_lock = asyncio.Lock()
|
||||||
self._min_temp = min_temp
|
self._min_temp = min_temp
|
||||||
self._max_temp = max_temp
|
self._max_temp = max_temp
|
||||||
|
self._attr_preset_mode = PRESET_NONE
|
||||||
self._target_temp = target_temp
|
self._target_temp = target_temp
|
||||||
self._unit = unit
|
self._unit = unit
|
||||||
self._unique_id = unique_id
|
self._unique_id = unique_id
|
||||||
self._support_flags = SUPPORT_FLAGS
|
self._support_flags = SUPPORT_FLAGS
|
||||||
if away_temp:
|
if away_temp:
|
||||||
self._support_flags = SUPPORT_FLAGS | SUPPORT_PRESET_MODE
|
self._support_flags = SUPPORT_FLAGS | SUPPORT_PRESET_MODE
|
||||||
|
self._attr_preset_modes = [PRESET_NONE, PRESET_AWAY]
|
||||||
|
else:
|
||||||
|
self._attr_preset_modes = [PRESET_NONE]
|
||||||
self._away_temp = away_temp
|
self._away_temp = away_temp
|
||||||
self._is_away = False
|
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Run when entity about to be added."""
|
"""Run when entity about to be added."""
|
||||||
@ -247,8 +250,8 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self._target_temp = float(old_state.attributes[ATTR_TEMPERATURE])
|
self._target_temp = float(old_state.attributes[ATTR_TEMPERATURE])
|
||||||
if old_state.attributes.get(ATTR_PRESET_MODE) == PRESET_AWAY:
|
if old_state.attributes.get(ATTR_PRESET_MODE) in self._attr_preset_modes:
|
||||||
self._is_away = True
|
self._attr_preset_mode = old_state.attributes.get(ATTR_PRESET_MODE)
|
||||||
if not self._hvac_mode and old_state.state:
|
if not self._hvac_mode and old_state.state:
|
||||||
self._hvac_mode = old_state.state
|
self._hvac_mode = old_state.state
|
||||||
|
|
||||||
@ -343,16 +346,6 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
|||||||
"""List of available operation modes."""
|
"""List of available operation modes."""
|
||||||
return self._hvac_list
|
return self._hvac_list
|
||||||
|
|
||||||
@property
|
|
||||||
def preset_mode(self):
|
|
||||||
"""Return the current preset mode, e.g., home, away, temp."""
|
|
||||||
return PRESET_AWAY if self._is_away else PRESET_NONE
|
|
||||||
|
|
||||||
@property
|
|
||||||
def preset_modes(self):
|
|
||||||
"""Return a list of available preset modes or PRESET_NONE if _away_temp is undefined."""
|
|
||||||
return [PRESET_NONE, PRESET_AWAY] if self._away_temp else PRESET_NONE
|
|
||||||
|
|
||||||
async def async_set_hvac_mode(self, hvac_mode):
|
async def async_set_hvac_mode(self, hvac_mode):
|
||||||
"""Set hvac mode."""
|
"""Set hvac mode."""
|
||||||
if hvac_mode == HVAC_MODE_HEAT:
|
if hvac_mode == HVAC_MODE_HEAT:
|
||||||
@ -521,13 +514,20 @@ class GenericThermostat(ClimateEntity, RestoreEntity):
|
|||||||
|
|
||||||
async def async_set_preset_mode(self, preset_mode: str):
|
async def async_set_preset_mode(self, preset_mode: str):
|
||||||
"""Set new preset mode."""
|
"""Set new preset mode."""
|
||||||
if preset_mode == PRESET_AWAY and not self._is_away:
|
if preset_mode not in (self._attr_preset_modes or []):
|
||||||
self._is_away = True
|
raise ValueError(
|
||||||
|
f"Got unsupported preset_mode {preset_mode}. Must be one of {self._attr_preset_modes}"
|
||||||
|
)
|
||||||
|
if preset_mode == self._attr_preset_mode:
|
||||||
|
# I don't think we need to call async_write_ha_state if we didn't change the state
|
||||||
|
return
|
||||||
|
if preset_mode == PRESET_AWAY:
|
||||||
|
self._attr_preset_mode = PRESET_AWAY
|
||||||
self._saved_target_temp = self._target_temp
|
self._saved_target_temp = self._target_temp
|
||||||
self._target_temp = self._away_temp
|
self._target_temp = self._away_temp
|
||||||
await self._async_control_heating(force=True)
|
await self._async_control_heating(force=True)
|
||||||
elif preset_mode == PRESET_NONE and self._is_away:
|
elif preset_mode == PRESET_NONE:
|
||||||
self._is_away = False
|
self._attr_preset_mode = PRESET_NONE
|
||||||
self._target_temp = self._saved_target_temp
|
self._target_temp = self._saved_target_temp
|
||||||
await self._async_control_heating(force=True)
|
await self._async_control_heating(force=True)
|
||||||
|
|
||||||
|
@ -324,6 +324,21 @@ async def test_set_away_mode_twice_and_restore_prev_temp(hass, setup_comp_2):
|
|||||||
assert state.attributes.get("temperature") == 23
|
assert state.attributes.get("temperature") == 23
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_preset_mode_invalid(hass, setup_comp_2):
|
||||||
|
"""Test an invalid mode raises an error and ignore case when checking modes."""
|
||||||
|
await common.async_set_temperature(hass, 23)
|
||||||
|
await common.async_set_preset_mode(hass, "away")
|
||||||
|
state = hass.states.get(ENTITY)
|
||||||
|
assert state.attributes.get("preset_mode") == "away"
|
||||||
|
await common.async_set_preset_mode(hass, "none")
|
||||||
|
state = hass.states.get(ENTITY)
|
||||||
|
assert state.attributes.get("preset_mode") == "none"
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
await common.async_set_preset_mode(hass, "Sleep")
|
||||||
|
state = hass.states.get(ENTITY)
|
||||||
|
assert state.attributes.get("preset_mode") == "none"
|
||||||
|
|
||||||
|
|
||||||
async def test_sensor_bad_value(hass, setup_comp_2):
|
async def test_sensor_bad_value(hass, setup_comp_2):
|
||||||
"""Test sensor that have None as state."""
|
"""Test sensor that have None as state."""
|
||||||
state = hass.states.get(ENTITY)
|
state = hass.states.get(ENTITY)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user