Skip to content

Commit 7e388cb

Browse files
authored
Fixes for curtain firmware 6 (#139)
1 parent 87a626e commit 7e388cb

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

switchbot/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Library to handle connection with Switchbot."""
22
from __future__ import annotations
33

4-
from bleak_retry_connector import get_device, close_stale_connections
4+
from bleak_retry_connector import close_stale_connections, get_device
55

66
from .adv_parser import SwitchbotSupportedType, parse_advertisement_data
77
from .const import SwitchbotModel

switchbot/adv_parser.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424

2525
_LOGGER = logging.getLogger(__name__)
2626

27+
SERVICE_DATA_ORDER = (
28+
"0000fd3d-0000-1000-8000-00805f9b34fb",
29+
"00000d00-0000-1000-8000-00805f9b34fb",
30+
)
31+
2732

2833
class SwitchbotSupportedType(TypedDict):
2934
"""Supported type of Switchbot."""
@@ -101,9 +106,17 @@ def parse_advertisement_data(
101106

102107
if not _services:
103108
return None
104-
_service_data = _services[0]
109+
110+
_service_data = None
111+
for uuid in SERVICE_DATA_ORDER:
112+
if uuid in _services:
113+
_service_data = _services[uuid]
114+
break
115+
if not _service_data:
116+
_service_data = _services[0]
105117
if not _service_data:
106118
return None
119+
107120
_mfr_data = _mgr_datas[0] if _mgr_datas else None
108121

109122
data = _parse_data(_service_data, _mfr_data)

tests/test_adv_parser.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,80 @@ def test_parse_advertisement_data_curtain_firmware_six_position_100_other_rssi()
180180
)
181181

182182

183+
def test_parse_advertisement_data_curtain_fully_closed():
184+
"""Test parse_advertisement_data with firmware six fully closed."""
185+
ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
186+
adv_data = generate_advertisement_data(
187+
local_name="WoCurtain",
188+
manufacturer_data={2409: b"\xc1\xc7'}U\xab\"\x0fd\x11\x04"},
189+
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"c\xc0Sd\x11\x04"},
190+
service_uuids=[
191+
"00001800-0000-1000-8000-00805f9b34fb",
192+
"00001801-0000-1000-8000-00805f9b34fb",
193+
"cba20d00-224d-11e6-9fb8-0002a5d5c51b",
194+
],
195+
rssi=1,
196+
)
197+
result = parse_advertisement_data(ble_device, adv_data)
198+
assert result == SwitchBotAdvertisement(
199+
address="aa:bb:cc:dd:ee:ff",
200+
data={
201+
"rawAdvData": b"c\xc0Sd\x11\x04",
202+
"data": {
203+
"calibration": True,
204+
"battery": 83,
205+
"inMotion": False,
206+
"position": 0,
207+
"lightLevel": 1,
208+
"deviceChain": 1,
209+
},
210+
"isEncrypted": False,
211+
"model": "c",
212+
"modelFriendlyName": "Curtain",
213+
"modelName": SwitchbotModel.CURTAIN,
214+
},
215+
device=ble_device,
216+
rssi=1,
217+
)
218+
219+
220+
def test_parse_advertisement_data_curtain_fully_open():
221+
"""Test parse_advertisement_data with firmware six fully open."""
222+
ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")
223+
adv_data = generate_advertisement_data(
224+
local_name="WoCurtain",
225+
manufacturer_data={2409: b"\xc1\xc7'}U\xab%\x0f\x00\x11\x04"},
226+
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"c\xc0S\x00\x11\x04"},
227+
service_uuids=[
228+
"00001800-0000-1000-8000-00805f9b34fb",
229+
"00001801-0000-1000-8000-00805f9b34fb",
230+
"cba20d00-224d-11e6-9fb8-0002a5d5c51b",
231+
],
232+
rssi=1,
233+
)
234+
result = parse_advertisement_data(ble_device, adv_data)
235+
assert result == SwitchBotAdvertisement(
236+
address="aa:bb:cc:dd:ee:ff",
237+
data={
238+
"rawAdvData": b"c\xc0S\x00\x11\x04",
239+
"data": {
240+
"calibration": True,
241+
"battery": 83,
242+
"inMotion": False,
243+
"position": 100,
244+
"lightLevel": 1,
245+
"deviceChain": 1,
246+
},
247+
"isEncrypted": False,
248+
"model": "c",
249+
"modelFriendlyName": "Curtain",
250+
"modelName": SwitchbotModel.CURTAIN,
251+
},
252+
device=ble_device,
253+
rssi=1,
254+
)
255+
256+
183257
def test_parse_advertisement_data_contact():
184258
"""Test parse_advertisement_data for the contact sensor."""
185259
ble_device = BLEDevice("aa:bb:cc:dd:ee:ff", "any")

0 commit comments

Comments
 (0)