Skip to content

Commit d8b759b

Browse files
authored
Merge branch 'main' into feat/q10-cli-commands
2 parents 48b7fcf + dfa2fb1 commit d8b759b

File tree

12 files changed

+136
-24
lines changed

12 files changed

+136
-24
lines changed

CHANGELOG.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,67 @@
22

33
<!-- version list -->
44

5+
## v4.12.0 (2026-02-02)
6+
7+
### Bug Fixes
8+
9+
- **map**: Removed unnecessary conversion of empty dict to none
10+
([#763](https://github.com/Python-roborock/python-roborock/pull/763),
11+
[`5e28569`](https://github.com/Python-roborock/python-roborock/commit/5e285694b329701c019d804540493d856299a138))
12+
13+
### Features
14+
15+
- Add support for hiding walls and rooms in map rendering
16+
([#763](https://github.com/Python-roborock/python-roborock/pull/763),
17+
[`5e28569`](https://github.com/Python-roborock/python-roborock/commit/5e285694b329701c019d804540493d856299a138))
18+
19+
- **map**: Add option to hide walls and rooms in map rendering
20+
([#763](https://github.com/Python-roborock/python-roborock/pull/763),
21+
[`5e28569`](https://github.com/Python-roborock/python-roborock/commit/5e285694b329701c019d804540493d856299a138))
22+
23+
24+
## v4.11.0 (2026-02-02)
25+
26+
### Features
27+
28+
- Add clean route and repeat for q7
29+
([#756](https://github.com/Python-roborock/python-roborock/pull/756),
30+
[`35f7910`](https://github.com/Python-roborock/python-roborock/commit/35f7910263dd4e61ffbd0c20e2d88d2f34b4c34c))
31+
32+
33+
## v4.10.1 (2026-02-02)
34+
35+
### Bug Fixes
36+
37+
- Fix typo in B01_Q10_DP constant from REQUETDPS to REQUEST_DPS
38+
([#762](https://github.com/Python-roborock/python-roborock/pull/762),
39+
[`601a402`](https://github.com/Python-roborock/python-roborock/commit/601a4029fa975f43b6a04bfcd863dc2c8bd8b8ae))
40+
41+
- Fix typos in code mappings for Roborock
42+
([#762](https://github.com/Python-roborock/python-roborock/pull/762),
43+
[`601a402`](https://github.com/Python-roborock/python-roborock/commit/601a4029fa975f43b6a04bfcd863dc2c8bd8b8ae))
44+
45+
- Rename FUN_LEVEL to FAN_LEVEL in code mappings
46+
([#762](https://github.com/Python-roborock/python-roborock/pull/762),
47+
[`601a402`](https://github.com/Python-roborock/python-roborock/commit/601a4029fa975f43b6a04bfcd863dc2c8bd8b8ae))
48+
49+
- Typos in code mappings for Q10
50+
([#762](https://github.com/Python-roborock/python-roborock/pull/762),
51+
[`601a402`](https://github.com/Python-roborock/python-roborock/commit/601a4029fa975f43b6a04bfcd863dc2c8bd8b8ae))
52+
53+
### Chores
54+
55+
- Set typing for from_code_optional to use Self
56+
([#761](https://github.com/Python-roborock/python-roborock/pull/761),
57+
[`220ae8b`](https://github.com/Python-roborock/python-roborock/commit/220ae8bfc8b53d2e5070dc6c5211ef9b23df606d))
58+
59+
### Documentation
60+
61+
- Add comments documenting source code typos in B01_Q10_DP mappings
62+
([#762](https://github.com/Python-roborock/python-roborock/pull/762),
63+
[`601a402`](https://github.com/Python-roborock/python-roborock/commit/601a4029fa975f43b6a04bfcd863dc2c8bd8b8ae))
64+
65+
566
## v4.10.0 (2026-02-01)
667

768
### Features

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "python-roborock"
3-
version = "4.10.0"
3+
version = "4.12.0"
44
description = "A package to control Roborock vacuums."
55
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
66
requires-python = ">=3.11, <4"

roborock/data/b01_q10/b01_q10_code_mappings.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class B01_Q10_DP(RoborockModeEnum):
3434
DUST_SETTING = ("dpDustSetting", 50)
3535
MAP_SAVE_SWITCH = ("dpMapSaveSwitch", 51)
3636
CLEAN_RECORD = ("dpCleanRecord", 52)
37-
RECEND_CLEAN_RECORD = ("dpRecendCleanRecord", 53)
37+
RECENT_CLEAN_RECORD = ("dpRecentCleanRecord", 53) # NOTE: typo "dpRecendCleanRecord" in source code
3838
RESTRICTED_ZONE = ("dpRestrictedZone", 54)
3939
RESTRICTED_ZONE_UP = ("dpRestrictedZoneUp", 55)
4040
VIRTUAL_WALL = ("dpVirtualWall", 56)
@@ -56,7 +56,7 @@ class B01_Q10_DP(RoborockModeEnum):
5656
ROOM_MERGE = ("dpRoomMerge", 72)
5757
ROOM_SPLIT = ("dpRoomSplit", 73)
5858
RESET_ROOM_NAME = ("dpResetRoomName", 74)
59-
REQUSET_NOT_DISTURB_DATA = ("dpRequsetNotDisturbData", 75)
59+
REQUEST_NOT_DISTURB_DATA = ("dpRequestNotDisturbData", 75) # NOTE: typo "dpRequsetNotDisturbData" in source code
6060
CARPET_CLEAN_TYPE = ("dpCarpetCleanType", 76)
6161
BUTTON_LIGHT_SWITCH = ("dpButtonLightSwitch", 77)
6262
CLEAN_LINE = ("dpCleanLine", 78)
@@ -68,7 +68,7 @@ class B01_Q10_DP(RoborockModeEnum):
6868
LOG_SWITCH = ("dpLogSwitch", 84)
6969
FLOOR_MATERIAL = ("dpFloorMaterial", 85)
7070
LINE_LASER_OBSTACLE_AVOIDANCE = ("dpLineLaserObstacleAvoidance", 86)
71-
CLEAN_PROGESS = ("dpCleanProgess", 87)
71+
CLEAN_PROGRESS = ("dpCleanProgress", 87) # NOTE: typo "dpCleanProgess" in source code
7272
GROUND_CLEAN = ("dpGroundClean", 88)
7373
IGNORE_OBSTACLE = ("dpIgnoreObstacle", 89)
7474
FAULT = ("dpFault", 90)
@@ -84,7 +84,7 @@ class B01_Q10_DP(RoborockModeEnum):
8484
SUSPECTED_THRESHOLD_UP = ("dpSuspectedThresholdUp", 100)
8585
COMMON = ("dpCommon", 101)
8686
JUMP_SCAN = ("dpJumpScan", 101)
87-
REQUETDPS = ("dpRequetdps", 102) # NOTE: THIS TYPO IS FOUND IN SOURCE CODE
87+
REQUEST_DPS = ("dpRequestDps", 102) # NOTE: typo "dpRequetdps" in source code
8888
CLIFF_RESTRICTED_AREA = ("dpCliffRestrictedArea", 102)
8989
CLIFF_RESTRICTED_AREA_UP = ("dpCliffRestrictedAreaUp", 103)
9090
BREAKPOINT_CLEAN = ("dpBreakpointClean", 104)
@@ -96,7 +96,7 @@ class B01_Q10_DP(RoborockModeEnum):
9696
HEARTBEAT = ("dpHeartbeat", 110)
9797
STATUS = ("dpStatus", 121)
9898
BATTERY = ("dpBattery", 122)
99-
FUN_LEVEL = ("dpfunLevel", 123)
99+
FAN_LEVEL = ("dpFanLevel", 123) # NOTE: typo "dpfunLevel" in source code
100100
WATER_LEVEL = ("dpWaterLevel", 124)
101101
MAIN_BRUSH_LIFE = ("dpMainBrushLife", 125)
102102
SIDE_BRUSH_LIFE = ("dpSideBrushLife", 126)
@@ -125,8 +125,7 @@ class YXFanLevel(RoborockModeEnum):
125125
NORMAL = "normal", 2
126126
STRONG = "strong", 3
127127
MAX = "max", 4
128-
SUPER = "super", 5
129-
CUSTOM = "custom", 8
128+
SUPER = "super", 8
130129

131130

132131
class YXWaterLevel(RoborockModeEnum):

roborock/data/b01_q7/b01_q7_code_mappings.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,15 @@ class CleanTypeMapping(RoborockModeEnum):
4646
class CleanRepeatMapping(RoborockModeEnum):
4747
"""Maps the cleaning repeat parameter."""
4848

49-
ONCE = ("once", 0)
50-
TWICE = ("twice", 1)
49+
ONE = ("one", 0)
50+
TWO = ("two", 1)
51+
52+
53+
class CleanPathPreferenceMapping(RoborockModeEnum):
54+
"""Maps the cleaning path preference parameter."""
55+
56+
BALANCED = ("balanced", 0)
57+
DEEP = ("deep", 1)
5158

5259

5360
class SCDeviceCleanParam(RoborockModeEnum):

roborock/data/b01_q7/b01_q7_containers.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from ..containers import RoborockBase
88
from .b01_q7_code_mappings import (
99
B01Fault,
10+
CleanPathPreferenceMapping,
11+
CleanRepeatMapping,
1012
CleanTypeMapping,
1113
SCWindMapping,
1214
WaterLevelMapping,
@@ -94,10 +96,10 @@ class B01Props(RoborockBase):
9496
mop_life: int | None = None
9597
main_sensor: int | None = None
9698
net_status: NetStatus | None = None
97-
repeat_state: int | None = None
99+
repeat_state: CleanRepeatMapping | None = None
98100
tank_state: int | None = None
99101
sweep_type: int | None = None
100-
clean_path_preference: int | None = None
102+
clean_path_preference: CleanPathPreferenceMapping | None = None
101103
cloth_state: int | None = None
102104
time_zone: int | None = None
103105
time_zone_info: str | None = None
@@ -210,6 +212,16 @@ def work_mode_name(self) -> str | None:
210212
"""Returns the name of the current work mode."""
211213
return self.work_mode.value if self.work_mode is not None else None
212214

215+
@property
216+
def repeat_state_name(self) -> str | None:
217+
"""Returns the name of the current repeat state."""
218+
return self.repeat_state.value if self.repeat_state is not None else None
219+
220+
@property
221+
def clean_path_preference_name(self) -> str | None:
222+
"""Returns the name of the current clean path preference."""
223+
return self.clean_path_preference.value if self.clean_path_preference is not None else None
224+
213225

214226
@dataclass
215227
class CleanRecordDetail(RoborockBase):

roborock/devices/traits/b01/q7/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
from roborock import B01Props
77
from roborock.data.b01_q7.b01_q7_code_mappings import (
8+
CleanPathPreferenceMapping,
9+
CleanRepeatMapping,
810
CleanTaskTypeMapping,
911
CleanTypeMapping,
1012
SCDeviceCleanParam,
@@ -66,6 +68,14 @@ async def set_mode(self, mode: CleanTypeMapping) -> None:
6668
"""Set the cleaning mode (vacuum, mop, or vacuum and mop)."""
6769
await self.set_prop(RoborockB01Props.MODE, mode.code)
6870

71+
async def set_clean_path_preference(self, preference: CleanPathPreferenceMapping) -> None:
72+
"""Set the cleaning path preference (route)."""
73+
await self.set_prop(RoborockB01Props.CLEAN_PATH_PREFERENCE, preference.code)
74+
75+
async def set_repeat_state(self, repeat: CleanRepeatMapping) -> None:
76+
"""Set the cleaning repeat state (cycles)."""
77+
await self.set_prop(RoborockB01Props.REPEAT_STATE, repeat.code)
78+
6979
async def start_clean(self) -> None:
7080
"""Start cleaning."""
7181
await self.send(

roborock/map/map_parser.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ class MapParserConfig:
5151
show_background: bool = True
5252
"""Whether to show the background of the map."""
5353

54+
show_walls: bool = True
55+
"""Whether to show the walls of the map."""
56+
57+
show_rooms: bool = True
58+
"""Whether to show the rooms of the map."""
59+
5460
map_scale: int = DEFAULT_MAP_SCALE
5561
"""Scale factor for the map."""
5662

@@ -94,11 +100,22 @@ def parse(self, map_bytes: bytes) -> ParsedMapData | None:
94100

95101
def _create_map_data_parser(config: MapParserConfig) -> RoborockMapDataParser:
96102
"""Create a RoborockMapDataParser based on the config entry."""
97-
colors = ColorsPalette()
103+
color_dicts = {}
104+
room_colors = {}
105+
98106
if not config.show_background:
99-
colors = ColorsPalette({SupportedColor.MAP_OUTSIDE: (0, 0, 0, 0)})
107+
color_dicts[SupportedColor.MAP_OUTSIDE] = (0, 0, 0, 0)
108+
109+
if not config.show_walls:
110+
color_dicts[SupportedColor.GREY_WALL] = (0, 0, 0, 0)
111+
color_dicts[SupportedColor.MAP_WALL] = (0, 0, 0, 0)
112+
color_dicts[SupportedColor.MAP_WALL_V2] = (0, 0, 0, 0)
113+
114+
if not config.show_rooms:
115+
room_colors = {str(x): (0, 0, 0, 0) for x in range(1, 32)}
116+
100117
return RoborockMapDataParser(
101-
colors,
118+
ColorsPalette(color_dicts, room_colors),
102119
Sizes({k: v * config.map_scale for k, v in Sizes.SIZES.items() if k != Size.MOP_PATH_WIDTH}),
103120
config.drawables,
104121
ImageConfig(scale=config.map_scale),

tests/data/b01_q7/test_b01_q7_containers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
from roborock.data.b01_q7 import (
66
B01Fault,
77
B01Props,
8+
CleanPathPreferenceMapping,
89
CleanRecordDetail,
910
CleanRecordList,
11+
CleanRepeatMapping,
1012
SCWindMapping,
1113
WorkStatusMapping,
1214
)
@@ -106,6 +108,10 @@ def test_b01props_deserialization():
106108
assert deserialized.wind == SCWindMapping.STRONG
107109
assert deserialized.net_status is not None
108110
assert deserialized.net_status.ip == "192.168.1.102"
111+
assert deserialized.repeat_state == CleanRepeatMapping.TWO
112+
assert deserialized.clean_path_preference == CleanPathPreferenceMapping.DEEP
113+
assert deserialized.repeat_state_name == "two"
114+
assert deserialized.clean_path_preference_name == "deep"
109115

110116

111117
def test_b01_q7_clean_record_list_parses_detail_fields():

tests/e2e/test_device_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ async def test_q10_device(
439439
# against the golden byte stream snapshot.
440440
assert device.b01_q10_properties
441441
command = device.b01_q10_properties.command
442-
await command.send(B01_Q10_DP.REQUETDPS, params={})
442+
await command.send(B01_Q10_DP.REQUEST_DPS, params={})
443443

444444
# In the future here we can verify receiving requests from the device
445445

tests/protocols/__snapshots__/test_b01_q10_protocol.ambr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"dpStatus": 8,
1313
"dpBattery": 100,
14-
"dpfunLevel": 2,
14+
"dpFanLevel": 2,
1515
"dpWaterLevel": 1,
1616
"dpMainBrushLife": 0,
1717
"dpSideBrushLife": 0,
@@ -35,7 +35,7 @@
3535
"dpChildLock": 0,
3636
"dpDustSetting": 0,
3737
"dpMapSaveSwitch": true,
38-
"dpRecendCleanRecord": false,
38+
"dpRecentCleanRecord": false,
3939
"dpCleanTime": 0,
4040
"dpMultiMapSwitch": 1,
4141
"dpSensorLife": 0,
@@ -55,7 +55,7 @@
5555
},
5656
"dpRobotType": 1,
5757
"dpLineLaserObstacleAvoidance": 1,
58-
"dpCleanProgess": 100,
58+
"dpCleanProgress": 100,
5959
"dpGroundClean": 0,
6060
"dpFault": 0,
6161
"dpNotDisturbExpand": {
@@ -77,10 +77,10 @@
7777
}
7878
'''
7979
# ---
80-
# name: test_encode_mqtt_payload[dpRequetdps-None]
80+
# name: test_encode_mqtt_payload[dpRequestDps-None]
8181
b'{"dps": {"102": {}}}'
8282
# ---
83-
# name: test_encode_mqtt_payload[dpRequetdps-params0]
83+
# name: test_encode_mqtt_payload[dpRequestDps-params0]
8484
b'{"dps": {"102": {}}}'
8585
# ---
8686
# name: test_encode_mqtt_payload[dpStartClean-params2]

0 commit comments

Comments
 (0)