Browse Source

Timeout when unable to connect to device after 40 seconds. (#40)

* Use timeout on _sendcommand.

* Update __init__.py

* Update __init__.py

* Revert "Update __init__.py"

This reverts commit 2f9934cbb2beb8404aab66943896fed4af9e4a94.

* Revert "Update __init__.py"

This reverts commit 2e99a9482b7417cbc7fe64fcc71656cf28db9625.

* Revert "Use timeout on _sendcommand."

This reverts commit 05304c5125360201220146dc41bf3b979b33370e.

* Update __init__.py

* Revert "Update __init__.py"

This reverts commit a8649cb3ed897c64489662b4c231a6c070ea147e.

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Update __init__.py

* Alternative handling of disc state

* Update __init__.py
RenierM26 2 years ago
parent
commit
23efbec019
1 changed files with 18 additions and 9 deletions
  1. 18 9
      switchbot/__init__.py

+ 18 - 9
switchbot/__init__.py

@@ -268,7 +268,9 @@ class SwitchbotDevice(bluepy.btle.Peripheral):
 
         if retry < 1:  # failsafe
             self._stopHelper()
-            return
+            raise bluepy.btle.BTLEDisconnectError(
+                "Failed to connect to peripheral %s" % self._mac
+            )
 
         if self._helper is None:
             self._startHelper(self._interface)
@@ -277,13 +279,20 @@ class SwitchbotDevice(bluepy.btle.Peripheral):
 
         rsp = self._getResp(["stat", "err"], timeout)
 
-        while rsp.get("state") and rsp["state"][0] in [
+        while rsp and rsp["state"][0] in [
             "tryconn",
             "scan",
-            "disc",
         ]:  # Wait for any operations to finish.
             rsp = self._getResp(["stat", "err"], timeout)
 
+        # If operation in progress, disc is returned.
+        # Bluepy helper can't handle state. Execute stop, wait and retry.
+        if rsp and rsp["state"][0] == "disc":
+            _LOGGER.warning("Bluepy busy, waiting before retry")
+            self._stopHelper()
+            time.sleep(self._scan_timeout)
+            return self._connect(retry - 1, timeout)
+
         if rsp and rsp["rsp"][0] == "err":
             errcode = rsp["code"][0]
             _LOGGER.debug(
@@ -306,16 +315,16 @@ class SwitchbotDevice(bluepy.btle.Peripheral):
                 "Error from bluepy-helper (%s)" % errcode, rsp
             )
 
-        if not rsp or rsp["state"][0] != "conn":
-            _LOGGER.warning("Bluehelper returned unable to connect state: %s", rsp)
+        if rsp is None or rsp["state"][0] != "conn":
             self._stopHelper()
 
             if rsp is None:
-                raise bluepy.btle.BTLEDisconnectError(
-                    "Timed out while trying to connect to peripheral %s" % self._mac,
-                    rsp,
+                _LOGGER.warning(
+                    "Timed out while trying to connect to peripheral %s", self._mac
                 )
 
+            _LOGGER.warning("Bluehelper returned unable to connect state: %s", rsp)
+
             raise bluepy.btle.BTLEDisconnectError(
                 "Failed to connect to peripheral %s, rsp: %s" % (self._mac, rsp)
             )
@@ -383,7 +392,7 @@ class SwitchbotDevice(bluepy.btle.Peripheral):
 
         return b"\x00"
 
-    def _sendcommand(self, key: str, retry: int, timeout: int | None = None) -> bytes:
+    def _sendcommand(self, key: str, retry: int, timeout: int | None = 40) -> bytes:
         command = self._commandkey(key)
         send_success = False
         notify_msg = None