python-roborock 4.7.1__tar.gz → 4.7.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.7.1 → python_roborock-4.7.2}/PKG-INFO +1 -1
- {python_roborock-4.7.1 → python_roborock-4.7.2}/pyproject.toml +1 -1
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/home.py +7 -2
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/exceptions.py +4 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/protocols/v1_protocol.py +42 -12
- {python_roborock-4.7.1 → python_roborock-4.7.2}/.gitignore +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/LICENSE +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/README.md +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/callbacks.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/cli.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/const.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/code_mappings.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/containers.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/v1/v1_containers.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/device_features.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/README.md +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/cache.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/device.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/device_manager.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/file_cache.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/rpc/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/rpc/a01_channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/rpc/b01_q10_channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/rpc/b01_q7_channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/rpc/v1_channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/b01/q10/command.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/transport/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/transport/channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/transport/local_channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/transport/mqtt_channel.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/diagnostics.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/map/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/map/map_parser.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/mqtt/session.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/protocol.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/protocols/__init__.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/protocols/b01_q10_protocol.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/py.typed +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/roborock_message.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/roborock_typing.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/util.py +0 -0
- {python_roborock-4.7.1 → python_roborock-4.7.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.7.
|
|
3
|
+
Version: 4.7.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.7.
|
|
3
|
+
version = "4.7.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"
|
|
@@ -24,7 +24,7 @@ from roborock.data import CombinedMapInfo, NamedRoomMapping, RoborockBase
|
|
|
24
24
|
from roborock.data.v1.v1_code_mappings import RoborockStateCode
|
|
25
25
|
from roborock.devices.cache import DeviceCache
|
|
26
26
|
from roborock.devices.traits.v1 import common
|
|
27
|
-
from roborock.exceptions import RoborockDeviceBusy, RoborockException
|
|
27
|
+
from roborock.exceptions import RoborockDeviceBusy, RoborockException, RoborockInvalidStatus
|
|
28
28
|
from roborock.roborock_typing import RoborockCommand
|
|
29
29
|
|
|
30
30
|
from .map_content import MapContent, MapContentTrait
|
|
@@ -171,7 +171,12 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
171
171
|
# We need to load each map to get its room data
|
|
172
172
|
if len(sorted_map_infos) > 1:
|
|
173
173
|
_LOGGER.debug("Loading map %s", map_info.map_flag)
|
|
174
|
-
|
|
174
|
+
try:
|
|
175
|
+
await self._maps_trait.set_current_map(map_info.map_flag)
|
|
176
|
+
except RoborockInvalidStatus as ex:
|
|
177
|
+
# Device is in a state that forbids map switching. Translate to
|
|
178
|
+
# "busy" so callers can fall back to refreshing the current map only.
|
|
179
|
+
raise RoborockDeviceBusy("Cannot switch maps right now (device action locked)") from ex
|
|
175
180
|
await asyncio.sleep(MAP_SLEEP)
|
|
176
181
|
|
|
177
182
|
map_content = await self._refresh_map_content()
|
|
@@ -87,5 +87,9 @@ class RoborockDeviceBusy(RoborockException):
|
|
|
87
87
|
"""Class for Roborock device busy exceptions."""
|
|
88
88
|
|
|
89
89
|
|
|
90
|
+
class RoborockInvalidStatus(RoborockException):
|
|
91
|
+
"""Class for Roborock invalid status exceptions (device action locked)."""
|
|
92
|
+
|
|
93
|
+
|
|
90
94
|
class RoborockUnsupportedFeature(RoborockException):
|
|
91
95
|
"""Class for Roborock unsupported feature exceptions."""
|
|
@@ -13,7 +13,7 @@ from enum import StrEnum
|
|
|
13
13
|
from typing import Any, Protocol, TypeVar, overload
|
|
14
14
|
|
|
15
15
|
from roborock.data import RoborockBase, RRiot
|
|
16
|
-
from roborock.exceptions import RoborockException, RoborockUnsupportedFeature
|
|
16
|
+
from roborock.exceptions import RoborockException, RoborockInvalidStatus, RoborockUnsupportedFeature
|
|
17
17
|
from roborock.protocol import Utils
|
|
18
18
|
from roborock.roborock_message import RoborockMessage, RoborockMessageProtocol
|
|
19
19
|
from roborock.roborock_typing import RoborockCommand
|
|
@@ -106,6 +106,24 @@ class RequestMessage:
|
|
|
106
106
|
|
|
107
107
|
ResponseData = dict[str, Any] | list | int
|
|
108
108
|
|
|
109
|
+
# V1 RPC error code mappings to specific exception types
|
|
110
|
+
_V1_ERROR_CODE_EXCEPTIONS: dict[int, type[RoborockException]] = {
|
|
111
|
+
-10007: RoborockInvalidStatus, # "invalid status" - device action locked
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _create_api_error(error: Any) -> RoborockException:
|
|
116
|
+
"""Create an appropriate exception for a V1 RPC error response.
|
|
117
|
+
|
|
118
|
+
Maps known error codes to specific exception types for easier handling
|
|
119
|
+
at higher levels.
|
|
120
|
+
"""
|
|
121
|
+
if isinstance(error, dict):
|
|
122
|
+
code = error.get("code")
|
|
123
|
+
if isinstance(code, int) and (exc_type := _V1_ERROR_CODE_EXCEPTIONS.get(code)):
|
|
124
|
+
return exc_type(error)
|
|
125
|
+
return RoborockException(error)
|
|
126
|
+
|
|
109
127
|
|
|
110
128
|
@dataclass(kw_only=True, frozen=True)
|
|
111
129
|
class ResponseMessage:
|
|
@@ -154,26 +172,38 @@ def decode_rpc_response(message: RoborockMessage) -> ResponseMessage:
|
|
|
154
172
|
) from e
|
|
155
173
|
|
|
156
174
|
request_id: int | None = data_point_response.get("id")
|
|
157
|
-
|
|
175
|
+
api_error: RoborockException | None = None
|
|
158
176
|
if error := data_point_response.get("error"):
|
|
159
|
-
|
|
177
|
+
api_error = _create_api_error(error)
|
|
178
|
+
|
|
160
179
|
if (result := data_point_response.get("result")) is None:
|
|
161
|
-
|
|
180
|
+
# Some firmware versions return an error-only response (no "result" key).
|
|
181
|
+
# Preserve that error instead of overwriting it with a parsing exception.
|
|
182
|
+
if api_error is None:
|
|
183
|
+
api_error = RoborockException(
|
|
184
|
+
f"Invalid V1 message format: missing 'result' in data point for {message.payload!r}"
|
|
185
|
+
)
|
|
186
|
+
result = {}
|
|
162
187
|
else:
|
|
163
188
|
_LOGGER.debug("Decoded V1 message result: %s", result)
|
|
164
189
|
if isinstance(result, str):
|
|
165
190
|
if result == "unknown_method":
|
|
166
|
-
|
|
191
|
+
api_error = RoborockUnsupportedFeature("The method called is not recognized by the device.")
|
|
167
192
|
elif result != "ok":
|
|
168
|
-
|
|
193
|
+
api_error = RoborockException(f"Unexpected API Result: {result}")
|
|
169
194
|
result = {}
|
|
170
195
|
if not isinstance(result, dict | list | int):
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
196
|
+
# If we already have an API error, prefer returning a response object
|
|
197
|
+
# rather than failing to decode the message entirely.
|
|
198
|
+
if api_error is None:
|
|
199
|
+
raise RoborockException(
|
|
200
|
+
f"Invalid V1 message format: 'result' was unexpected type {type(result)}. {message.payload!r}"
|
|
201
|
+
)
|
|
202
|
+
result = {}
|
|
203
|
+
|
|
204
|
+
if not request_id and api_error:
|
|
205
|
+
raise api_error
|
|
206
|
+
return ResponseMessage(request_id=request_id, data=result, api_error=api_error)
|
|
177
207
|
|
|
178
208
|
|
|
179
209
|
@dataclass
|
|
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.7.1 → python_roborock-4.7.2}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.7.1 → python_roborock-4.7.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
|
|
File without changes
|
|
File without changes
|
{python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-4.7.1 → python_roborock-4.7.2}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-4.7.1 → python_roborock-4.7.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
|
{python_roborock-4.7.1 → python_roborock-4.7.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.7.1 → python_roborock-4.7.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
|
|
File without changes
|
|
File without changes
|