Преглед изворни кода

Add passive parsers for light strip and bulb (#154)

J. Nick Koston пре 2 година
родитељ
комит
96ddb65cec
2 измењених фајлова са 111 додато и 2 уклоњено
  1. 6 1
      switchbot/adv_parser.py
  2. 105 1
      tests/test_adv_parser.py

+ 6 - 1
switchbot/adv_parser.py

@@ -64,6 +64,8 @@ SUPPORTED_TYPES: dict[str, SwitchbotSupportedType] = {
         "modelName": SwitchbotModel.LIGHT_STRIP,
         "modelFriendlyName": "Light Strip",
         "func": process_wostrip,
+        "manufacturer_id": 2409,
+        "manufacturer_data_length": 16,
     },
     "c": {
         "modelName": SwitchbotModel.CURTAIN,
@@ -100,6 +102,8 @@ SUPPORTED_TYPES: dict[str, SwitchbotSupportedType] = {
         "modelName": SwitchbotModel.COLOR_BULB,
         "modelFriendlyName": "Color Bulb",
         "func": process_color_bulb,
+        "manufacturer_id": 2409,
+        "manufacturer_data_length": 11,
     },
     "q": {
         "modelName": SwitchbotModel.CEILING_LIGHT,
@@ -194,7 +198,8 @@ def _parse_data(
             if model_data.get("manufacturer_data_length") == len(_mfr_data):
                 _model = model_chr
                 break
-            if model_data.get("service_uuids", set()).intersection(_service_uuids):
+            service_uuids = model_data.get("service_uuids", set())
+            if service_uuids and service_uuids.intersection(_service_uuids):
                 _model = model_chr
                 break
 

+ 105 - 1
tests/test_adv_parser.py

@@ -292,7 +292,7 @@ def test_parse_advertisement_data_empty():
     """Test parse_advertisement_data with empty data does not blow up."""
     ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
     adv_data = generate_advertisement_data(
-        manufacturer_data={2409: b"\xe7\xabF\xac\x8f\x92|\x0f\x00\x11\x04"},
+        manufacturer_data={2403: b"\xe7\xabF\xac\x8f\x92|\x0f\x00\x11\x04"},
         service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b""},
     )
     result = parse_advertisement_data(ble_device, adv_data)
@@ -609,3 +609,107 @@ def test_switchbot_passive():
         device=ble_device,
         rssi=-50,
     )
+
+
+def test_bulb_active():
+    """Test parsing bulb as active."""
+    ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
+    adv_data = generate_advertisement_data(
+        manufacturer_data={2409: b"\x84\xf7\x03\xb4\xcbz\x03\xe4!\x00\x00"},
+        service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"u\x00d"},
+        tx_power=-127,
+        rssi=-50,
+    )
+    result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.BOT)
+    assert result == SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "data": {
+                "brightness": 100,
+                "color_mode": 1,
+                "delay": False,
+                "isOn": True,
+                "loop_index": 0,
+                "preset": False,
+                "sequence_number": 3,
+                "speed": 0,
+            },
+            "isEncrypted": False,
+            "model": "u",
+            "modelFriendlyName": "Color Bulb",
+            "modelName": SwitchbotModel.COLOR_BULB,
+            "rawAdvData": b"u\x00d",
+        },
+        device=ble_device,
+        rssi=-50,
+    )
+
+
+def test_bulb_passive():
+    """Test parsing bulb as passive."""
+    ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
+    adv_data = generate_advertisement_data(
+        manufacturer_data={2409: b"\x84\xf7\x03\xb4\xcbz\x03\xe4!\x00\x00"},
+        service_data={},
+        tx_power=-127,
+        rssi=-50,
+    )
+    result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.BOT)
+    assert result == SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "data": {
+                "brightness": 100,
+                "color_mode": 1,
+                "delay": False,
+                "isOn": True,
+                "loop_index": 0,
+                "preset": False,
+                "sequence_number": 3,
+                "speed": 0,
+            },
+            "isEncrypted": False,
+            "model": "u",
+            "modelFriendlyName": "Color Bulb",
+            "modelName": SwitchbotModel.COLOR_BULB,
+            "rawAdvData": None,
+        },
+        device=ble_device,
+        rssi=-50,
+    )
+
+
+def test_lightstrip_passive():
+    """Test parsing lightstrip as passive."""
+    ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
+    adv_data = generate_advertisement_data(
+        manufacturer_data={
+            2409: b"`U\xf9(\xe5\x96\x00d\x02\xb0\x00\x00\x00\x00\x00\x00"
+        },
+        service_data={},
+        tx_power=-127,
+        rssi=-50,
+    )
+    result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.BOT)
+    assert result == SwitchBotAdvertisement(
+        address="aa:bb:cc:dd:ee:ff",
+        data={
+            "data": {
+                "brightness": 100,
+                "color_mode": 2,
+                "delay": False,
+                "isOn": False,
+                "loop_index": 0,
+                "preset": False,
+                "sequence_number": 0,
+                "speed": 48,
+            },
+            "isEncrypted": False,
+            "model": "r",
+            "modelFriendlyName": "Light Strip",
+            "modelName": SwitchbotModel.LIGHT_STRIP,
+            "rawAdvData": None,
+        },
+        device=ble_device,
+        rssi=-50,
+    )