Răsfoiți Sursa

Fix full poll starvation from frequent push updates (#4472)

* Fix full poll starvation from frequent push updates

Devices that send frequent push updates (e.g. power readings every
~8 seconds) keep resetting last_cache, preventing the cache timeout
condition from ever triggering a full status poll. This causes DPS
values only available via full polls (like temperatures) to go stale.

Track the last full poll time separately and force a full poll when
it has been longer than CACHE_TIMEOUT since the last one, regardless
of how recently push data was received.

Fixes #4470

* fix (device): don't override force polling with new needs_poll

The previous code alternated force polls and full polls for those devices that need force polling. This is because the full poll does not return some dps (that need the force poll), but the force poll only returns those specified dps. We need to keep that behaviour.

Also fixed lint formatting issue.

PR #4472

---------

Co-authored-by: Jason Rumney <make-all@users.noreply.github.com>
leah-potato 12 ore în urmă
părinte
comite
5b1b8ddaff
1 a modificat fișierele cu 6 adăugiri și 1 ștergeri
  1. 6 1
      custom_components/tuya_local/device.py

+ 6 - 1
custom_components/tuya_local/device.py

@@ -322,7 +322,10 @@ class TuyaLocalDevice(object):
                     if self._api.parent:
                         self._api.parent.set_socketPersistent(persist)
 
-                if now - last_cache > self._CACHE_TIMEOUT:
+                needs_full_poll = now - self._last_full_poll > self._CACHE_TIMEOUT
+                if now - last_cache > self._CACHE_TIMEOUT or (
+                    persist and needs_full_poll
+                ):
                     if (
                         self._force_dps
                         and not dps_updated
@@ -340,6 +343,7 @@ class TuyaLocalDevice(object):
                         )
                         dps_updated = False
                         full_poll = True
+                    self._last_full_poll = now
                 elif persist:
                     await self._hass.async_add_executor_job(
                         self._api.heartbeat,
@@ -496,6 +500,7 @@ class TuyaLocalDevice(object):
         self._cached_state = {"updated_at": 0}
         self._pending_updates = {}
         self._last_connection = 0
+        self._last_full_poll = 0
 
     def _refresh_cached_state(self):
         new_state = self._api.status()