Skip to content

Commit f1be36b

Browse files
authored
fix: handle new switchbot firmwares (#124)
1 parent d4bd047 commit f1be36b

File tree

6 files changed

+43
-15
lines changed

6 files changed

+43
-15
lines changed

switchbot/adv_parser.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,14 @@ def _parse_data(
125125

126126
type_data = SUPPORTED_TYPES.get(_model)
127127
if type_data:
128-
data.update(
129-
{
130-
"modelFriendlyName": type_data["modelFriendlyName"],
131-
"modelName": type_data["modelName"],
132-
"data": type_data["func"](_service_data, _mfr_data),
133-
}
134-
)
128+
model_data = type_data["func"](_service_data, _mfr_data)
129+
if model_data:
130+
data.update(
131+
{
132+
"modelFriendlyName": type_data["modelFriendlyName"],
133+
"modelName": type_data["modelName"],
134+
"data": model_data,
135+
}
136+
)
135137

136138
return data

switchbot/adv_parsers/bulb.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
def process_color_bulb(data: bytes, mfr_data: bytes | None) -> dict[str, bool | int]:
66
"""Process WoBulb services data."""
7-
assert mfr_data is not None
7+
if mfr_data is None:
8+
return {}
89
return {
910
"sequence_number": mfr_data[6],
1011
"isOn": bool(mfr_data[7] & 0b10000000),

switchbot/adv_parsers/ceiling_light.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
def process_woceiling(data: bytes, mfr_data: bytes | None) -> dict[str, bool | int]:
1616
"""Process WoCeiling services data."""
17-
assert mfr_data is not None
17+
if mfr_data is None:
18+
return {}
1819
return {
1920
"sequence_number": mfr_data[6],
2021
"isOn": bool(mfr_data[10] & 0b10000000),

switchbot/adv_parsers/light_strip.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
def process_wostrip(data: bytes, mfr_data: bytes | None) -> dict[str, bool | int]:
66
"""Process WoStrip services data."""
7-
assert mfr_data is not None
7+
if mfr_data is None:
8+
return {}
89
return {
910
"sequence_number": mfr_data[6],
1011
"isOn": bool(mfr_data[7] & 0b10000000),

switchbot/adv_parsers/plug.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
def process_woplugmini(data: bytes, mfr_data: bytes | None) -> dict[str, bool | int]:
66
"""Process plug mini."""
7-
assert mfr_data is not None
7+
if mfr_data is None:
8+
return {}
89
return {
910
"switchMode": True,
1011
"isOn": mfr_data[7] == 0x80,

tests/test_adv_parser.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from bleak.backends.device import BLEDevice
44

55
from switchbot.models import SwitchBotAdvertisement
6+
from switchbot import SwitchbotModel
67

78

89
def test_parse_advertisement_data_curtain():
@@ -16,7 +17,6 @@ def test_parse_advertisement_data_curtain():
1617
assert result == SwitchBotAdvertisement(
1718
address="aa:bb:cc:dd:ee:ff",
1819
data={
19-
"address": "aa:bb:cc:dd:ee:ff",
2020
"rawAdvData": b"c\xc0X\x00\x11\x04",
2121
"data": {
2222
"calibration": True,
@@ -25,12 +25,11 @@ def test_parse_advertisement_data_curtain():
2525
"position": 100,
2626
"lightLevel": 1,
2727
"deviceChain": 1,
28-
"rssi": 0,
2928
},
3029
"isEncrypted": False,
3130
"model": "c",
3231
"modelFriendlyName": "Curtain",
33-
"modelName": "WoCurtain",
32+
"modelName": SwitchbotModel.CURTAIN,
3433
},
3534
device=ble_device,
3635
)
@@ -44,4 +43,27 @@ def test_parse_advertisement_data_empty():
4443
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b""},
4544
)
4645
result = parse_advertisement_data(ble_device, adv_data)
47-
assert result is None
46+
assert result is None
47+
48+
49+
def test_new_bot_firmware():
50+
"""Test parsing adv data from new bot firmware."""
51+
ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
52+
adv_data = AdvertisementData(
53+
manufacturer_data={89: b"\xd8.\xad\xcd\r\x85"},
54+
service_data={"00000d00-0000-1000-8000-00805f9b34fb": b"H\x10\xe1"},
55+
service_uuids=["CBA20D00-224D-11E6-9FB8-0002A5D5C51B"],
56+
)
57+
result = parse_advertisement_data(ble_device, adv_data)
58+
assert result == SwitchBotAdvertisement(
59+
address="aa:bb:cc:dd:ee:ff",
60+
data={
61+
"rawAdvData": b"H\x10\xe1",
62+
"data": {"switchMode": False, "isOn": False, "battery": 97},
63+
"model": "H",
64+
"isEncrypted": False,
65+
"modelFriendlyName": "Bot",
66+
"modelName": SwitchbotModel.BOT,
67+
},
68+
device=ble_device,
69+
)

0 commit comments

Comments
 (0)