python-roborock 4.0.1__tar.gz → 4.0.2__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.
- {python_roborock-4.0.1 → python_roborock-4.0.2}/PKG-INFO +1 -1
- {python_roborock-4.0.1 → python_roborock-4.0.2}/pyproject.toml +1 -1
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/code_mappings.py +13 -1
- python_roborock-4.0.2/roborock/protocols/b01_q10_protocol.py +88 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/.gitignore +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/LICENSE +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/README.md +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/callbacks.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/cli.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/const.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/containers.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/v1/v1_containers.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/device_features.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/README.md +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/a01_channel.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/b01_q7_channel.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/cache.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/channel.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/device.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/device_manager.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/file_cache.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/local_channel.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/mqtt_channel.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/home.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/v1_channel.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/diagnostics.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/exceptions.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/map/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/map/map_parser.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/mqtt/session.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/protocol.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/protocols/__init__.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/py.typed +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/roborock_message.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/roborock_typing.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/util.py +0 -0
- {python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/web_api.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.2
|
|
4
4
|
Summary: A package to control Roborock vacuums.
|
|
5
5
|
Project-URL: Repository, https://github.com/humbertogontijo/python-roborock
|
|
6
6
|
Project-URL: Documentation, https://python-roborock.readthedocs.io/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-roborock"
|
|
3
|
-
version = "4.0.
|
|
3
|
+
version = "4.0.2"
|
|
4
4
|
description = "A package to control Roborock vacuums."
|
|
5
5
|
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
|
|
6
6
|
requires-python = ">=3.11, <4"
|
|
@@ -55,6 +55,7 @@ class RoborockModeEnum(StrEnum):
|
|
|
55
55
|
"""A custom StrEnum that also stores an integer code for each member."""
|
|
56
56
|
|
|
57
57
|
code: int
|
|
58
|
+
"""The integer code associated with the enum member."""
|
|
58
59
|
|
|
59
60
|
def __new__(cls, value: str, code: int) -> RoborockModeEnum:
|
|
60
61
|
"""Creates a new enum member."""
|
|
@@ -68,7 +69,18 @@ class RoborockModeEnum(StrEnum):
|
|
|
68
69
|
for member in cls:
|
|
69
70
|
if member.code == code:
|
|
70
71
|
return member
|
|
71
|
-
|
|
72
|
+
message = f"{code} is not a valid code for {cls.__name__}"
|
|
73
|
+
if message not in completed_warnings:
|
|
74
|
+
completed_warnings.add(message)
|
|
75
|
+
_LOGGER.warning(message)
|
|
76
|
+
raise ValueError(message)
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def from_code_optional(cls, code: int) -> RoborockModeEnum | None:
|
|
80
|
+
try:
|
|
81
|
+
return cls.from_code(code)
|
|
82
|
+
except ValueError:
|
|
83
|
+
return None
|
|
72
84
|
|
|
73
85
|
@classmethod
|
|
74
86
|
def from_value(cls, value: str) -> RoborockModeEnum:
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Roborock B01 Protocol encoding and decoding."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from roborock.data.b01_q10.b01_q10_code_mappings import B01_Q10_DP
|
|
8
|
+
from roborock.exceptions import RoborockException
|
|
9
|
+
from roborock.roborock_message import (
|
|
10
|
+
RoborockMessage,
|
|
11
|
+
RoborockMessageProtocol,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
_LOGGER = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
B01_VERSION = b"B01"
|
|
17
|
+
ParamsType = list | dict | int | None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def encode_mqtt_payload(command: B01_Q10_DP, params: ParamsType) -> RoborockMessage:
|
|
21
|
+
"""Encode payload for B01 Q10 commands over MQTT.
|
|
22
|
+
|
|
23
|
+
This does not perform any special encoding for the command parameters and expects
|
|
24
|
+
them to already be in a request specific format.
|
|
25
|
+
"""
|
|
26
|
+
dps_data = {
|
|
27
|
+
"dps": {
|
|
28
|
+
# Important: some commands use falsy values so only default to `{}` when params is actually None.
|
|
29
|
+
command.code: params if params is not None else {},
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return RoborockMessage(
|
|
33
|
+
protocol=RoborockMessageProtocol.RPC_REQUEST,
|
|
34
|
+
version=B01_VERSION,
|
|
35
|
+
payload=json.dumps(dps_data).encode("utf-8"),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _convert_datapoints(datapoints: dict[str, Any], message: RoborockMessage) -> dict[B01_Q10_DP, Any]:
|
|
40
|
+
"""Convert the 'dps' dictionary keys from strings to B01_Q10_DP enums."""
|
|
41
|
+
result: dict[B01_Q10_DP, Any] = {}
|
|
42
|
+
for key, value in datapoints.items():
|
|
43
|
+
try:
|
|
44
|
+
code = int(key)
|
|
45
|
+
except ValueError as e:
|
|
46
|
+
raise ValueError(f"dps key is not a valid integer: {e} for {message.payload!r}") from e
|
|
47
|
+
if (dps := B01_Q10_DP.from_code_optional(code)) is not None:
|
|
48
|
+
# Update from_code to use `Self` on newer python version to remove this type ignore
|
|
49
|
+
result[dps] = value # type: ignore[index]
|
|
50
|
+
return result
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def decode_rpc_response(message: RoborockMessage) -> dict[B01_Q10_DP, Any]:
|
|
54
|
+
"""Decode a B01 Q10 RPC_RESPONSE message.
|
|
55
|
+
|
|
56
|
+
This does not perform any special decoding for the response body, but does
|
|
57
|
+
convert the 'dps' keys from strings to B01_Q10_DP enums.
|
|
58
|
+
"""
|
|
59
|
+
if not message.payload:
|
|
60
|
+
raise RoborockException("Invalid B01 message format: missing payload")
|
|
61
|
+
try:
|
|
62
|
+
payload = json.loads(message.payload.decode())
|
|
63
|
+
except (json.JSONDecodeError, UnicodeDecodeError) as e:
|
|
64
|
+
raise RoborockException(f"Invalid B01 json payload: {e} for {message.payload!r}") from e
|
|
65
|
+
|
|
66
|
+
if (datapoints := payload.get("dps")) is None:
|
|
67
|
+
raise RoborockException(f"Invalid B01 json payload: missing 'dps' for {message.payload!r}")
|
|
68
|
+
if not isinstance(datapoints, dict):
|
|
69
|
+
raise RoborockException(f"Invalid B01 message format: 'dps' should be a dictionary for {message.payload!r}")
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
result = _convert_datapoints(datapoints, message)
|
|
73
|
+
except ValueError as e:
|
|
74
|
+
raise RoborockException(f"Invalid B01 message format: {e}") from e
|
|
75
|
+
|
|
76
|
+
# The COMMON response contains nested datapoints need conversion. To simplify
|
|
77
|
+
# response handling at higher levels we flatten these into the main result.
|
|
78
|
+
if B01_Q10_DP.COMMON in result:
|
|
79
|
+
common_result = result.pop(B01_Q10_DP.COMMON)
|
|
80
|
+
if not isinstance(common_result, dict):
|
|
81
|
+
raise RoborockException(f"Invalid dpCommon format: expected dict, got {type(common_result).__name__}")
|
|
82
|
+
try:
|
|
83
|
+
common_dps_result = _convert_datapoints(common_result, message)
|
|
84
|
+
except ValueError as e:
|
|
85
|
+
raise RoborockException(f"Invalid dpCommon format: {e}") from e
|
|
86
|
+
result.update(common_dps_result)
|
|
87
|
+
|
|
88
|
+
return result
|
|
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
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/data/b01_q7/b01_q7_code_mappings.py
RENAMED
|
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
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/flow_led_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.0.1 → python_roborock-4.0.2}/roborock/devices/traits/v1/wash_towel_mode.py
RENAMED
|
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
|