Browse Source

device.py: resist rotating api versions again

When a device has been working using a protocol version, then any
communication failures are unlikely to be due to a protocol version
change.  Such changes will only happen after a device firmware upgrade
which is a rare case.  Instead of restarting protocol detection
immediately, give another 10 attempts (each "attempt" being 3
failures) using the current protocol, which is most likely to work.

Recent changes at the request of users who want to detect offline
devices faster have made things less resilient for devices which are
having intermittent network issues.  This change attempts to address
that.

Issue #653
Jason Rumney 2 năm trước cách đây
mục cha
commit
63d3e14229

+ 10 - 1
custom_components/tuya_local/device.py

@@ -66,6 +66,7 @@ class TuyaLocalDevice(object):
         self._startup_listener = None
         self._startup_listener = None
         self._api_protocol_version_index = None
         self._api_protocol_version_index = None
         self._api_protocol_working = False
         self._api_protocol_working = False
+        self._api_working_protocol_failures = 0
         try:
         try:
             if dev_cid is not None:
             if dev_cid is not None:
                 self._api = tinytuya.Device(
                 self._api = tinytuya.Device(
@@ -111,6 +112,8 @@ class TuyaLocalDevice(object):
         # the possibilities a couple of times
         # the possibilities a couple of times
         self._AUTO_CONNECTION_ATTEMPTS = len(API_PROTOCOL_VERSIONS) * 2 + 1
         self._AUTO_CONNECTION_ATTEMPTS = len(API_PROTOCOL_VERSIONS) * 2 + 1
         self._SINGLE_PROTO_CONNECTION_ATTEMPTS = 3
         self._SINGLE_PROTO_CONNECTION_ATTEMPTS = 3
+        # The number of failures from a working protocol before retrying other protocols.
+        self._AUTO_FAILURE_RESET_COUNT = 10
         self._lock = Lock()
         self._lock = Lock()
 
 
     @property
     @property
@@ -511,6 +514,7 @@ class TuyaLocalDevice(object):
                     if type(retval) is dict and "Error" in retval:
                     if type(retval) is dict and "Error" in retval:
                         raise AttributeError(retval["Error"])
                         raise AttributeError(retval["Error"])
                     self._api_protocol_working = True
                     self._api_protocol_working = True
+                    self._api_working_protocol_failures = 0
                     return retval
                     return retval
             except Exception as e:
             except Exception as e:
                 _LOGGER.debug(
                 _LOGGER.debug(
@@ -523,7 +527,12 @@ class TuyaLocalDevice(object):
 
 
                 if i + 1 == connections:
                 if i + 1 == connections:
                     self._reset_cached_state()
                     self._reset_cached_state()
-                    self._api_protocol_working = False
+                    self._api_working_protocol_failures += 1
+                    if (
+                        self._api_working_protocol_failures
+                        > self._AUTO_FAILURE_RESET_COUNT
+                    ):
+                        self._api_protocol_working = False
                     for entity in self._children:
                     for entity in self._children:
                         entity.async_schedule_update_ha_state()
                         entity.async_schedule_update_ha_state()
                     _LOGGER.error(error_message)
                     _LOGGER.error(error_message)