Issue #628 add follow underlying temp change entity (#630)

* First commit (no test)

* With tests ok

---------

Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
This commit is contained in:
Jean-Marc Collin
2024-11-13 19:14:03 +01:00
committed by GitHub
parent d31376d55d
commit b46a24f834
4 changed files with 200 additions and 8 deletions

View File

@@ -14,6 +14,6 @@
"quality_scale": "silver",
"requirements": [],
"ssdp": [],
"version": "6.6.0",
"version": "6.7.0",
"zeroconf": []
}

View File

@@ -34,10 +34,16 @@ async def async_setup_entry(
vt_type = entry.data.get(CONF_THERMOSTAT_TYPE)
auto_start_stop_feature = entry.data.get(CONF_USE_AUTO_START_STOP_FEATURE)
if vt_type == CONF_THERMOSTAT_CLIMATE and auto_start_stop_feature is True:
# Creates a switch to enable the auto-start/stop
enable_entity = AutoStartStopEnable(hass, unique_id, name, entry)
async_add_entities([enable_entity], True)
entities = []
if vt_type == CONF_THERMOSTAT_CLIMATE:
entities.append(FollowUnderlyingTemperatureChange(hass, unique_id, name, entry))
if auto_start_stop_feature is True:
# Creates a switch to enable the auto-start/stop
enable_entity = AutoStartStopEnable(hass, unique_id, name, entry)
entities.append(enable_entity)
async_add_entities(entities, True)
class AutoStartStopEnable(VersatileThermostatBaseEntity, SwitchEntity, RestoreEntity):
@@ -100,3 +106,63 @@ class AutoStartStopEnable(VersatileThermostatBaseEntity, SwitchEntity, RestoreEn
def turn_on(self, **kwargs: Any):
self._attr_is_on = True
self.update_my_state_and_vtherm()
class FollowUnderlyingTemperatureChange(
VersatileThermostatBaseEntity, SwitchEntity, RestoreEntity
):
"""The that enables the ManagedDevice optimisation with"""
def __init__(
self, hass: HomeAssistant, unique_id: str, name: str, entry_infos: ConfigEntry
):
super().__init__(hass, unique_id, name)
self._attr_name = "Follow underlying temp change"
self._attr_unique_id = f"{self._device_name}_follow_underlying_temp_change"
self._attr_is_on = False
@property
def icon(self) -> str | None:
"""The icon"""
return "mdi:content-copy"
async def async_added_to_hass(self):
await super().async_added_to_hass()
# Récupérer le dernier état sauvegardé de l'entité
last_state = await self.async_get_last_state()
# Si l'état précédent existe, vous pouvez l'utiliser
if last_state is not None:
self._attr_is_on = last_state.state == "on"
else:
# If no previous state set it to false by default
self._attr_is_on = False
self.update_my_state_and_vtherm()
def update_my_state_and_vtherm(self):
"""Update the follow flag in my VTherm"""
self.async_write_ha_state()
if self.my_climate is not None:
self.my_climate.set_follow_underlying_temp_change(self._attr_is_on)
@callback
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on."""
self.turn_on()
@callback
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
self.turn_off()
@overrides
def turn_off(self, **kwargs: Any):
self._attr_is_on = False
self.update_my_state_and_vtherm()
@overrides
def turn_on(self, **kwargs: Any):
self._attr_is_on = True
self.update_my_state_and_vtherm()

View File

@@ -62,6 +62,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
_auto_start_stop_level: TYPE_AUTO_START_STOP_LEVELS = AUTO_START_STOP_LEVEL_NONE
_auto_start_stop_algo: AutoStartStopDetectionAlgorithm | None = None
_is_auto_start_stop_enabled: bool = False
_follow_underlying_temp_change: bool = False
_entity_component_unrecorded_attributes = (
BaseThermostat._entity_component_unrecorded_attributes.union(
@@ -82,6 +83,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
"auto_start_stop_enable",
"auto_start_stop_accumulated_error",
"auto_start_stop_accumulated_error_threshold",
"follow_underlying_temp_change",
}
)
)
@@ -552,6 +554,10 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
"auto_start_stop_accumulated_error_threshold"
] = self._auto_start_stop_algo.accumulated_error_threshold
self._attr_extra_state_attributes["follow_underlying_temp_change"] = (
self._follow_underlying_temp_change
)
self.async_write_ha_state()
_LOGGER.debug(
@@ -853,7 +859,11 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
# try to manage new target temperature set if state if no other changes have been found
# and if a target temperature have already been sent
if not changes and under.last_sent_temperature is not None:
if (
self._follow_underlying_temp_change
and not changes
and under.last_sent_temperature is not None
):
_LOGGER.debug(
"Do temperature check. under.last_sent_temperature is %s, new_target_temp is %s",
under.last_sent_temperature,
@@ -972,6 +982,11 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
self._is_auto_start_stop_enabled = is_enabled
self.update_custom_attributes()
def set_follow_underlying_temp_change(self, follow: bool):
"""Set the flaf follow the underlying temperature changes"""
self._follow_underlying_temp_change = follow
self.update_custom_attributes()
@property
def auto_regulation_mode(self) -> str | None:
"""Get the regulation mode"""
@@ -1128,6 +1143,11 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
"""Returns the auto_start_stop_enable"""
return self._is_auto_start_stop_enabled
@property
def follow_underlying_temp_change(self) -> bool:
"""Get the follow underlying temp change flag"""
return self._follow_underlying_temp_change
@overrides
def init_underlyings(self):
"""Init the underlyings if not already done"""