Compare commits

..

3 Commits

Author SHA1 Message Date
Jean-Marc Collin
f6afaf2715 with local tests ok. (#555)
Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
2024-10-14 09:02:50 +02:00
Jean-Marc Collin
de9b95903e Add testu 2024-10-14 04:56:12 +00:00
Jean-Marc Collin
d112273c58 Fix preset temp is sommetimes lost on over_climate 2024-10-14 04:43:19 +00:00
3 changed files with 77 additions and 18 deletions

View File

@@ -692,6 +692,12 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
else None else None
) )
under_temp_diff = (
(new_target_temp - under.last_sent_temperature) if new_target_temp else 0
)
if -1 < under_temp_diff < 1:
under_temp_diff = 0
# Issue 99 - some AC turn hvac_mode=cool and hvac_action=idle when sending a HVACMode_OFF command # Issue 99 - some AC turn hvac_mode=cool and hvac_action=idle when sending a HVACMode_OFF command
# Issue 114 - Remove this because hvac_mode is now managed by local _hvac_mode and use idle action as is # Issue 114 - Remove this because hvac_mode is now managed by local _hvac_mode and use idle action as is
# if self._hvac_mode == HVACMode.OFF and new_hvac_action == HVACAction.IDLE: # if self._hvac_mode == HVACMode.OFF and new_hvac_action == HVACAction.IDLE:
@@ -702,7 +708,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
if ( if (
new_hvac_mode == self._hvac_mode new_hvac_mode == self._hvac_mode
and new_hvac_action == old_hvac_action and new_hvac_action == old_hvac_action
and new_target_temp is None and under_temp_diff == 0
and (new_fan_mode is None or new_fan_mode == self._attr_fan_mode) and (new_fan_mode is None or new_fan_mode == self._attr_fan_mode)
): ):
_LOGGER.debug( _LOGGER.debug(
@@ -834,11 +840,8 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
under.last_sent_temperature, under.last_sent_temperature,
new_target_temp, new_target_temp,
) )
if ( # if the underlying have change its target temperature
# if the underlying have change its target temperature if under_temp_diff != 0:
new_target_temp is not None
and new_target_temp != under.last_sent_temperature
):
_LOGGER.info( _LOGGER.info(
"%s - Target temp in underlying have change to %s (vs %s)", "%s - Target temp in underlying have change to %s (vs %s)",
self, self,
@@ -849,7 +852,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
changes = True changes = True
else: else:
_LOGGER.debug( _LOGGER.debug(
"%s - Forget the eventual underlying temperature change because VTherm is regulated", "%s - Forget the eventual underlying temperature change there is no real change",
self, self,
) )

View File

@@ -552,7 +552,7 @@ class UnderlyingClimate(UnderlyingEntity):
if self.is_initialized: if self.is_initialized:
return ( return (
self._underlying_climate.hvac_mode != HVACMode.OFF self._underlying_climate.hvac_mode != HVACMode.OFF
and self._underlying_climate.hvac_action and self.hvac_action
not in [ not in [
HVACAction.IDLE, HVACAction.IDLE,
HVACAction.OFF, HVACAction.OFF,
@@ -650,7 +650,36 @@ class UnderlyingClimate(UnderlyingEntity):
"""Get the hvac action of the underlying""" """Get the hvac action of the underlying"""
if not self.is_initialized: if not self.is_initialized:
return None return None
return self._underlying_climate.hvac_action
hvac_action = self._underlying_climate.hvac_action
if hvac_action is None:
target = (
self.underlying_target_temperature
or self._thermostat.target_temperature
)
current = (
self.underlying_current_temperature
or self._thermostat.current_temperature
)
hvac_mode = self.hvac_mode
_LOGGER.debug(
"%s - hvac_action simulation target=%s, current=%s, hvac_mode=%s",
self,
target,
current,
hvac_mode,
)
hvac_action = HVACAction.IDLE
if target is not None and current is not None:
dtemp = target - current
if hvac_mode == HVACMode.COOL and dtemp < 0:
hvac_action = HVACAction.COOLING
elif hvac_mode in [HVACMode.HEAT, HVACMode.HEAT_COOL] and dtemp > 0:
hvac_action = HVACAction.HEATING
return hvac_action
@property @property
def hvac_mode(self) -> HVACMode | None: def hvac_mode(self) -> HVACMode | None:
@@ -730,18 +759,19 @@ class UnderlyingClimate(UnderlyingEntity):
return self._underlying_climate.target_temperature_low return self._underlying_climate.target_temperature_low
@property @property
def target_temperature(self) -> float: def underlying_target_temperature(self) -> float:
"""Get the target_temperature""" """Get the target_temperature"""
if not self.is_initialized: if not self.is_initialized:
return None return None
return self._underlying_climate.target_temperature
@property if not hasattr(self._underlying_climate, "target_temperature"):
def is_aux_heat(self) -> bool: return None
"""Get the is_aux_heat""" else:
if not self.is_initialized: return self._underlying_climate.target_temperature
return False
return self._underlying_climate.is_aux_heat # return self._hass.states.get(self._entity_id).attributes.get(
# "target_temperature"
# )
@property @property
def underlying_current_temperature(self) -> float | None: def underlying_current_temperature(self) -> float | None:
@@ -752,8 +782,17 @@ class UnderlyingClimate(UnderlyingEntity):
if not hasattr(self._underlying_climate, "current_temperature"): if not hasattr(self._underlying_climate, "current_temperature"):
return None return None
else:
return self._underlying_climate.current_temperature
return self._hass.states.get(self._entity_id).attributes.get("current_temperature") # return self._hass.states.get(self._entity_id).attributes.get("current_temperature")
@property
def is_aux_heat(self) -> bool:
"""Get the is_aux_heat"""
if not self.is_initialized:
return False
return self._underlying_climate.is_aux_heat
def turn_aux_heat_on(self) -> None: def turn_aux_heat_on(self) -> None:
"""Turn auxiliary heater on.""" """Turn auxiliary heater on."""

View File

@@ -302,6 +302,23 @@ async def test_bug_101(
assert entity.target_temperature == 12.75 assert entity.target_temperature == 12.75
assert entity.preset_mode is PRESET_NONE assert entity.preset_mode is PRESET_NONE
# 4. Change the target temp with < 1 value. The value should not be taken
# Wait 11 sec
event_timestamp = now + timedelta(seconds=11)
await send_climate_change_event_with_temperature(
entity,
HVACMode.HEAT,
HVACMode.HEAT,
HVACAction.OFF,
HVACAction.OFF,
event_timestamp,
12.5, # 12.75 means 13 in vtherm
True,
"climate.mock_climate", # the underlying climate entity id
)
assert entity.target_temperature == 12.75
assert entity.preset_mode is PRESET_NONE
@pytest.mark.parametrize("expected_lingering_timers", [True]) @pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_bug_508( async def test_bug_508(