python-roborock 6.0.0__tar.gz → 6.2.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.
- {python_roborock-6.0.0 → python_roborock-6.2.0}/PKG-INFO +1 -1
- {python_roborock-6.0.0 → python_roborock-6.2.0}/pyproject.toml +1 -1
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/code_mappings.py +19 -2
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/dyad/dyad_code_mappings.py +1 -1
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/v1/v1_code_mappings.py +32 -32
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/v1/v1_containers.py +2 -2
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/b01_q10_map_parser.py +34 -16
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/map_parser.py +61 -3
- python_roborock-6.2.0/roborock/map/room_colors.py +59 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/.gitignore +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/LICENSE +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/README.md +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/callbacks.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/cli.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/const.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/containers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/mower/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/mower/mower_containers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/device_features.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/README.md +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/cache.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/device.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/device_manager.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/file_cache.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/rpc/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/rpc/a01_channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/rpc/b01_q10_channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/rpc/b01_q7_channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/rpc/v1_channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/button_light.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/child_lock.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/clean_history.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/command.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/common.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/consumable.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/do_not_disturb.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/dust_collection.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/map.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/network_info.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/remote.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/status.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/vacuum.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/volume.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q7/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q7/clean_summary.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q7/map.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q7/map_content.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/common.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/home.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/obstacle_photos.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/routines.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/transport/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/transport/channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/transport/local_channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/transport/mqtt_channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/diagnostics.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/exceptions.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/b01_grid_layers.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/b01_map_parser.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/b01_q10_overlays.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/b01_q10_render.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/proto/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/proto/b01_scmap.proto +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/map/proto/b01_scmap_pb2.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/mqtt/health_manager.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/mqtt/session.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/protocol.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/protocols/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/protocols/b01_q10_protocol.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/protocols/b01_q7_protocol.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/py.typed +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/roborock_message.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/roborock_typing.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/testing/__init__.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/testing/b01_q10_simulator.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/testing/channel.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/testing/cloud.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/testing/simulator.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/testing/v1_simulator.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/util.py +0 -0
- {python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/web_api.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.2.0
|
|
4
4
|
Summary: A package to control Roborock vacuums.
|
|
5
5
|
Project-URL: Repository, https://github.com/python-roborock/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 = "6.
|
|
3
|
+
version = "6.2.0"
|
|
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"
|
|
@@ -10,10 +10,22 @@ completed_warnings = set()
|
|
|
10
10
|
class RoborockEnum(IntEnum):
|
|
11
11
|
"""Roborock Enum for codes with int values"""
|
|
12
12
|
|
|
13
|
+
_display_name_: str | None
|
|
14
|
+
|
|
15
|
+
def __new__(cls, value: int, display_name: str | None = None) -> Self:
|
|
16
|
+
member = int.__new__(cls, value)
|
|
17
|
+
member._value_ = value
|
|
18
|
+
member._display_name_ = display_name
|
|
19
|
+
return member
|
|
20
|
+
|
|
13
21
|
@property
|
|
14
22
|
def name(self) -> str:
|
|
15
23
|
return super().name.lower()
|
|
16
24
|
|
|
25
|
+
@property
|
|
26
|
+
def display_name(self) -> str:
|
|
27
|
+
return self._display_name_ or self.name
|
|
28
|
+
|
|
17
29
|
@classmethod
|
|
18
30
|
def _missing_(cls: type[Self], key) -> Self:
|
|
19
31
|
if hasattr(cls, "unknown"):
|
|
@@ -30,8 +42,13 @@ class RoborockEnum(IntEnum):
|
|
|
30
42
|
return default_value
|
|
31
43
|
|
|
32
44
|
@classmethod
|
|
33
|
-
def as_dict(cls: type[Self]):
|
|
34
|
-
|
|
45
|
+
def as_dict(cls: type[Self]) -> dict[str, int]:
|
|
46
|
+
result: dict[str, int] = {}
|
|
47
|
+
for item in cls:
|
|
48
|
+
if item.name == "missing":
|
|
49
|
+
continue
|
|
50
|
+
result.setdefault(item.display_name, item.value)
|
|
51
|
+
return result
|
|
35
52
|
|
|
36
53
|
@classmethod
|
|
37
54
|
def as_enum_dict(cls: type[Self]):
|
|
@@ -95,7 +95,7 @@ class DyadError(RoborockEnum):
|
|
|
95
95
|
battery_temperature_protection = (
|
|
96
96
|
20007 # Battery temperature protection. Wait for the temperature to return to a normal range.
|
|
97
97
|
)
|
|
98
|
-
battery_temperature_protection_2 = 20008
|
|
98
|
+
battery_temperature_protection_2 = (20008, "battery_temperature_protection")
|
|
99
99
|
power_adapter_error = 20009 # Check if the power adapter is working properly.
|
|
100
100
|
dirty_charging_contacts = 10007 # Disconnection between the device and dock. Wipe charging contacts.
|
|
101
101
|
low_battery = 20017 # Low battery level. Charge before starting self-cleaning.
|
|
@@ -8,40 +8,40 @@ class RoborockFinishReason(RoborockEnum):
|
|
|
8
8
|
manual_interrupt = 21 # Cleaning interrupted by user
|
|
9
9
|
cleanup_interrupted = 24 # Cleanup interrupted
|
|
10
10
|
manual_interrupt_2 = 21
|
|
11
|
-
manual_interrupt_12 = 29
|
|
11
|
+
manual_interrupt_12 = (29, "manual_interrupt")
|
|
12
12
|
breakpoint = 32 # Could not continue cleaning
|
|
13
|
-
breakpoint_2 = 33
|
|
14
|
-
cleanup_interrupted_2 = 34
|
|
15
|
-
manual_interrupt_3 = 35
|
|
16
|
-
manual_interrupt_4 = 36
|
|
17
|
-
manual_interrupt_5 = 37
|
|
18
|
-
manual_interrupt_6 = 43
|
|
13
|
+
breakpoint_2 = (33, "breakpoint")
|
|
14
|
+
cleanup_interrupted_2 = (34, "cleanup_interrupted")
|
|
15
|
+
manual_interrupt_3 = (35, "manual_interrupt")
|
|
16
|
+
manual_interrupt_4 = (36, "manual_interrupt")
|
|
17
|
+
manual_interrupt_5 = (37, "manual_interrupt")
|
|
18
|
+
manual_interrupt_6 = (43, "manual_interrupt")
|
|
19
19
|
locate_fail = 45 # Positioning Failed
|
|
20
|
-
cleanup_interrupted_3 = 64
|
|
21
|
-
locate_fail_2 = 65
|
|
22
|
-
manual_interrupt_7 = 48
|
|
23
|
-
manual_interrupt_8 = 49
|
|
24
|
-
manual_interrupt_9 = 50
|
|
25
|
-
cleanup_interrupted_4 = 51
|
|
20
|
+
cleanup_interrupted_3 = (64, "cleanup_interrupted")
|
|
21
|
+
locate_fail_2 = (65, "locate_fail")
|
|
22
|
+
manual_interrupt_7 = (48, "manual_interrupt")
|
|
23
|
+
manual_interrupt_8 = (49, "manual_interrupt")
|
|
24
|
+
manual_interrupt_9 = (50, "manual_interrupt")
|
|
25
|
+
cleanup_interrupted_4 = (51, "cleanup_interrupted")
|
|
26
26
|
finished_cleaning = 52 # Finished cleaning
|
|
27
|
-
finished_cleaning_2 = 54
|
|
28
|
-
finished_cleaning_3 = 55
|
|
29
|
-
finished_cleaning_4 = 56
|
|
30
|
-
finished_clenaing_5 = 57
|
|
31
|
-
manual_interrupt_10 = 60
|
|
27
|
+
finished_cleaning_2 = (54, "finished_cleaning")
|
|
28
|
+
finished_cleaning_3 = (55, "finished_cleaning")
|
|
29
|
+
finished_cleaning_4 = (56, "finished_cleaning")
|
|
30
|
+
finished_clenaing_5 = (57, "finished_cleaning")
|
|
31
|
+
manual_interrupt_10 = (60, "manual_interrupt")
|
|
32
32
|
area_unreachable = 61 # Area unreachable
|
|
33
|
-
area_unreachable_2 = 62
|
|
33
|
+
area_unreachable_2 = (62, "area_unreachable")
|
|
34
34
|
washing_error = 67 # Washing error
|
|
35
35
|
back_to_wash_failure = 68 # Failed to return to the dock
|
|
36
|
-
cleanup_interrupted_5 = 101
|
|
37
|
-
breakpoint_4 = 102
|
|
38
|
-
manual_interrupt_11 = 103
|
|
39
|
-
cleanup_interrupted_6 = 104
|
|
40
|
-
cleanup_interrupted_7 = 105
|
|
41
|
-
cleanup_interrupted_8 = 106
|
|
42
|
-
cleanup_interrupted_9 = 107
|
|
43
|
-
cleanup_interrupted_10 = 109
|
|
44
|
-
cleanup_interrupted_11 = 110
|
|
36
|
+
cleanup_interrupted_5 = (101, "cleanup_interrupted")
|
|
37
|
+
breakpoint_4 = (102, "breakpoint")
|
|
38
|
+
manual_interrupt_11 = (103, "manual_interrupt")
|
|
39
|
+
cleanup_interrupted_6 = (104, "cleanup_interrupted")
|
|
40
|
+
cleanup_interrupted_7 = (105, "cleanup_interrupted")
|
|
41
|
+
cleanup_interrupted_8 = (106, "cleanup_interrupted")
|
|
42
|
+
cleanup_interrupted_9 = (107, "cleanup_interrupted")
|
|
43
|
+
cleanup_interrupted_10 = (109, "cleanup_interrupted")
|
|
44
|
+
cleanup_interrupted_11 = (110, "cleanup_interrupted")
|
|
45
45
|
patrol_success = 114 # Cruise completed
|
|
46
46
|
patrol_fail = 115 # Cruise failed
|
|
47
47
|
pet_patrol_success = 116 # Pet found
|
|
@@ -159,7 +159,7 @@ class ClearWaterBoxStatus(RoborockDssCodes):
|
|
|
159
159
|
|
|
160
160
|
okay = 0
|
|
161
161
|
out_of_water = 1
|
|
162
|
-
out_of_water_2 = 38
|
|
162
|
+
out_of_water_2 = (38, "out_of_water")
|
|
163
163
|
refill_error = 48
|
|
164
164
|
|
|
165
165
|
|
|
@@ -168,7 +168,7 @@ class DirtyWaterBoxStatus(RoborockDssCodes):
|
|
|
168
168
|
|
|
169
169
|
okay = 0
|
|
170
170
|
full_not_installed = 1
|
|
171
|
-
full_not_installed_2 = 39
|
|
171
|
+
full_not_installed_2 = (39, "full_not_installed")
|
|
172
172
|
drain_error = 49
|
|
173
173
|
|
|
174
174
|
|
|
@@ -232,7 +232,7 @@ class RoborockErrorCode(RoborockEnum):
|
|
|
232
232
|
clear_brush_exception = 42 # Check that the water filter has been correctly installed
|
|
233
233
|
clear_brush_exception_2 = 43 # Positioning button error
|
|
234
234
|
filter_screen_exception = 44 # Clean the dock water filter
|
|
235
|
-
mopping_roller_2 = 45 # Wash roller may be jammed
|
|
235
|
+
mopping_roller_2 = (45, "mopping_roller_1") # Wash roller may be jammed
|
|
236
236
|
up_water_exception = 48
|
|
237
237
|
drain_water_exception = 49
|
|
238
238
|
temperature_protection = 51 # Unit temperature protection
|
|
@@ -421,7 +421,7 @@ class RoborockStateCode(RoborockEnum):
|
|
|
421
421
|
segment_cleaning = 18
|
|
422
422
|
emptying_the_bin = 22 # on s7+
|
|
423
423
|
washing_the_mop = 23 # on a46
|
|
424
|
-
washing_the_mop_2 = 25
|
|
424
|
+
washing_the_mop_2 = (25, "washing_the_mop")
|
|
425
425
|
going_to_wash_the_mop = 26 # on a46
|
|
426
426
|
in_call = 28
|
|
427
427
|
mapping = 29
|
|
@@ -144,11 +144,11 @@ class StatusV2(RoborockBase):
|
|
|
144
144
|
|
|
145
145
|
@property
|
|
146
146
|
def error_code_name(self) -> str | None:
|
|
147
|
-
return self.error_code.
|
|
147
|
+
return self.error_code.display_name if self.error_code is not None else None
|
|
148
148
|
|
|
149
149
|
@property
|
|
150
150
|
def state_name(self) -> str | None:
|
|
151
|
-
return self.state.
|
|
151
|
+
return self.state.display_name if self.state is not None else None
|
|
152
152
|
|
|
153
153
|
@property
|
|
154
154
|
def current_map(self) -> int | None:
|
|
@@ -19,13 +19,13 @@ documentation that informed this clean-room implementation comes from the
|
|
|
19
19
|
https://github.com/v1b3c0d3x3r/roborock-qseries-map-bridge
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
-
import colorsys
|
|
23
22
|
import io
|
|
24
23
|
import math
|
|
25
24
|
import statistics
|
|
26
25
|
from dataclasses import dataclass, field, replace
|
|
27
26
|
|
|
28
27
|
from PIL import Image
|
|
28
|
+
from vacuum_map_parser_base.config.color import ColorsPalette, SupportedColor
|
|
29
29
|
from vacuum_map_parser_base.config.image_config import ImageConfig
|
|
30
30
|
from vacuum_map_parser_base.map_data import ImageData, MapData
|
|
31
31
|
|
|
@@ -40,6 +40,7 @@ from .b01_grid_layers import (
|
|
|
40
40
|
decompose_grid,
|
|
41
41
|
)
|
|
42
42
|
from .map_parser import ParsedMapData
|
|
43
|
+
from .room_colors import adjacency_aware_room_colors
|
|
43
44
|
|
|
44
45
|
_MAP_FILE_FORMAT = "PNG"
|
|
45
46
|
|
|
@@ -655,12 +656,12 @@ class B01Q10MapParser:
|
|
|
655
656
|
return ParsedMapData(image_content=image_bytes.getvalue(), map_data=map_data)
|
|
656
657
|
|
|
657
658
|
def _render(self, packet: Q10MapPacket) -> Image.Image:
|
|
658
|
-
"""Render the Q10 grid
|
|
659
|
-
palette = _build_palette(packet.grid)
|
|
660
|
-
|
|
659
|
+
"""Render the Q10 grid with the V1 map palette."""
|
|
660
|
+
palette = _build_palette(packet.grid, packet.width)
|
|
661
|
+
rgba = bytearray()
|
|
661
662
|
for value in packet.grid:
|
|
662
|
-
|
|
663
|
-
img = Image.frombytes("
|
|
663
|
+
rgba.extend(palette[value])
|
|
664
|
+
img = Image.frombytes("RGBA", (packet.width, packet.height), bytes(rgba))
|
|
664
665
|
# The ss07 grid is stored top-down (row 0 = top of the home), so it is
|
|
665
666
|
# rendered as-is -- unlike the V1/Q7 convention, no vertical flip.
|
|
666
667
|
scale = self._config.map_scale
|
|
@@ -669,15 +670,32 @@ class B01Q10MapParser:
|
|
|
669
670
|
return img
|
|
670
671
|
|
|
671
672
|
|
|
672
|
-
def
|
|
673
|
-
"""
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
673
|
+
def _opaque(color: tuple[int, ...]) -> tuple[int, int, int, int]:
|
|
674
|
+
"""Return a palette color as RGBA."""
|
|
675
|
+
return (color[0], color[1], color[2], color[3] if len(color) == 4 else 255)
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
def _build_palette(grid: bytes, width: int) -> list[tuple[int, int, int, int]]:
|
|
679
|
+
"""Map Q10 cells onto the same colors used by the V1 map renderer."""
|
|
680
|
+
|
|
681
|
+
def room_id(value: int) -> int | None:
|
|
682
|
+
return max(1, value // 4) if 0 < value < _WALL_THRESHOLD else None
|
|
683
|
+
|
|
684
|
+
colors = ColorsPalette()
|
|
685
|
+
room_colors = adjacency_aware_room_colors(
|
|
686
|
+
grid,
|
|
687
|
+
width,
|
|
688
|
+
colors,
|
|
689
|
+
room_id,
|
|
690
|
+
)
|
|
691
|
+
outside = (0, 0, 0, 0)
|
|
692
|
+
palette = [outside] * 256
|
|
693
|
+
for value in {value for value in grid if 0 < value < _WALL_THRESHOLD}:
|
|
694
|
+
palette[value] = _opaque(room_colors[max(1, value // 4)])
|
|
695
|
+
wall = _opaque(colors.get_color(SupportedColor.GREY_WALL))
|
|
680
696
|
for value in range(_WALL_THRESHOLD, 256):
|
|
681
|
-
palette[value] =
|
|
682
|
-
palette[
|
|
697
|
+
palette[value] = wall
|
|
698
|
+
palette[_UNSEGMENTED_FLOOR_VALUE] = _opaque(colors.get_color(SupportedColor.MAP_INSIDE))
|
|
699
|
+
palette[_BACKGROUND_VALUE] = outside
|
|
700
|
+
palette[0] = outside
|
|
683
701
|
return palette
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import io
|
|
4
4
|
import logging
|
|
5
|
+
import threading
|
|
5
6
|
from dataclasses import dataclass, field
|
|
6
7
|
|
|
7
8
|
from vacuum_map_parser_base.config.color import ColorsPalette, SupportedColor
|
|
@@ -9,10 +10,13 @@ from vacuum_map_parser_base.config.drawable import Drawable
|
|
|
9
10
|
from vacuum_map_parser_base.config.image_config import ImageConfig
|
|
10
11
|
from vacuum_map_parser_base.config.size import Size, Sizes
|
|
11
12
|
from vacuum_map_parser_base.map_data import MapData
|
|
13
|
+
from vacuum_map_parser_roborock.image_parser import RoborockImageParser
|
|
12
14
|
from vacuum_map_parser_roborock.map_data_parser import RoborockMapDataParser
|
|
13
15
|
|
|
14
16
|
from roborock.exceptions import RoborockException
|
|
15
17
|
|
|
18
|
+
from .room_colors import adjacency_aware_room_colors
|
|
19
|
+
|
|
16
20
|
_LOGGER = logging.getLogger(__name__)
|
|
17
21
|
|
|
18
22
|
DEFAULT_DRAWABLES = {
|
|
@@ -98,6 +102,52 @@ class MapParser:
|
|
|
98
102
|
return ParsedMapData(image_content=img_byte_arr.getvalue(), map_data=parsed_map)
|
|
99
103
|
|
|
100
104
|
|
|
105
|
+
class _AdjacencyAwareRoborockImageParser(RoborockImageParser):
|
|
106
|
+
"""Apply the shared adjacency color policy to V1 room cells."""
|
|
107
|
+
|
|
108
|
+
def __init__(
|
|
109
|
+
self,
|
|
110
|
+
palette: ColorsPalette,
|
|
111
|
+
image_config: ImageConfig,
|
|
112
|
+
*,
|
|
113
|
+
recolor_rooms: bool = True,
|
|
114
|
+
) -> None:
|
|
115
|
+
super().__init__(palette, image_config)
|
|
116
|
+
self._room_palette = palette
|
|
117
|
+
self._base_room_colors = palette.cached_room_colors.copy()
|
|
118
|
+
self._recolor_rooms = recolor_rooms
|
|
119
|
+
self._palette_lock = threading.Lock()
|
|
120
|
+
|
|
121
|
+
def parse(
|
|
122
|
+
self,
|
|
123
|
+
raw_data: bytes,
|
|
124
|
+
width: int,
|
|
125
|
+
height: int,
|
|
126
|
+
carpet_map: set[int] | None,
|
|
127
|
+
removed_map: set[int] | None = None,
|
|
128
|
+
):
|
|
129
|
+
"""Assign non-conflicting room colors before the V1 image pass."""
|
|
130
|
+
with self._palette_lock:
|
|
131
|
+
# cached_room_colors is a read-only property, so reset its dict in place.
|
|
132
|
+
cached_room_colors = self._room_palette.cached_room_colors
|
|
133
|
+
cached_room_colors.clear()
|
|
134
|
+
cached_room_colors.update(self._base_room_colors)
|
|
135
|
+
|
|
136
|
+
if self._recolor_rooms:
|
|
137
|
+
|
|
138
|
+
def room_id(value: int) -> int | None:
|
|
139
|
+
if value in (self.MAP_OUTSIDE, self.MAP_WALL, self.MAP_INSIDE, self.MAP_SCAN):
|
|
140
|
+
return None
|
|
141
|
+
return self._get_room_number(value) if value & 0x07 == 0x07 else None
|
|
142
|
+
|
|
143
|
+
room_colors = adjacency_aware_room_colors(raw_data, width, self._room_palette, room_id)
|
|
144
|
+
for number, color in room_colors.items():
|
|
145
|
+
# ColorsPalette caches both forms for get_room_color(str | int).
|
|
146
|
+
cached_room_colors[number] = color
|
|
147
|
+
cached_room_colors[str(number)] = color
|
|
148
|
+
return super().parse(raw_data, width, height, carpet_map, removed_map)
|
|
149
|
+
|
|
150
|
+
|
|
101
151
|
def _create_map_data_parser(config: MapParserConfig) -> RoborockMapDataParser:
|
|
102
152
|
"""Create a RoborockMapDataParser based on the config entry."""
|
|
103
153
|
color_dicts = {}
|
|
@@ -114,10 +164,18 @@ def _create_map_data_parser(config: MapParserConfig) -> RoborockMapDataParser:
|
|
|
114
164
|
if not config.show_rooms:
|
|
115
165
|
room_colors = {str(x): (0, 0, 0, 0) for x in range(1, 32)}
|
|
116
166
|
|
|
117
|
-
|
|
118
|
-
|
|
167
|
+
palette = ColorsPalette(color_dicts, room_colors)
|
|
168
|
+
image_config = ImageConfig(scale=config.map_scale)
|
|
169
|
+
parser = RoborockMapDataParser(
|
|
170
|
+
palette,
|
|
119
171
|
Sizes({k: v * config.map_scale for k, v in Sizes.SIZES.items() if k != Size.MOP_PATH_WIDTH}),
|
|
120
172
|
config.drawables,
|
|
121
|
-
|
|
173
|
+
image_config,
|
|
122
174
|
[],
|
|
123
175
|
)
|
|
176
|
+
parser._image_parser = _AdjacencyAwareRoborockImageParser(
|
|
177
|
+
palette,
|
|
178
|
+
image_config,
|
|
179
|
+
recolor_rooms=config.show_rooms,
|
|
180
|
+
)
|
|
181
|
+
return parser
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Deterministic room colors that keep adjacent segments distinguishable."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable, Sequence
|
|
4
|
+
|
|
5
|
+
from vacuum_map_parser_base.config.color import Color, ColorsPalette
|
|
6
|
+
|
|
7
|
+
RoomIdFromCell = Callable[[int], int | None]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def adjacency_aware_room_colors(
|
|
11
|
+
grid: Sequence[int],
|
|
12
|
+
width: int,
|
|
13
|
+
palette: ColorsPalette,
|
|
14
|
+
room_id_from_cell: RoomIdFromCell,
|
|
15
|
+
) -> dict[int, Color]:
|
|
16
|
+
"""Return room colors, changing only adjacent same-color conflicts.
|
|
17
|
+
|
|
18
|
+
Room IDs remain the stable preference, matching the existing V1 palette.
|
|
19
|
+
When two rooms sharing an edge resolve to the same RGB value, the
|
|
20
|
+
higher-numbered room receives the first palette color not already used by
|
|
21
|
+
one of its colored neighbors.
|
|
22
|
+
"""
|
|
23
|
+
if width <= 0:
|
|
24
|
+
return {}
|
|
25
|
+
|
|
26
|
+
room_ids: set[int] = set()
|
|
27
|
+
neighbors: dict[int, set[int]] = {}
|
|
28
|
+
for index, value in enumerate(grid):
|
|
29
|
+
room_id = room_id_from_cell(value)
|
|
30
|
+
if room_id is None:
|
|
31
|
+
continue
|
|
32
|
+
room_ids.add(room_id)
|
|
33
|
+
neighbors.setdefault(room_id, set())
|
|
34
|
+
|
|
35
|
+
for neighbor_index in (index - 1 if index % width else -1, index - width):
|
|
36
|
+
if neighbor_index < 0:
|
|
37
|
+
continue
|
|
38
|
+
neighbor_id = room_id_from_cell(grid[neighbor_index])
|
|
39
|
+
if neighbor_id is None or neighbor_id == room_id:
|
|
40
|
+
continue
|
|
41
|
+
neighbors[room_id].add(neighbor_id)
|
|
42
|
+
neighbors.setdefault(neighbor_id, set()).add(room_id)
|
|
43
|
+
|
|
44
|
+
candidates: list[Color] = []
|
|
45
|
+
for palette_id in map(int, ColorsPalette.ROOM_COLORS):
|
|
46
|
+
color = palette.get_room_color(palette_id)
|
|
47
|
+
if color not in candidates:
|
|
48
|
+
candidates.append(color)
|
|
49
|
+
|
|
50
|
+
assigned: dict[int, Color] = {}
|
|
51
|
+
for room_id in sorted(room_ids):
|
|
52
|
+
preferred = palette.get_room_color(room_id)
|
|
53
|
+
neighbor_colors = {assigned[neighbor] for neighbor in neighbors[room_id] if neighbor in assigned}
|
|
54
|
+
assigned[room_id] = (
|
|
55
|
+
preferred
|
|
56
|
+
if preferred not in neighbor_colors
|
|
57
|
+
else next((color for color in candidates if color not in neighbor_colors), preferred)
|
|
58
|
+
)
|
|
59
|
+
return assigned
|
|
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-6.0.0 → python_roborock-6.2.0}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/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
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/button_light.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/child_lock.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/clean_history.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/consumable.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/dust_collection.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q10/network_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q7/clean_summary.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/b01/q7/map_content.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
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/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
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/obstacle_photos.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-6.0.0 → python_roborock-6.2.0}/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
|
|
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
|