PySwitchbot 3.0.0__tar.gz → 3.1.0__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-3.0.0 → pyswitchbot-3.1.0}/PKG-INFO +14 -1
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/README.md +13 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/pyproject.toml +1 -1
- pyswitchbot-3.1.0/switchbot/__version__.py +1 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/air_purifier.py +27 -0
- pyswitchbot-3.0.0/switchbot/__version__.py +0 -1
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/LICENSE +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/__init__.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parser.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/__init__.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/_sensor_th.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/air_purifier.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/art_frame.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/blind_tilt.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/bot.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/bulb.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/ceiling_light.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/climate_panel.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/contact.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/curtain.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/fan.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/hub2.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/hub3.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/hubmini_matter.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/humidifier.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/keypad.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/keypad_vision.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/leak.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/light_strip.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/lock.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/meter.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/motion.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/plug.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/presence_sensor.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/relay_switch.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/remote.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/roller_shade.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/smart_thermostat_radiator.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/vacuum.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/adv_parsers/weather_station.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/api_config.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/__init__.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/air_purifier.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/climate.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/evaporative_humidifier.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/fan.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/hub2.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/hub3.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/light.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/lock.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/const/presence_sensor.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/__init__.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/art_frame.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/base_cover.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/base_light.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/blind_tilt.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/bot.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/bulb.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/ceiling_light.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/contact.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/curtain.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/device.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/evaporative_humidifier.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/fan.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/humidifier.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/keypad.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/keypad_vision.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/light_strip.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/lock.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/meter.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/meter_pro.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/motion.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/plug.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/relay_switch.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/roller_shade.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/smart_thermostat_radiator.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/universal_remote.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/devices/vacuum.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/discovery.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/enum.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/helpers.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/models.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/oauth.py +0 -0
- {pyswitchbot-3.0.0 → pyswitchbot-3.1.0}/switchbot/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PySwitchbot
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1.0
|
|
4
4
|
Summary: A library to communicate with Switchbot
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -42,6 +42,19 @@ source .venv/bin/activate
|
|
|
42
42
|
pip install .
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
## Air purifier filter reset
|
|
46
|
+
|
|
47
|
+
After replacing the filter, call `await purifier.reset_filter_usage()` on a
|
|
48
|
+
configured `SwitchbotAirPurifier` instance. The method uses the device's
|
|
49
|
+
encrypted BLE connection, sends the reset command without automatic retries,
|
|
50
|
+
and reads back the used-hours counter. It returns `True` and refreshes the
|
|
51
|
+
cached `filter element working time` only after the device reports zero.
|
|
52
|
+
|
|
53
|
+
Failed commands or an unconfirmed reset raise `SwitchbotOperationError`. If a
|
|
54
|
+
reply is lost, check the device before retrying: the reset may already have
|
|
55
|
+
been applied. This resets the device counter and does not restore its previous
|
|
56
|
+
value.
|
|
57
|
+
|
|
45
58
|
## OAuth account access
|
|
46
59
|
|
|
47
60
|
pySwitchbot provides helpers for SwitchBot's authorization-code flow. The
|
|
@@ -10,6 +10,19 @@ source .venv/bin/activate
|
|
|
10
10
|
pip install .
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
## Air purifier filter reset
|
|
14
|
+
|
|
15
|
+
After replacing the filter, call `await purifier.reset_filter_usage()` on a
|
|
16
|
+
configured `SwitchbotAirPurifier` instance. The method uses the device's
|
|
17
|
+
encrypted BLE connection, sends the reset command without automatic retries,
|
|
18
|
+
and reads back the used-hours counter. It returns `True` and refreshes the
|
|
19
|
+
cached `filter element working time` only after the device reports zero.
|
|
20
|
+
|
|
21
|
+
Failed commands or an unconfirmed reset raise `SwitchbotOperationError`. If a
|
|
22
|
+
reply is lost, check the device before retrying: the reset may already have
|
|
23
|
+
been applied. This resets the device counter and does not restore its previous
|
|
24
|
+
value.
|
|
25
|
+
|
|
13
26
|
## OAuth account access
|
|
14
27
|
|
|
15
28
|
pySwitchbot provides helpers for SwitchBot's authorization-code flow. The
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.1.0"
|
|
@@ -33,6 +33,8 @@ DEVICE_GET_BASIC_SETTINGS_KEY = "570f4d81"
|
|
|
33
33
|
COMMAND_SET_PERCENTAGE = f"{COMMAND_HEAD}02{{percentage:02x}}"
|
|
34
34
|
READ_LED_SETTINGS_COMMAND = "570f4d05"
|
|
35
35
|
READ_LED_STATUS_COMMAND = "570f4d07"
|
|
36
|
+
RESET_FILTER_USAGE_COMMAND = f"{COMMAND_HEAD}09"
|
|
37
|
+
READ_FILTER_USAGE_COMMAND = "570f4d09"
|
|
36
38
|
|
|
37
39
|
|
|
38
40
|
class SwitchbotAirPurifier(SwitchbotSequenceBaseLight, SwitchbotEncryptedDevice):
|
|
@@ -147,6 +149,31 @@ class SwitchbotAirPurifier(SwitchbotSequenceBaseLight, SwitchbotEncryptedDevice)
|
|
|
147
149
|
return data | {"pm25": pm25}
|
|
148
150
|
return data
|
|
149
151
|
|
|
152
|
+
async def reset_filter_usage(self) -> bool:
|
|
153
|
+
"""Reset filter usage, returning True only after a verified zero readback."""
|
|
154
|
+
result = await self._send_command(RESET_FILTER_USAGE_COMMAND, retry=0)
|
|
155
|
+
if not self._check_command_result(result, 0, {1}):
|
|
156
|
+
raise SwitchbotOperationError("Filter usage reset was rejected")
|
|
157
|
+
|
|
158
|
+
result = await self._send_command(READ_FILTER_USAGE_COMMAND)
|
|
159
|
+
if not result or len(result) < 3:
|
|
160
|
+
raise SwitchbotOperationError(
|
|
161
|
+
"Reset was sent, but filter usage could not be verified. "
|
|
162
|
+
"Check the device before retrying"
|
|
163
|
+
)
|
|
164
|
+
if not self._check_command_result(result, 0, {1}):
|
|
165
|
+
raise SwitchbotOperationError("Filter usage read was rejected")
|
|
166
|
+
used_hours = _UNPACK_UINT16_BE(result, 1)[0]
|
|
167
|
+
if used_hours != 0:
|
|
168
|
+
raise SwitchbotOperationError(
|
|
169
|
+
f"Reset was sent, but the device still reports {used_hours} used hours. "
|
|
170
|
+
"Check the device before retrying"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
self._update_parsed_data({"filter element working time": used_hours})
|
|
174
|
+
self._fire_callbacks()
|
|
175
|
+
return True
|
|
176
|
+
|
|
150
177
|
@update_after_operation
|
|
151
178
|
async def set_preset_mode(self, preset_mode: str) -> bool:
|
|
152
179
|
"""Send command to set air purifier preset_mode."""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "3.0.0"
|
|
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
|
|
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
|