Browse Source

Fix issue with SB password issue and Temp issue. (#28)

* Fix issue with SB password issue and Temp issue.

-Revert master branch to V0.11.0 release. (Latest master runs scanner in separate thread, this causes memory leak on hassio leading to supervisor restarts every 2nd day.)
-Add WoSensorTH key fix.

* and model value as 1st bit indicates encryption.

* Update __init__.py

* Update __init__.py

* Update __init__.py
RenierM26 2 years ago
parent
commit
3175309f58
2 changed files with 17 additions and 46 deletions
  1. 1 0
      .gitignore
  2. 16 46
      switchbot/__init__.py

+ 1 - 0
.gitignore

@@ -105,3 +105,4 @@ venv.bak/
 switchbot/.vs/slnx.sqlite
 switchbot/.vs/switchbot/v16/.suo
 switchbot/.vs/VSWorkspaceState.json
+switchbot/.vs/ProjectSettings.json

+ 16 - 46
switchbot/__init__.py

@@ -3,7 +3,7 @@ from __future__ import annotations
 
 import binascii
 import logging
-from multiprocessing import Manager, Process
+import threading
 import time
 
 import bluepy
@@ -31,6 +31,7 @@ OFF_KEY_SUFFIX = "02"
 PRESS_KEY_SUFFIX = "00"
 
 _LOGGER = logging.getLogger(__name__)
+CONNECT_LOCK = threading.Lock()
 
 
 def _process_wohand(data) -> dict:
@@ -93,34 +94,6 @@ def _process_wosensorth(data) -> dict:
     return _wosensorth_data
 
 
-class BLEScanner:
-    """Helper for bluepy device scanning."""
-
-    def __init__(self, scan_timeout=DEFAULT_SCAN_TIMEOUT, interface=None) -> None:
-        """Init class constructor."""
-        self._scan_timeout = scan_timeout
-        self._interface = interface
-        self._devices = None
-
-    def start(self) -> dict | None:
-        """Start scan in seperate process."""
-        with Manager() as manager:
-            _devices = manager.dict()
-            process = Process(target=self._scan, args=(_devices,))
-            process.start()
-            process.join()
-
-            return _devices.get(0, None)
-
-    def _scan(self, devices) -> dict | None:
-        """Scan for advertisement data."""
-        try:
-            devices[0] = bluepy.btle.Scanner(self._interface).scan(self._scan_timeout)
-
-        except bluepy.btle.BTLEDisconnectError:
-            pass
-
-
 class GetSwitchbotDevices:
     """Scan for all Switchbot devices and return by type."""
 
@@ -137,9 +110,7 @@ class GetSwitchbotDevices:
         devices = None
 
         try:
-            devices = BLEScanner(
-                scan_timeout=scan_timeout, interface=self._interface
-            ).start()
+            devices = bluepy.btle.Scanner(self._interface).scan(scan_timeout)
 
         except bluepy.btle.BTLEManagementError:
             _LOGGER.error("Error scanning for switchbot devices", exc_info=True)
@@ -165,7 +136,7 @@ class GetSwitchbotDevices:
                 self._all_services_data[dev_id]["mac_address"] = dev.addr
                 for (adtype, desc, value) in dev.getScanData():
                     if adtype == 22:
-                        _model = binascii.unhexlify(value[4:6]).decode()
+                        _model = chr(binascii.unhexlify(value.encode())[2] & 0b01111111)
                         if _model == "H":
                             self._all_services_data[dev_id]["data"] = _process_wohand(
                                 value[4:]
@@ -229,7 +200,7 @@ class GetSwitchbotDevices:
         _switchbot_data = {}
 
         for item in self._all_services_data:
-            if self._all_services_data[item]["mac_address"] == mac.replace("-", ":").lower():
+            if self._all_services_data[item]["mac_address"] == mac:
                 _switchbot_data = self._all_services_data[item]
 
         return _switchbot_data
@@ -241,7 +212,7 @@ class SwitchbotDevice:
     def __init__(self, mac, password=None, interface=None, **kwargs) -> None:
         """Switchbot base class constructor."""
         self._interface = interface
-        self._mac = mac.replace("-", ":").lower()
+        self._mac = mac
         self._device = None
         self._switchbot_device_data = {}
         self._scan_timeout = kwargs.pop("scan_timeout", DEFAULT_SCAN_TIMEOUT)
@@ -307,13 +278,14 @@ class SwitchbotDevice:
         send_success = False
         command = self._commandkey(key)
         _LOGGER.debug("Sending command to switchbot %s", command)
-        try:
-            self._connect()
-            send_success = self._writekey(command)
-        except bluepy.btle.BTLEException:
-            _LOGGER.warning("Error talking to Switchbot", exc_info=True)
-        finally:
-            self._disconnect()
+        with CONNECT_LOCK:
+            try:
+                self._connect()
+                send_success = self._writekey(command)
+            except bluepy.btle.BTLEException:
+                _LOGGER.warning("Error talking to Switchbot", exc_info=True)
+            finally:
+                self._disconnect()
         if send_success:
             return True
         if retry < 1:
@@ -345,9 +317,7 @@ class SwitchbotDevice:
         devices = None
 
         try:
-            devices = BLEScanner(
-                scan_timeout=self._scan_timeout, interface=_interface
-            ).start()
+            devices = bluepy.btle.Scanner(_interface).scan(self._scan_timeout)
 
         except bluepy.btle.BTLEManagementError:
             _LOGGER.error("Error scanning for switchbot devices", exc_info=True)
@@ -371,7 +341,7 @@ class SwitchbotDevice:
                 self._switchbot_device_data["mac_address"] = dev.addr
                 for (adtype, desc, value) in dev.getScanData():
                     if adtype == 22:
-                        _model = binascii.unhexlify(value[4:6]).decode()
+                        _model = chr(binascii.unhexlify(value.encode())[2] & 0b01111111)
                         if _model == "H":
                             self._switchbot_device_data["data"] = _process_wohand(
                                 value[4:]