7 Commits a05726c7c8 ... abd5008b0a

Author SHA1 Message Date
  J. Nick Koston abd5008b0a 0.18.4 4 months ago
  J. Nick Koston 50de33b4f1 Bump bleak-retry-connector to >= 1.4.0 (#68) 4 months ago
  J. Nick Koston 345a0ec48b 0.18.3 4 months ago
  J. Nick Koston 8c0239c3a4 Only lookup the characteristics once (#67) 4 months ago
  J. Nick Koston 96b56489e9 Add parser tests (#66) 4 months ago
  J. Nick Koston bf0abb8956 0.18.2 4 months ago
  David K 4b9a5b2999 Fix for "ValueError: non-hexadecimal number found in fromhex()" raised with some passwords (#65) 4 months ago
3 changed files with 44 additions and 6 deletions
  1. 2 2
      setup.py
  2. 6 4
      switchbot/devices/device.py
  3. 36 0
      tests/test_adv_parser.py

+ 2 - 2
setup.py

@@ -3,8 +3,8 @@ from setuptools import setup
 setup(
     name="PySwitchbot",
     packages=["switchbot", "switchbot.devices", "switchbot.adv_parsers"],
-    install_requires=["async_timeout>=4.0.1", "bleak", "bleak-retry-connector>=1.2.0"],
-    version="0.18.1",
+    install_requires=["async_timeout>=4.0.1", "bleak", "bleak-retry-connector>=1.4.0"],
+    version="0.18.4",
     description="A library to communicate with Switchbot",
     author="Daniel Hjelseth Hoyer",
     url="https://github.com/Danielhiversen/pySwitchbot/",

+ 6 - 4
switchbot/devices/device.py

@@ -58,7 +58,7 @@ class SwitchbotDevice:
         if password is None or password == "":
             self._password_encoded = None
         else:
-            self._password_encoded = "%x" % (
+            self._password_encoded = "%08x" % (
                 binascii.crc32(password.encode("ascii")) & 0xFFFFFFFF
             )
 
@@ -107,6 +107,8 @@ class SwitchbotDevice:
             _LOGGER.debug(
                 "%s: Connnected to switchbot: %s", self.name, client.is_connected
             )
+            read_char = client.services.get_characteristic(_sb_uuid(comms_type="rx"))
+            write_char = client.services.get_characteristic(_sb_uuid(comms_type="tx"))
             future: asyncio.Future[bytearray] = asyncio.Future()
 
             def _notification_handler(_sender: int, data: bytearray) -> None:
@@ -117,17 +119,17 @@ class SwitchbotDevice:
                 future.set_result(data)
 
             _LOGGER.debug("%s: Subscribe to notifications", self.name)
-            await client.start_notify(_sb_uuid(comms_type="rx"), _notification_handler)
+            await client.start_notify(read_char, _notification_handler)
 
             _LOGGER.debug("%s: Sending command, %s", self.name, key)
-            await client.write_gatt_char(_sb_uuid(comms_type="tx"), command, False)
+            await client.write_gatt_char(write_char, command, False)
 
             async with async_timeout.timeout(5):
                 notify_msg = await future
             _LOGGER.info("%s: Notification received: %s", self.name, notify_msg)
 
             _LOGGER.debug("%s: UnSubscribe to notifications", self.name)
-            await client.stop_notify(_sb_uuid(comms_type="rx"))
+            await client.stop_notify(read_char)
 
         finally:
             if client:

+ 36 - 0
tests/test_adv_parser.py

@@ -0,0 +1,36 @@
+from switchbot.adv_parser import parse_advertisement_data
+from bleak.backends.scanner import AdvertisementData
+from bleak.backends.device import BLEDevice
+
+from switchbot.models import SwitchBotAdvertisement
+
+
+def test_parse_advertisement_data_curtain():
+    """Test parse_advertisement_data for curtain."""
+    ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
+    adv_data = AdvertisementData(
+        manufacturer_data={2409: b"\xe7\xabF\xac\x8f\x92|\x0f\x00\x11\x04"},
+        service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"c\xc0X\x00\x11\x04"},
+    )
+    result = parse_advertisement_data(ble_device, adv_data)
+    assert result == SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "address": "aa:bb:cc:dd:ee:ff",
+            "rawAdvData": b"c\xc0X\x00\x11\x04",
+            "data": {
+                "calibration": True,
+                "battery": 88,
+                "inMotion": False,
+                "position": 100,
+                "lightLevel": 1,
+                "deviceChain": 1,
+                "rssi": 0,
+            },
+            "isEncrypted": False,
+            "model": "c",
+            "model_friendly_name": "Curtain",
+            "modelName": "WoCurtain",
+        },
+        device=ble_device,
+    )