Skip to content

Commit 8a98883

Browse files
zerzhangpre-commit-ci[bot]bdraco
authored
Add support for S20 Vacuum (#411)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston <[email protected]>
1 parent 187cdc2 commit 8a98883

File tree

6 files changed

+61
-2
lines changed

6 files changed

+61
-2
lines changed

switchbot/adv_parser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ class SwitchbotSupportedType(TypedDict):
384384
"func": process_smart_thermostat_radiator,
385385
"manufacturer_id": 2409,
386386
},
387+
b"\x00\x10\xe0P": {
388+
"modelName": SwitchbotModel.S20_VACUUM,
389+
"modelFriendlyName": "S20 Vacuum",
390+
"func": process_vacuum,
391+
"manufacturer_id": 2409,
392+
},
387393
}
388394

389395
_SWITCHBOT_MODEL_TO_CHAR = {

switchbot/adv_parsers/vacuum.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
from __future__ import annotations
44

5+
import logging
56
import struct
67

8+
_LOGGER = logging.getLogger(__name__)
9+
710

811
def process_vacuum(
912
data: bytes | None, mfr_data: bytes | None
@@ -20,7 +23,7 @@ def process_vacuum(
2023
_battery = mfr_data[12]
2124
_work_status = mfr_data[13] & 0b00111111
2225

23-
return {
26+
result = {
2427
"sequence_number": _seq_num,
2528
"soc_version": _soc_version,
2629
"step": _step,
@@ -29,6 +32,10 @@ def process_vacuum(
2932
"work_status": _work_status,
3033
}
3134

35+
_LOGGER.debug("Processed Vacuum data: %s, result: %s", data, result)
36+
37+
return result
38+
3239

3340
def get_device_fw_version(version_bytes: bytes) -> str | None:
3441
version1 = version_bytes[0] & 0x0F
@@ -51,11 +58,15 @@ def process_vacuum_k(
5158
_work_status = (mfr_data[7] & 0b00010000) >> 4
5259
_battery = mfr_data[8] & 0b01111111
5360

54-
return {
61+
result = {
5562
"sequence_number": _seq_num,
5663
"dustbin_bound": _dustbin_bound,
5764
"dusbin_connected": _dusbin_connected,
5865
"network_connected": _network_connected,
5966
"work_status": _work_status,
6067
"battery": _battery,
6168
}
69+
70+
_LOGGER.debug("Processed Vacuum K data: %s, result: %s", data, result)
71+
72+
return result

switchbot/const/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class SwitchbotModel(StrEnum):
100100
K11_VACUUM = "K11+ Vacuum"
101101
CLIMATE_PANEL = "Climate Panel"
102102
SMART_THERMOSTAT_RADIATOR = "Smart Thermostat Radiator"
103+
S20_VACUUM = "S20 Vacuum"
103104

104105

105106
__all__ = [

switchbot/devices/device.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def _extract_region(userinfo: dict[str, Any]) -> str:
7373
"W1083002": SwitchbotModel.RELAY_SWITCH_1, # Relay Switch 1
7474
"W1079000": SwitchbotModel.METER_PRO, # Meter Pro (another variant)
7575
"W1102001": SwitchbotModel.STRIP_LIGHT_3, # RGBWW Strip Light 3
76+
"W1106000": SwitchbotModel.S20_VACUUM,
7677
}
7778

7879
REQ_HEADER = "570f"

tests/test_adv_parser.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3486,6 +3486,21 @@ def test_humidifer_with_empty_data() -> None:
34863486
"Smart Thermostat Radiator",
34873487
SwitchbotModel.SMART_THERMOSTAT_RADIATOR,
34883488
),
3489+
AdvTestCase(
3490+
b"\xb0\xe9\xfe\xc3\x1a!:\x01\x11\x1e\x00\x00d\x03",
3491+
b"\x00\x00d\x00\x10\xe0P",
3492+
{
3493+
"battery": 100,
3494+
"mqtt_connected": False,
3495+
"sequence_number": 58,
3496+
"soc_version": "1.1.030",
3497+
"step": 0,
3498+
"work_status": 3,
3499+
},
3500+
b"\x00\x10\xe0P",
3501+
"S20 Vacuum",
3502+
SwitchbotModel.S20_VACUUM,
3503+
),
34893504
],
34903505
)
34913506
def test_adv_active(test_case: AdvTestCase) -> None:
@@ -3738,6 +3753,21 @@ def test_adv_active(test_case: AdvTestCase) -> None:
37383753
"Smart Thermostat Radiator",
37393754
SwitchbotModel.SMART_THERMOSTAT_RADIATOR,
37403755
),
3756+
AdvTestCase(
3757+
b"\xb0\xe9\xfe\xc3\x1a!:\x01\x11\x1e\x00\x00d\x03",
3758+
None,
3759+
{
3760+
"battery": 100,
3761+
"mqtt_connected": False,
3762+
"sequence_number": 58,
3763+
"soc_version": "1.1.030",
3764+
"step": 0,
3765+
"work_status": 3,
3766+
},
3767+
b"\x00\x10\xe0P",
3768+
"S20 Vacuum",
3769+
SwitchbotModel.S20_VACUUM,
3770+
),
37413771
],
37423772
)
37433773
def test_adv_passive(test_case: AdvTestCase) -> None:
@@ -3919,6 +3949,14 @@ def test_adv_passive(test_case: AdvTestCase) -> None:
39193949
"Smart Thermostat Radiator",
39203950
SwitchbotModel.SMART_THERMOSTAT_RADIATOR,
39213951
),
3952+
AdvTestCase(
3953+
None,
3954+
b"\x00\x00d\x00\x10\xe0P",
3955+
{},
3956+
b"\x00\x10\xe0P",
3957+
"S20 Vacuum",
3958+
SwitchbotModel.S20_VACUUM,
3959+
),
39223960
],
39233961
)
39243962
def test_adv_with_empty_data(test_case: AdvTestCase) -> None:

tests/test_vacuum.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
(b"(\x00", "(", 1),
1717
(b"}\x00", "(", 1),
1818
(b"\x00\x00M\x00\x10\xfb\xa8", b"\x00\x10\xfb\xa8", 2),
19+
(b"\x00\x00d\x00\x10\xe0P", b"\x00\x10\xe0P", 2),
1920
]
2021

2122

@@ -88,6 +89,7 @@ def make_advertisement_data(
8889
(b"z\x00\x00", "z"),
8990
(b"3\x00\x00", "3"),
9091
(b"\x00\x00M\x00\x10\xfb\xa8", b"\x00\x10\xfb\xa8"),
92+
(b"\x00\x00d\x00\x10\xe0P", b"\x00\x10\xe0P"),
9193
],
9294
)
9395
async def test_status_from_proceess_adv(rawAdvData: bytes, model: str) -> None:

0 commit comments

Comments
 (0)