Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions custom_components/goecharger_api2/pygoecharger_ha/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ async def read_all(self) -> dict:

async def read_all_states(self):
do_minimal_status_update: bool = False
updated_states = {}
if self.isCharger:
# ok we are in idle state - so we do not need all states... [but 5 minutes (=300sec) do a full update]
if Tag.CAR.key in self._states and self._states[Tag.CAR.key] == CAR_VALUES.IDLE.value:
Expand All @@ -353,6 +354,7 @@ async def read_all_states(self):
idle_states = self._read_filtered_data_from_ws_source(filters=filter, log_info="read_idle_states")
else:
idle_states = await self._read_filtered_data(filters=filter, log_info="read_idle_states")
updated_states = idle_states

if len(idle_states) > 0:
# copy all fields from 'idle_states' to self._states
Expand All @@ -370,15 +372,23 @@ async def read_all_states(self):
await self.read_all_states()

else:
filter = self._FILTER_ALL_STATES
if self.ws_connected:
self._states = self._read_filtered_data_from_ws_source(filters=self._FILTER_ALL_STATES, log_info="read_all_states")
self._states = self._read_filtered_data_from_ws_source(filters=filter, log_info="read_all_states")
else:
ret = await self._read_filtered_data(filters=self._FILTER_ALL_STATES, log_info="read_all_states")
ret = await self._read_filtered_data(filters=filter, log_info="read_all_states")
if ret is not None and len(ret) > 0 and isinstance(ret, NonNullDict):
self._states = ret
updated_states = ret
if len(self._states) > 0:
self._LAST_FULL_STATE_UPDATE_TS = time.time()

if not self.ws_connected and updated_states:
# Fresh polled states replace cached write results, including expiry to null.
for a_key in filter.split(","):
if a_key in updated_states:
self._ws_states.pop(a_key, None)

async def force_config_update(self):
self._LAST_CONFIG_UPDATE_TS = 0
self._LAST_FULL_STATE_UPDATE_TS = 0
Expand Down
28 changes: 28 additions & 0 deletions tests/integration/test_bridge_polling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""
import asyncio
import time
from collections import ChainMap
from types import SimpleNamespace
from unittest.mock import AsyncMock, patch

Expand Down Expand Up @@ -202,6 +203,33 @@ async def test_force_config_update_over_websocket_still_works(hass, aioclient_mo

# ----------------------------------------------------------------------------- read_all

@pytest.mark.parametrize("car", [1, 4])
@pytest.mark.parametrize("reported", [None, 8])
async def test_poll_replaces_cached_tcl_write_with_reported_value(hass, aioclient_mock, car, reported):
coordinator = make_coordinator(hass)
bridge = coordinator.bridge
bridge._states = NonNullDict({"car": car, "tcl": 6})
bridge._config = NonNullDict({"amp": 16, "ama": 16})
bridge._LAST_CONFIG_UPDATE_TS = bridge._LAST_FULL_STATE_UPDATE_TS = time.time()
coordinator.data = ChainMap(bridge._ws_states, bridge._config, bridge._states, bridge._versions)
coordinator.handle_write_result("single", 6, "tcl", {"tcl": 6}, None)
assert bridge._ws_states["tcl"] == 6
aioclient_mock.get(STATUS, json={"car": car, "tcl": reported})
data = await bridge.read_all()
assert data["tcl"] == reported and "tcl" not in bridge._ws_states
assert data["amp"] == data["ama"] == 16


async def test_failed_poll_keeps_cached_tcl_write(hass, aioclient_mock):
bridge = make_bridge(hass)
bridge._states = NonNullDict({"car": 4, "tcl": 6})
bridge._ws_states["tcl"] = 6
bridge._LAST_CONFIG_UPDATE_TS = time.time()
aioclient_mock.get(STATUS, status=503)
assert (await bridge.read_all())["tcl"] == 6
assert bridge._ws_states["tcl"] == 6


async def test_read_all_returns_a_merged_view_with_websocket_values_first(hass, aioclient_mock):
aioclient_mock.get(STATUS, json={"car": 1, "amp": 6})
bridge = make_bridge(hass)
Expand Down
Loading