Compare commits

..

5 Commits

Author SHA1 Message Date
Jean-Marc Collin 00d0659eef +1 2023-10-14 17:36:17 +02:00
Jean-Marc Collin 0b22abefa0 Issue #121 - try fix 2023-10-14 17:34:40 +02:00
Jean-Marc Collin a6ad8e7927 +1 2023-10-14 09:29:42 +02:00
Jean-Marc Collin 23ee8f3d7f NPE fix 2023-10-14 08:49:28 +02:00
Jean-Marc Collin 03723375e2 Issue #121 - loop when underlying is slow 2023-10-14 08:28:04 +02:00
8 changed files with 19 additions and 37 deletions
+2 -4
View File
@@ -31,8 +31,6 @@ jobs:
- run: black .
tests:
# Tests don't run in Gitlab ci environment
if: 0
runs-on: "ubuntu-latest"
name: Run tests
steps:
@@ -43,10 +41,10 @@ jobs:
with:
python-version: "3.8"
- name: Install requirements
run: cd custom_components/versatile_thermostat && python3 -m pip install -r requirements_test.txt
run: python3 -m pip install -r requirements_test.txt
- name: Run tests
run: |
cd custom_components/versatile_thermostat && pytest \
pytest \
-qq \
--timeout=9 \
--durations=10 \
@@ -956,6 +956,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
"""Return current operation."""
# Issue #114 - returns my current hvac_mode and not the underlying hvac_mode which could be different
# delta will be managed by climate_state_change event.
# TODO remove this when ok
# if self._is_over_climate:
# if one not OFF -> return it
# else OFF
@@ -1597,14 +1598,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
@callback
async def _async_climate_changed(self, event):
"""Handle unerdlying climate state changes.
This method takes the underlying values and update the VTherm with them.
To avoid loops (issues #121 #101 #95 #99), we discard the event if it is received
less than 10 sec after the last command. What we want here is to take the values
from underlyings ONLY if someone have change directly on the underlying and not
as a return of the command. The only thing we take all the time is the HVACAction
which is important for feedaback and which cannot generates loops.
"""
"""Handle unerdlying climate state changes."""
async def end_climate_changed(changes):
""" To end the event management"""
@@ -1694,8 +1688,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
)
changes = True
# Issue #120 - Some TRV are chaning target temperature a very long time (6 sec) after the change.
# In that case a loop is possible if a user change multiple times during this 6 sec.
# Issue #120 - Some TRV are chaning target temperature a very long time (6 sec) after the change. In that case a loop is possible because
if new_state_date_updated and self._last_change_time:
delta = (new_state_date_updated - self._last_change_time).total_seconds()
if delta < 10:
@@ -2145,6 +2138,9 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
now - self._last_ext_temperature_mesure.replace(tzinfo=self._current_tz)
).total_seconds() / 60.0
# TODO before change:
# mode_cond = self._is_over_climate or self._hvac_mode != HVACMode.OFF
# fixed into this. Why if _is_over_climate we could into security even if HVACMode is OFF ?
mode_cond = self._hvac_mode != HVACMode.OFF
temp_cond: bool = (
@@ -2426,7 +2422,7 @@ class VersatileThermostat(ClimateEntity, RestoreEntity):
"window_auto_max_duration": self._window_auto_max_duration,
}
if self._is_over_climate:
self._attr_extra_state_attributes["underlying_climate_0"] = self._underlyings[
self._attr_extra_state_attributes["underlying_climate_1"] = self._underlyings[
0
].entity_id
self._attr_extra_state_attributes["underlying_climate_1"] = self._underlyings[
@@ -14,6 +14,6 @@
"quality_scale": "silver",
"requirements": [],
"ssdp": [],
"version": "3.5.3",
"version": "3.0.0",
"zeroconf": []
}
@@ -1,2 +1,2 @@
homeassistant==2023.10.3
homeassistant==2023.10.1
ffmpeg
@@ -1,5 +1,4 @@
# For automatic run of test in Gitlab CI, we must not include other things that pytest-homeassistant-custom-component
#-r requirements_dev.txt
-r requirements_dev.txt
# aiodiscover
# ulid_transform
ulid_transform
pytest-homeassistant-custom-component
@@ -530,16 +530,9 @@ async def test_bug_101(
await entity.async_set_preset_mode(PRESET_COMFORT)
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)
# 2. Change the target temp of underlying thermostat
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
# 2. Change the target temp of underlying thermostat at 11 sec later -> the event will 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.75)
# Should have been switched to Manual preset
assert entity.target_temperature == 12.75
assert entity.preset_mode is PRESET_NONE
@@ -163,7 +163,7 @@ async def test_one_switch_cycle(
await asyncio.sleep(0.1)
assert mock_heater_on.call_count == 1
# normal ? assert entity.underlying_entity(0)._should_relaunch_control_heating is False
# TODO normal ? assert entity.underlying_entity(0)._should_relaunch_control_heating is False
# Simulate the end of heater on cycle
event_timestamp = now - timedelta(minutes=3)
@@ -522,9 +522,7 @@ async def test_multiple_climates_underlying_changes(
), patch(
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.set_hvac_mode"
) as mock_underlying_set_hvac_mode:
# Wait 11 sec so that the event will not be discarded
event_timestamp = now + timedelta(seconds=11)
await send_climate_change_event(entity, HVACMode.OFF, HVACMode.HEAT, HVACAction.OFF, HVACAction.HEATING, event_timestamp)
await send_climate_change_event(entity, HVACMode.OFF, HVACMode.HEAT, HVACAction.OFF, HVACAction.HEATING, now)
# Should be call for all Switch
assert mock_underlying_set_hvac_mode.call_count == 4
@@ -545,9 +543,7 @@ async def test_multiple_climates_underlying_changes(
# notice that there is no need of return_value=HVACAction.IDLE because this is not a function but a property
"custom_components.versatile_thermostat.underlyings.UnderlyingClimate.hvac_action", HVACAction.IDLE
) as mock_underlying_get_hvac_action:
# Wait 11 sec so that the event will not be discarded
event_timestamp = now + timedelta(seconds=11)
await send_climate_change_event(entity, HVACMode.HEAT, HVACMode.OFF, HVACAction.IDLE, HVACAction.OFF, event_timestamp)
await send_climate_change_event(entity, HVACMode.HEAT, HVACMode.OFF, HVACAction.IDLE, HVACAction.OFF, now)
# Should be call for all Switch
assert mock_underlying_set_hvac_mode.call_count == 4
+1 -1
View File
@@ -3,5 +3,5 @@
"content_in_root": false,
"render_readme": true,
"hide_default_branch": false,
"homeassistant": "2023.10.3"
"homeassistant": "2023.7.3"
}