Skip to content

Commit

Permalink
Add support for WoTHPc (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Oct 22, 2024
1 parent e7ad3c8 commit c385099
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
8 changes: 7 additions & 1 deletion switchbot/adv_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .adv_parsers.humidifier import process_wohumidifier
from .adv_parsers.light_strip import process_wostrip
from .adv_parsers.lock import process_wolock, process_wolock_pro
from .adv_parsers.meter import process_wosensorth
from .adv_parsers.meter import process_wosensorth, process_wosensorth_c
from .adv_parsers.motion import process_wopresence
from .adv_parsers.plug import process_woplugmini
from .const import SwitchbotModel
Expand Down Expand Up @@ -107,6 +107,12 @@ class SwitchbotSupportedType(TypedDict):
"func": process_wosensorth,
"manufacturer_id": 2409,
},
"5": {
"modelName": SwitchbotModel.METER_PRO_C,
"modelFriendlyName": "Meter",
"func": process_wosensorth_c,
"manufacturer_id": 2409,
},
"v": {
"modelName": SwitchbotModel.HUB2,
"modelFriendlyName": "Hub 2",
Expand Down
39 changes: 39 additions & 0 deletions switchbot/adv_parsers/meter.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,42 @@ def process_wosensorth(data: bytes | None, mfr_data: bytes | None) -> dict[str,
}

return _wosensorth_data


def process_wosensorth_c(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]:
"""Process woSensorTH/Temp sensor services data with CO2."""
temp_data = None
battery = None

if mfr_data:
temp_data = mfr_data[8:11]

if data:
if not temp_data:
temp_data = data[3:6]
battery = data[2] & 0b01111111

if not temp_data:
return {}

_temp_sign = 1 if temp_data[1] & 0b10000000 else -1
_temp_c = _temp_sign * (
(temp_data[1] & 0b01111111) + ((temp_data[0] & 0b00001111) / 10)
)
_temp_f = (_temp_c * 9 / 5) + 32
_temp_f = (_temp_f * 10) / 10
humidity = temp_data[2] & 0b01111111

if _temp_c == 0 and humidity == 0 and battery == 0:
return {}

_wosensorth_data = {
# Data should be flat, but we keep the original structure for now
"temp": {"c": _temp_c, "f": _temp_f},
"temperature": _temp_c,
"fahrenheit": bool(temp_data[2] & 0b10000000),
"humidity": humidity,
"battery": battery,
}

return _wosensorth_data
3 changes: 2 additions & 1 deletion switchbot/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class SwitchbotModel(StrEnum):
CONTACT_SENSOR = "WoContact"
LIGHT_STRIP = "WoStrip"
METER = "WoSensorTH"
METER_PRO = "WoSensorTHP"
METER_PRO = "WoTHP"
METER_PRO_C = "WoTHPc"
IO_METER = "WoIOSensorTH"
MOTION_SENSOR = "WoPresence"
COLOR_BULB = "WoBulb"
Expand Down
66 changes: 66 additions & 0 deletions tests/test_adv_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,9 @@ def test_meter_pro_passive() -> None:
rssi=-67,
)
result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.METER_PRO)
import pprint

pprint.pprint(result)
assert result == SwitchBotAdvertisement(
address="aa:bb:cc:dd:ee:ff",
data={
Expand All @@ -1619,3 +1622,66 @@ def test_meter_pro_passive() -> None:
rssi=-67,
active=False,
)


def test_meter_pro_c_active() -> None:
ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
adv_data = generate_advertisement_data(
manufacturer_data={
2409: b"\xb0\xe9\xfeT2\x15\xb7\xe4\x07\x9b\xa4\x007\x02\xd5\x00"
},
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"5\x00d"},
rssi=-67,
)
result = parse_advertisement_data(ble_device, adv_data)
assert result == SwitchBotAdvertisement(
address="aa:bb:cc:dd:ee:ff",
data={
"data": {
"battery": 100,
"fahrenheit": True,
"humidity": 36,
"temp": {"c": 27.7, "f": 81.86},
"temperature": 27.7,
},
"isEncrypted": False,
"model": "5",
"modelFriendlyName": "Meter",
"modelName": SwitchbotModel.METER_PRO_C,
"rawAdvData": b"5\x00d",
},
device=ble_device,
rssi=-67,
active=True,
)


def test_meter_pro_c_passive() -> None:
ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
adv_data = generate_advertisement_data(
manufacturer_data={
2409: b"\xb0\xe9\xfeT2\x15\xb7\xe4\x07\x9b\xa4\x007\x02\xd5\x00"
},
rssi=-67,
)
result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.METER_PRO_C)
assert result == SwitchBotAdvertisement(
address="aa:bb:cc:dd:ee:ff",
data={
"data": {
"battery": None,
"fahrenheit": True,
"humidity": 36,
"temp": {"c": 27.7, "f": 81.86},
"temperature": 27.7,
},
"isEncrypted": False,
"model": "5",
"modelFriendlyName": "Meter",
"modelName": SwitchbotModel.METER_PRO_C,
"rawAdvData": None,
},
device=ble_device,
rssi=-67,
active=False,
)

0 comments on commit c385099

Please sign in to comment.