Try auto window new algo

This commit is contained in:
Jean-Marc Collin
2023-11-28 06:38:47 +00:00
parent 18a72bd907
commit 5540f6e8a9
4 changed files with 49 additions and 30 deletions

View File

@@ -506,17 +506,15 @@ class RegulatedTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
"""Called when my climate have change"""
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
if math.isnan(self.my_climate.regulated_target_temp) or math.isinf(
self.my_climate.regulated_target_temp
):
raise ValueError(
f"Sensor has illegal state {self.my_climate.regulated_target_temp}"
)
new_temp = self.my_climate.regulated_target_temp
if new_temp is None:
return
if math.isnan(new_temp) or math.isinf(new_temp):
raise ValueError(f"Sensor has illegal state {new_temp}")
old_state = self._attr_native_value
self._attr_native_value = round(
self.my_climate.regulated_target_temp, self.suggested_display_precision
)
self._attr_native_value = round(new_temp, self.suggested_display_precision)
if old_state != self._attr_native_value:
self.async_write_ha_state()
return
@@ -559,15 +557,15 @@ class EMATemperatureSensor(VersatileThermostatBaseEntity, SensorEntity):
"""Called when my climate have change"""
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
if math.isnan(self.my_climate.ema_temperature) or math.isinf(
self.my_climate.ema_temperature
):
raise ValueError(
f"Sensor has illegal state {self.my_climate.ema_temperature}"
)
new_ema = self.my_climate.ema_temperature
if new_ema is None:
return
if math.isnan(new_ema) or math.isinf(new_ema):
raise ValueError(f"Sensor has illegal state {new_ema}")
old_state = self._attr_native_value
self._attr_native_value = self.my_climate.ema_temperature
self._attr_native_value = new_ema
if old_state != self._attr_native_value:
self.async_write_ha_state()
return

View File

@@ -363,12 +363,12 @@ async def test_over_climate_regulation_limitations(
"custom_components.versatile_thermostat.commons.NowClass.get_now",
return_value=event_timestamp,
):
await send_temperature_change_event(entity, 16, event_timestamp)
await send_temperature_change_event(entity, 15, event_timestamp)
await send_ext_temperature_change_event(entity, 12, event_timestamp)
# the regulated should have been done
assert entity.regulated_target_temp != old_regulated_temp
assert entity.regulated_target_temp >= entity.target_temperature
assert (
entity.regulated_target_temp == 17 + 0.5
entity.regulated_target_temp == 17 + 1.5
) # 0.7 without round_to_nearest

View File

@@ -2,7 +2,9 @@
""" Test the OpenWindow algorithm """
from datetime import datetime, timedelta
from custom_components.versatile_thermostat.open_window_algorithm import WindowOpenDetectionAlgorithm
from custom_components.versatile_thermostat.open_window_algorithm import (
WindowOpenDetectionAlgorithm,
)
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
@@ -19,18 +21,28 @@ async def test_open_window_algo(
tz = get_tz(hass) # pylint: disable=invalid-name
now = datetime.now(tz)
event_timestamp = now - timedelta(minutes=5)
event_timestamp = now - timedelta(minutes=10)
last_slope = the_algo.add_temp_measurement(
temperature=10, datetime_measure=event_timestamp
)
# We need at least 2 measurement
# We need at least 4 measurement
assert last_slope is None
assert the_algo.last_slope is None
assert the_algo.is_window_close_detected() is False
assert the_algo.is_window_open_detected() is False
event_timestamp = now - timedelta(minutes=4)
event_timestamp = now - timedelta(minutes=9)
last_slope = the_algo.add_temp_measurement(
temperature=10, datetime_measure=event_timestamp
)
event_timestamp = now - timedelta(minutes=8)
last_slope = the_algo.add_temp_measurement(
temperature=10, datetime_measure=event_timestamp
)
event_timestamp = now - timedelta(minutes=7)
last_slope = the_algo.add_temp_measurement(
temperature=10, datetime_measure=event_timestamp
)
@@ -41,19 +53,19 @@ async def test_open_window_algo(
assert the_algo.is_window_close_detected() is True
assert the_algo.is_window_open_detected() is False
event_timestamp = now - timedelta(minutes=3)
event_timestamp = now - timedelta(minutes=6)
last_slope = the_algo.add_temp_measurement(
temperature=9, datetime_measure=event_timestamp
)
# A slope is calculated
assert last_slope == -0.5
assert the_algo.last_slope == -0.5
assert last_slope == -0.8
assert the_algo.last_slope == -0.8
assert the_algo.is_window_close_detected() is False
assert the_algo.is_window_open_detected() is False
# A new temperature with 2 degre less in one minute (value will be rejected)
event_timestamp = now - timedelta(minutes=2)
event_timestamp = now - timedelta(minutes=5)
last_slope = the_algo.add_temp_measurement(
temperature=7, datetime_measure=event_timestamp
)
@@ -65,7 +77,7 @@ async def test_open_window_algo(
assert the_algo.is_window_open_detected() is True
# A new temperature with 1 degre less
event_timestamp = now - timedelta(minutes=1)
event_timestamp = now - timedelta(minutes=4)
last_slope = the_algo.add_temp_measurement(
temperature=6, datetime_measure=event_timestamp
)
@@ -77,7 +89,7 @@ async def test_open_window_algo(
assert the_algo.is_window_open_detected() is True
# A new temperature with 0 degre less
event_timestamp = now - timedelta(minutes=0)
event_timestamp = now - timedelta(minutes=3)
last_slope = the_algo.add_temp_measurement(
temperature=6, datetime_measure=event_timestamp
)
@@ -89,7 +101,7 @@ async def test_open_window_algo(
assert the_algo.is_window_open_detected() is False
# A new temperature with 1 degre more
event_timestamp = now + timedelta(minutes=1)
event_timestamp = now + timedelta(minutes=2)
last_slope = the_algo.add_temp_measurement(
temperature=7, datetime_measure=event_timestamp
)

View File

@@ -477,6 +477,14 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
assert entity.window_state is STATE_OFF
# Initialize the slope algo with 2 measurements
# event_timestamp = now - timedelta(minutes=9)
# await send_temperature_change_event(entity, 19, event_timestamp)
# event_timestamp = now - timedelta(minutes=8)
# await send_temperature_change_event(entity, 19, event_timestamp)
# event_timestamp = now - timedelta(minutes=7)
# await send_temperature_change_event(entity, 19, event_timestamp)
# Make the temperature down
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
@@ -486,6 +494,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.is_device_active",
return_value=True,
):
# This is the 3rd measurment. Slope is not ready
event_timestamp = now - timedelta(minutes=4)
await send_temperature_change_event(entity, 19, event_timestamp)
@@ -531,7 +540,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
assert entity.window_auto_state == STATE_ON
assert entity.hvac_mode is HVACMode.OFF
# Waits for automatic disable
# Waits for automatic disable
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(