From b6f52bcc1b2882bf40757731c59667719dce5446 Mon Sep 17 00:00:00 2001 From: Jean-Marc Collin Date: Sun, 3 Dec 2023 18:05:22 +0000 Subject: [PATCH] =?UTF-8?q?Issue=20#21=C3=A0=20-=20rename=20mesure=20with?= =?UTF-8?q?=20measure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../versatile_thermostat/base_thermostat.py | 60 +++++++++---------- .../versatile_thermostat/sensor.py | 4 +- tests/test_bugs.py | 48 +++++++++++---- tests/test_security.py | 48 +++++++-------- 4 files changed, 92 insertions(+), 68 deletions(-) diff --git a/custom_components/versatile_thermostat/base_thermostat.py b/custom_components/versatile_thermostat/base_thermostat.py index c8f1274..02dc7e7 100644 --- a/custom_components/versatile_thermostat/base_thermostat.py +++ b/custom_components/versatile_thermostat/base_thermostat.py @@ -131,8 +131,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity): # The list of VersatileThermostat entities _hass: HomeAssistant - _last_temperature_mesure: datetime - _last_ext_temperature_mesure: datetime + _last_temperature_measure: datetime + _last_ext_temperature_measure: datetime _total_energy: float _overpowering_state: bool _window_state: bool @@ -217,8 +217,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity): self._motion_call_cancel = None self._cur_temp = None self._ac_mode = None - self._last_ext_temperature_mesure = None - self._last_temperature_mesure = None + self._last_ext_temperature_measure = None + self._last_temperature_measure = None self._cur_ext_temp = None self._presence_state = None self._overpowering_state = None @@ -429,8 +429,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity): else DEFAULT_SECURITY_DEFAULT_ON_PERCENT ) self._minimal_activation_delay = entry_infos.get(CONF_MINIMAL_ACTIVATION_DELAY) - self._last_temperature_mesure = datetime.now(tz=self._current_tz) - self._last_ext_temperature_mesure = datetime.now(tz=self._current_tz) + self._last_temperature_measure = datetime.now(tz=self._current_tz) + self._last_ext_temperature_measure = datetime.now(tz=self._current_tz) self._security_state = False # Initiate the ProportionalAlgorithm @@ -1017,14 +1017,14 @@ class BaseThermostat(ClimateEntity, RestoreEntity): return self._prop_algorithm @property - def last_temperature_mesure(self) -> datetime | None: + def last_temperature_measure(self) -> datetime | None: """Get the last temperature datetime""" - return self._last_temperature_mesure + return self._last_temperature_measure @property - def last_ext_temperature_mesure(self) -> datetime | None: + def last_ext_temperature_measure(self) -> datetime | None: """Get the last external temperature datetime""" - return self._last_ext_temperature_mesure + return self._last_ext_temperature_measure @property def preset_mode(self) -> str | None: @@ -1191,8 +1191,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity): self._attr_preset_mode not in HIDDEN_PRESETS and old_preset_mode not in HIDDEN_PRESETS ): - self._last_temperature_mesure = ( - self._last_ext_temperature_mesure + self._last_temperature_measure = ( + self._last_ext_temperature_measure ) = datetime.now(tz=self._current_tz) def find_preset_temp(self, preset_mode): @@ -1509,17 +1509,17 @@ class BaseThermostat(ClimateEntity, RestoreEntity): raise ValueError(f"Sensor has illegal state {state.state}") self._cur_temp = cur_temp - self._last_temperature_mesure = self.get_state_date_or_now(state) + self._last_temperature_measure = self.get_state_date_or_now(state) # calculate the smooth_temperature with EMA calculation self._ema_temp = self._ema_algo.calculate_ema( - self._cur_temp, self._last_temperature_mesure + self._cur_temp, self._last_temperature_measure ) _LOGGER.debug( - "%s - After setting _last_temperature_mesure %s , state.last_changed.replace=%s", + "%s - After setting _last_temperature_measure %s , state.last_changed.replace=%s", self, - self._last_temperature_mesure, + self._last_temperature_measure, state.last_changed.astimezone(self._current_tz), ) @@ -1541,12 +1541,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity): if math.isnan(cur_ext_temp) or math.isinf(cur_ext_temp): raise ValueError(f"Sensor has illegal state {state.state}") self._cur_ext_temp = cur_ext_temp - self._last_ext_temperature_mesure = self.get_state_date_or_now(state) + self._last_ext_temperature_measure = self.get_state_date_or_now(state) _LOGGER.debug( - "%s - After setting _last_ext_temperature_mesure %s , state.last_changed.replace=%s", + "%s - After setting _last_ext_temperature_measure %s , state.last_changed.replace=%s", self, - self._last_ext_temperature_mesure, + self._last_ext_temperature_measure, state.last_changed.astimezone(self._current_tz), ) @@ -1726,7 +1726,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity): else: slope = self._window_auto_algo.add_temp_measurement( temperature=self._ema_temp, - datetime_measure=self._last_temperature_mesure, + datetime_measure=self._last_temperature_measure, ) _LOGGER.debug( @@ -1930,10 +1930,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity): """Check if last temperature date is too long""" now = self.now delta_temp = ( - now - self._last_temperature_mesure.replace(tzinfo=self._current_tz) + now - self._last_temperature_measure.replace(tzinfo=self._current_tz) ).total_seconds() / 60.0 delta_ext_temp = ( - now - self._last_ext_temperature_mesure.replace(tzinfo=self._current_tz) + now - self._last_ext_temperature_measure.replace(tzinfo=self._current_tz) ).total_seconds() / 60.0 mode_cond = self._hvac_mode != HVACMode.OFF @@ -2004,10 +2004,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity): self.send_event( EventType.TEMPERATURE_EVENT, { - "last_temperature_mesure": self._last_temperature_mesure.replace( + "last_temperature_measure": self._last_temperature_measure.replace( tzinfo=self._current_tz ).isoformat(), - "last_ext_temperature_mesure": self._last_ext_temperature_mesure.replace( + "last_ext_temperature_measure": self._last_ext_temperature_measure.replace( tzinfo=self._current_tz ).isoformat(), "current_temp": self._cur_temp, @@ -2032,10 +2032,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity): EventType.SECURITY_EVENT, { "type": "start", - "last_temperature_mesure": self._last_temperature_mesure.replace( + "last_temperature_measure": self._last_temperature_measure.replace( tzinfo=self._current_tz ).isoformat(), - "last_ext_temperature_mesure": self._last_ext_temperature_mesure.replace( + "last_ext_temperature_measure": self._last_ext_temperature_measure.replace( tzinfo=self._current_tz ).isoformat(), "current_temp": self._cur_temp, @@ -2063,10 +2063,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity): EventType.SECURITY_EVENT, { "type": "end", - "last_temperature_mesure": self._last_temperature_mesure.replace( + "last_temperature_measure": self._last_temperature_measure.replace( tzinfo=self._current_tz ).isoformat(), - "last_ext_temperature_mesure": self._last_ext_temperature_mesure.replace( + "last_ext_temperature_measure": self._last_ext_temperature_measure.replace( tzinfo=self._current_tz ).isoformat(), "current_temp": self._cur_temp, @@ -2191,10 +2191,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity): "security_delay_min": self._security_delay_min, "security_min_on_percent": self._security_min_on_percent, "security_default_on_percent": self._security_default_on_percent, - "last_temperature_datetime": self._last_temperature_mesure.astimezone( + "last_temperature_datetime": self._last_temperature_measure.astimezone( self._current_tz ).isoformat(), - "last_ext_temperature_datetime": self._last_ext_temperature_mesure.astimezone( + "last_ext_temperature_datetime": self._last_ext_temperature_measure.astimezone( self._current_tz ).isoformat(), "security_state": self._security_state, diff --git a/custom_components/versatile_thermostat/sensor.py b/custom_components/versatile_thermostat/sensor.py index f11d734..a72833d 100644 --- a/custom_components/versatile_thermostat/sensor.py +++ b/custom_components/versatile_thermostat/sensor.py @@ -396,7 +396,7 @@ class LastTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity): _LOGGER.debug("%s - climate state change", self._attr_unique_id) old_state = self._attr_native_value - self._attr_native_value = self.my_climate.last_temperature_mesure + self._attr_native_value = self.my_climate.last_temperature_measure if old_state != self._attr_native_value: self.async_write_ha_state() return @@ -425,7 +425,7 @@ class LastExtTemperatureSensor(VersatileThermostatBaseEntity, SensorEntity): _LOGGER.debug("%s - climate state change", self._attr_unique_id) old_state = self._attr_native_value - self._attr_native_value = self.my_climate.last_ext_temperature_mesure + self._attr_native_value = self.my_climate.last_ext_temperature_measure if old_state != self._attr_native_value: self.async_write_ha_state() return diff --git a/tests/test_bugs.py b/tests/test_bugs.py index 23ae0e9..efb5956 100644 --- a/tests/test_bugs.py +++ b/tests/test_bugs.py @@ -7,6 +7,7 @@ from datetime import datetime, timedelta import logging from .commons import * + logging.getLogger().setLevel(logging.DEBUG) @@ -362,10 +363,12 @@ async def test_bug_82( domain=DOMAIN, title="TheOverClimateMockName", unique_id="uniqueId", - data=PARTIAL_CLIMATE_CONFIG, # 5 minutes security delay + data=PARTIAL_CLIMATE_CONFIG, # 5 minutes security delay ) - fake_underlying_climate = MockUnavailableClimate(hass, "mockUniqueId", "MockClimateName", {}) + fake_underlying_climate = MockUnavailableClimate( + hass, "mockUniqueId", "MockClimateName", {} + ) with patch( "custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event" @@ -420,11 +423,13 @@ async def test_bug_82( mock_find_climate.assert_has_calls([call.find_underlying_entity()]) # Force security mode - assert entity._last_ext_temperature_mesure is not None - assert entity._last_temperature_mesure is not None - assert (entity._last_temperature_mesure.astimezone(tz) - now).total_seconds() < 1 + assert entity._last_ext_temperature_measure is not None + assert entity._last_temperature_measure is not None assert ( - entity._last_ext_temperature_mesure.astimezone(tz) - now + entity._last_temperature_measure.astimezone(tz) - now + ).total_seconds() < 1 + assert ( + entity._last_ext_temperature_measure.astimezone(tz) - now ).total_seconds() < 1 # Tries to turns on the Thermostat @@ -443,8 +448,9 @@ async def test_bug_82( await send_temperature_change_event(entity, 15, event_timestamp) # Should stay False assert entity.security_state is False - assert entity.preset_mode == 'none' - assert entity._saved_preset_mode == 'none' + assert entity.preset_mode == "none" + assert entity._saved_preset_mode == "none" + @pytest.mark.parametrize("expected_lingering_tasks", [True]) @pytest.mark.parametrize("expected_lingering_timers", [True]) @@ -463,11 +469,13 @@ async def test_bug_101( domain=DOMAIN, title="TheOverClimateMockName", unique_id="uniqueId", - data=PARTIAL_CLIMATE_NOT_REGULATED_CONFIG, # 5 minutes security delay + data=PARTIAL_CLIMATE_NOT_REGULATED_CONFIG, # 5 minutes security delay ) # Underlying is in HEAT mode but should be shutdown at startup - fake_underlying_climate = MockClimate(hass, "mockUniqueId", "MockClimateName", {}, HVACMode.HEAT, HVACAction.HEATING) + fake_underlying_climate = MockClimate( + hass, "mockUniqueId", "MockClimateName", {}, HVACMode.HEAT, HVACAction.HEATING + ) with patch( "custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event" @@ -531,7 +539,15 @@ async def test_bug_101( assert entity.preset_mode == PRESET_COMFORT # 2. Change the target temp of underlying thermostat at now -> the event will be disgarded because to fast (to avoid loop cf issue 121) - await send_climate_change_event_with_temperature(entity, HVACMode.HEAT, HVACMode.HEAT, HVACAction.OFF, HVACAction.OFF, now, 12.75) + await send_climate_change_event_with_temperature( + entity, + HVACMode.HEAT, + HVACMode.HEAT, + HVACAction.OFF, + HVACAction.OFF, + now, + 12.75, + ) # Should NOT have been switched to Manual preset assert entity.target_temperature == 17 assert entity.preset_mode is PRESET_COMFORT @@ -540,6 +556,14 @@ async def test_bug_101( # Wait 11 sec event_timestamp = now + timedelta(seconds=11) assert entity.is_regulated is False - await send_climate_change_event_with_temperature(entity, HVACMode.HEAT, HVACMode.HEAT, HVACAction.OFF, HVACAction.OFF, event_timestamp, 12.75) + await send_climate_change_event_with_temperature( + entity, + HVACMode.HEAT, + HVACMode.HEAT, + HVACAction.OFF, + HVACAction.OFF, + event_timestamp, + 12.75, + ) assert entity.target_temperature == 12.75 assert entity.preset_mode is PRESET_NONE diff --git a/tests/test_security.py b/tests/test_security.py index 8000432..1ea8f6e 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -76,11 +76,11 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state): PRESET_COMFORT, PRESET_BOOST, ] - assert entity._last_ext_temperature_mesure is not None - assert entity._last_temperature_mesure is not None - assert (entity._last_temperature_mesure.astimezone(tz) - now).total_seconds() < 1 + assert entity._last_ext_temperature_measure is not None + assert entity._last_temperature_measure is not None + assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1 assert ( - entity._last_ext_temperature_mesure.astimezone(tz) - now + entity._last_ext_temperature_measure.astimezone(tz) - now ).total_seconds() < 1 # set a preset @@ -116,8 +116,8 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state): call.send_event( EventType.TEMPERATURE_EVENT, { - "last_temperature_mesure": event_timestamp.isoformat(), - "last_ext_temperature_mesure": entity._last_ext_temperature_mesure.isoformat(), + "last_temperature_measure": event_timestamp.isoformat(), + "last_ext_temperature_measure": entity._last_ext_temperature_measure.isoformat(), "current_temp": 15, "current_ext_temp": None, "target_temp": 18, @@ -127,8 +127,8 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state): EventType.SECURITY_EVENT, { "type": "start", - "last_temperature_mesure": event_timestamp.isoformat(), - "last_ext_temperature_mesure": entity._last_ext_temperature_mesure.isoformat(), + "last_temperature_measure": event_timestamp.isoformat(), + "last_ext_temperature_measure": entity._last_ext_temperature_measure.isoformat(), "current_temp": 15, "current_ext_temp": None, "target_temp": 18, @@ -180,10 +180,10 @@ async def test_security_feature(hass: HomeAssistant, skip_hass_states_is_state): EventType.SECURITY_EVENT, { "type": "end", - "last_temperature_mesure": event_timestamp.astimezone( + "last_temperature_measure": event_timestamp.astimezone( tz ).isoformat(), - "last_ext_temperature_mesure": entity._last_ext_temperature_mesure.astimezone( + "last_ext_temperature_measure": entity._last_ext_temperature_measure.astimezone( tz ).isoformat(), "current_temp": 15.2, @@ -253,11 +253,11 @@ async def test_security_feature_back_on_percent( assert entity._security_state is False assert entity.preset_mode is not PRESET_SECURITY - assert entity._last_ext_temperature_mesure is not None - assert entity._last_temperature_mesure is not None - assert (entity._last_temperature_mesure.astimezone(tz) - now).total_seconds() < 1 + assert entity._last_ext_temperature_measure is not None + assert entity._last_temperature_measure is not None + assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1 assert ( - entity._last_ext_temperature_mesure.astimezone(tz) - now + entity._last_ext_temperature_measure.astimezone(tz) - now ).total_seconds() < 1 # set a preset @@ -311,8 +311,8 @@ async def test_security_feature_back_on_percent( call.send_event( EventType.TEMPERATURE_EVENT, { - "last_temperature_mesure": event_timestamp.isoformat(), - "last_ext_temperature_mesure": entity._last_ext_temperature_mesure.isoformat(), + "last_temperature_measure": event_timestamp.isoformat(), + "last_ext_temperature_measure": entity._last_ext_temperature_measure.isoformat(), "current_temp": 17, "current_ext_temp": None, "target_temp": 19, @@ -322,8 +322,8 @@ async def test_security_feature_back_on_percent( EventType.SECURITY_EVENT, { "type": "start", - "last_temperature_mesure": event_timestamp.isoformat(), - "last_ext_temperature_mesure": entity._last_ext_temperature_mesure.isoformat(), + "last_temperature_measure": event_timestamp.isoformat(), + "last_ext_temperature_measure": entity._last_ext_temperature_measure.isoformat(), "current_temp": 17, "current_ext_temp": None, "target_temp": 19, @@ -371,10 +371,10 @@ async def test_security_feature_back_on_percent( EventType.SECURITY_EVENT, { "type": "end", - "last_temperature_mesure": event_timestamp.astimezone( + "last_temperature_measure": event_timestamp.astimezone( tz ).isoformat(), - "last_ext_temperature_mesure": entity._last_ext_temperature_mesure.astimezone( + "last_ext_temperature_measure": entity._last_ext_temperature_measure.astimezone( tz ).isoformat(), "current_temp": 18.92, @@ -469,13 +469,13 @@ async def test_security_over_climate( mock_find_climate.assert_has_calls([call.find_underlying_entity()]) # Force security mode - assert entity._last_ext_temperature_mesure is not None - assert entity._last_temperature_mesure is not None + assert entity._last_ext_temperature_measure is not None + assert entity._last_temperature_measure is not None assert ( - entity._last_temperature_mesure.astimezone(tz) - now + entity._last_temperature_measure.astimezone(tz) - now ).total_seconds() < 1 assert ( - entity._last_ext_temperature_mesure.astimezone(tz) - now + entity._last_ext_temperature_measure.astimezone(tz) - now ).total_seconds() < 1 # Tries to turns on the Thermostat