Browse Source

Fix compatibilty for old/US firmware (#217)

Co-authored-by: J. Nick Koston <nick@koston.org>
Michal Jál 8 months ago
parent
commit
e8adfd9cb1
3 changed files with 73 additions and 3 deletions
  1. 1 1
      switchbot/adv_parsers/lock.py
  2. 3 2
      switchbot/devices/lock.py
  3. 69 0
      tests/test_adv_parser.py

+ 1 - 1
switchbot/adv_parsers/lock.py

@@ -27,5 +27,5 @@ def process_wolock(data: bytes | None, mfr_data: bytes | None) -> dict[str, bool
         "unclosed_alarm": bool(mfr_data[8] & 0b00100000),
         "unlocked_alarm": bool(mfr_data[8] & 0b00010000),
         "auto_lock_paused": bool(mfr_data[8] & 0b00000010),
-        "night_latch": bool(mfr_data[9] & 0b00000001),
+        "night_latch": bool(mfr_data[9] & 0b00000001) if len(mfr_data) > 9 else False,
     }

+ 3 - 2
switchbot/devices/lock.py

@@ -173,7 +173,8 @@ class SwitchbotLock(SwitchbotDevice):
     async def unlock_without_unlatch(self) -> bool:
         """Send unlock command. This command will not unlatch the door."""
         return await self._lock_unlock(
-            COMMAND_UNLOCK_WITHOUT_UNLATCH, {LockStatus.UNLOCKED, LockStatus.UNLOCKING, LockStatus.NOT_FULLY_LOCKED}
+            COMMAND_UNLOCK_WITHOUT_UNLATCH,
+            {LockStatus.UNLOCKED, LockStatus.UNLOCKING, LockStatus.NOT_FULLY_LOCKED},
         )
 
     def _parse_basic_data(self, basic_data: bytes) -> dict[str, Any]:
@@ -249,7 +250,7 @@ class SwitchbotLock(SwitchbotDevice):
     def is_night_latch_enabled(self) -> bool:
         """Return True if Night Latch is enabled on EU firmware."""
         return self._get_adv_value("night_latch")
-        
+
     async def _get_lock_info(self) -> bytes | None:
         """Return lock info of device."""
         _data = await self._send_command(key=COMMAND_LOCK_INFO, retry=self._retry_count)

+ 69 - 0
tests/test_adv_parser.py

@@ -1284,3 +1284,72 @@ def test_parsing_lock_passive():
         rssi=-67,
         active=False,
     )
+
+def test_parsing_lock_active_old_firmware():
+    """Test parsing lock with active data. Old firmware."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    adv_data = generate_advertisement_data(
+        manufacturer_data={2409: b"\xf1\t\x9fE\x1a]\x07\x83\x00"},
+        service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"o\x80d"},
+        rssi=-67,
+    )
+    result = parse_advertisement_data(ble_device, adv_data)
+    assert result == SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "data": {
+                "auto_lock_paused": False,
+                "battery": 100,
+                "calibration": True,
+                "door_open": False,
+                "double_lock_mode": False,
+                "night_latch": False,
+                "status": LockStatus.LOCKED,
+                "unclosed_alarm": False,
+                "unlocked_alarm": False,
+                "update_from_secondary_lock": False,
+            },
+            "isEncrypted": False,
+            "model": "o",
+            "modelFriendlyName": "Lock",
+            "modelName": SwitchbotModel.LOCK,
+            "rawAdvData": b"o\x80d",
+        },
+        device=ble_device,
+        rssi=-67,
+        active=True,
+    )
+
+
+def test_parsing_lock_passive_old_firmware():
+    """Test parsing lock with active data. Old firmware."""
+    ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
+    adv_data = generate_advertisement_data(
+        manufacturer_data={2409: b"\xf1\t\x9fE\x1a]\x07\x83\x00"}, rssi=-67
+    )
+    result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.LOCK)
+    assert result == SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "data": {
+                "auto_lock_paused": False,
+                "battery": None,
+                "calibration": True,
+                "door_open": False,
+                "double_lock_mode": False,
+                "night_latch": False,
+                "status": LockStatus.LOCKED,
+                "unclosed_alarm": False,
+                "unlocked_alarm": False,
+                "update_from_secondary_lock": False,
+            },
+            "isEncrypted": False,
+            "model": "o",
+            "modelFriendlyName": "Lock",
+            "modelName": SwitchbotModel.LOCK,
+            "rawAdvData": None,
+        },
+        device=ble_device,
+        rssi=-67,
+        active=False,
+    )