PySwitchbot 0.49.0__tar.gz → 0.50.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/PKG-INFO +1 -1
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/PySwitchbot.egg-info/PKG-INFO +1 -1
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/setup.py +1 -1
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parser.py +7 -1
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/meter.py +39 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/const.py +2 -1
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/tests/test_adv_parser.py +63 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/LICENSE +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/MANIFEST.in +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/PySwitchbot.egg-info/SOURCES.txt +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/PySwitchbot.egg-info/dependency_links.txt +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/PySwitchbot.egg-info/requires.txt +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/PySwitchbot.egg-info/top_level.txt +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/README.md +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/setup.cfg +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/__init__.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/__init__.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/blind_tilt.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/bot.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/bulb.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/ceiling_light.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/contact.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/curtain.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/hub2.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/humidifier.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/light_strip.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/lock.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/motion.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/adv_parsers/plug.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/api_config.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/__init__.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/base_cover.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/base_light.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/blind_tilt.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/bot.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/bulb.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/ceiling_light.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/contact.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/curtain.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/device.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/humidifier.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/light_strip.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/lock.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/meter.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/motion.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/devices/plug.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/discovery.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/enum.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/switchbot/models.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/tests/test_base_cover.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/tests/test_blind_tilt.py +0 -0
- {pyswitchbot-0.49.0 → pyswitchbot-0.50.1}/tests/test_curtain.py +0 -0
|
@@ -20,7 +20,7 @@ from .adv_parsers.hub2 import process_wohub2
|
|
|
20
20
|
from .adv_parsers.humidifier import process_wohumidifier
|
|
21
21
|
from .adv_parsers.light_strip import process_wostrip
|
|
22
22
|
from .adv_parsers.lock import process_wolock, process_wolock_pro
|
|
23
|
-
from .adv_parsers.meter import process_wosensorth
|
|
23
|
+
from .adv_parsers.meter import process_wosensorth, process_wosensorth_c
|
|
24
24
|
from .adv_parsers.motion import process_wopresence
|
|
25
25
|
from .adv_parsers.plug import process_woplugmini
|
|
26
26
|
from .const import SwitchbotModel
|
|
@@ -107,6 +107,12 @@ SUPPORTED_TYPES: dict[str, SwitchbotSupportedType] = {
|
|
|
107
107
|
"func": process_wosensorth,
|
|
108
108
|
"manufacturer_id": 2409,
|
|
109
109
|
},
|
|
110
|
+
"5": {
|
|
111
|
+
"modelName": SwitchbotModel.METER_PRO_C,
|
|
112
|
+
"modelFriendlyName": "Meter",
|
|
113
|
+
"func": process_wosensorth_c,
|
|
114
|
+
"manufacturer_id": 2409,
|
|
115
|
+
},
|
|
110
116
|
"v": {
|
|
111
117
|
"modelName": SwitchbotModel.HUB2,
|
|
112
118
|
"modelFriendlyName": "Hub 2",
|
|
@@ -41,3 +41,42 @@ def process_wosensorth(data: bytes | None, mfr_data: bytes | None) -> dict[str,
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
return _wosensorth_data
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def process_wosensorth_c(data: bytes | None, mfr_data: bytes | None) -> dict[str, Any]:
|
|
47
|
+
"""Process woSensorTH/Temp sensor services data with CO2."""
|
|
48
|
+
temp_data = None
|
|
49
|
+
battery = None
|
|
50
|
+
|
|
51
|
+
if mfr_data:
|
|
52
|
+
temp_data = mfr_data[8:11]
|
|
53
|
+
|
|
54
|
+
if data:
|
|
55
|
+
if not temp_data:
|
|
56
|
+
temp_data = data[3:6]
|
|
57
|
+
battery = data[2] & 0b01111111
|
|
58
|
+
|
|
59
|
+
if not temp_data:
|
|
60
|
+
return {}
|
|
61
|
+
|
|
62
|
+
_temp_sign = 1 if temp_data[1] & 0b10000000 else -1
|
|
63
|
+
_temp_c = _temp_sign * (
|
|
64
|
+
(temp_data[1] & 0b01111111) + ((temp_data[0] & 0b00001111) / 10)
|
|
65
|
+
)
|
|
66
|
+
_temp_f = (_temp_c * 9 / 5) + 32
|
|
67
|
+
_temp_f = (_temp_f * 10) / 10
|
|
68
|
+
humidity = temp_data[2] & 0b01111111
|
|
69
|
+
|
|
70
|
+
if _temp_c == 0 and humidity == 0 and battery == 0:
|
|
71
|
+
return {}
|
|
72
|
+
|
|
73
|
+
_wosensorth_data = {
|
|
74
|
+
# Data should be flat, but we keep the original structure for now
|
|
75
|
+
"temp": {"c": _temp_c, "f": _temp_f},
|
|
76
|
+
"temperature": _temp_c,
|
|
77
|
+
"fahrenheit": bool(temp_data[2] & 0b10000000),
|
|
78
|
+
"humidity": humidity,
|
|
79
|
+
"battery": battery,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return _wosensorth_data
|
|
@@ -42,7 +42,8 @@ class SwitchbotModel(StrEnum):
|
|
|
42
42
|
CONTACT_SENSOR = "WoContact"
|
|
43
43
|
LIGHT_STRIP = "WoStrip"
|
|
44
44
|
METER = "WoSensorTH"
|
|
45
|
-
METER_PRO = "
|
|
45
|
+
METER_PRO = "WoTHP"
|
|
46
|
+
METER_PRO_C = "WoTHPc"
|
|
46
47
|
IO_METER = "WoIOSensorTH"
|
|
47
48
|
MOTION_SENSOR = "WoPresence"
|
|
48
49
|
COLOR_BULB = "WoBulb"
|
|
@@ -1619,3 +1619,66 @@ def test_meter_pro_passive() -> None:
|
|
|
1619
1619
|
rssi=-67,
|
|
1620
1620
|
active=False,
|
|
1621
1621
|
)
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
def test_meter_pro_c_active() -> None:
|
|
1625
|
+
ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
|
|
1626
|
+
adv_data = generate_advertisement_data(
|
|
1627
|
+
manufacturer_data={
|
|
1628
|
+
2409: b"\xb0\xe9\xfeT2\x15\xb7\xe4\x07\x9b\xa4\x007\x02\xd5\x00"
|
|
1629
|
+
},
|
|
1630
|
+
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"5\x00d"},
|
|
1631
|
+
rssi=-67,
|
|
1632
|
+
)
|
|
1633
|
+
result = parse_advertisement_data(ble_device, adv_data)
|
|
1634
|
+
assert result == SwitchBotAdvertisement(
|
|
1635
|
+
address="aa:bb:cc:dd:ee:ff",
|
|
1636
|
+
data={
|
|
1637
|
+
"data": {
|
|
1638
|
+
"battery": 100,
|
|
1639
|
+
"fahrenheit": True,
|
|
1640
|
+
"humidity": 36,
|
|
1641
|
+
"temp": {"c": 27.7, "f": 81.86},
|
|
1642
|
+
"temperature": 27.7,
|
|
1643
|
+
},
|
|
1644
|
+
"isEncrypted": False,
|
|
1645
|
+
"model": "5",
|
|
1646
|
+
"modelFriendlyName": "Meter",
|
|
1647
|
+
"modelName": SwitchbotModel.METER_PRO_C,
|
|
1648
|
+
"rawAdvData": b"5\x00d",
|
|
1649
|
+
},
|
|
1650
|
+
device=ble_device,
|
|
1651
|
+
rssi=-67,
|
|
1652
|
+
active=True,
|
|
1653
|
+
)
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
def test_meter_pro_c_passive() -> None:
|
|
1657
|
+
ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
|
|
1658
|
+
adv_data = generate_advertisement_data(
|
|
1659
|
+
manufacturer_data={
|
|
1660
|
+
2409: b"\xb0\xe9\xfeT2\x15\xb7\xe4\x07\x9b\xa4\x007\x02\xd5\x00"
|
|
1661
|
+
},
|
|
1662
|
+
rssi=-67,
|
|
1663
|
+
)
|
|
1664
|
+
result = parse_advertisement_data(ble_device, adv_data, SwitchbotModel.METER_PRO_C)
|
|
1665
|
+
assert result == SwitchBotAdvertisement(
|
|
1666
|
+
address="aa:bb:cc:dd:ee:ff",
|
|
1667
|
+
data={
|
|
1668
|
+
"data": {
|
|
1669
|
+
"battery": None,
|
|
1670
|
+
"fahrenheit": True,
|
|
1671
|
+
"humidity": 36,
|
|
1672
|
+
"temp": {"c": 27.7, "f": 81.86},
|
|
1673
|
+
"temperature": 27.7,
|
|
1674
|
+
},
|
|
1675
|
+
"isEncrypted": False,
|
|
1676
|
+
"model": "5",
|
|
1677
|
+
"modelFriendlyName": "Meter",
|
|
1678
|
+
"modelName": SwitchbotModel.METER_PRO_C,
|
|
1679
|
+
"rawAdvData": None,
|
|
1680
|
+
},
|
|
1681
|
+
device=ble_device,
|
|
1682
|
+
rssi=-67,
|
|
1683
|
+
active=False,
|
|
1684
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|