Skip to content

Commit 614ae21

Browse files
committed
improve zone handling
1 parent 3f15d12 commit 614ae21

2 files changed

Lines changed: 21 additions & 64 deletions

File tree

src/roborock_local_server/bundled_backend/shared/routine_runner.py

Lines changed: 18 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -251,55 +251,29 @@ def _segment_ids(entry: dict[str, Any]) -> list[int]:
251251
return segment_ids
252252

253253

254-
def _zone_ids(entry: dict[str, Any]) -> list[dict[str, int]]:
254+
def _zone_coord_params(entry: dict[str, Any]) -> list[list[int]]:
255+
"""Build raw coordinate params for app_zoned_clean: [[x1,y1,x2,y2,repeat], ...]."""
255256
raw_zones = entry.get("zones")
256257
if not isinstance(raw_zones, list) or not raw_zones:
257258
raise RoutineExecutionError("Scene zone step is missing zones[]")
258-
zones: list[dict[str, int]] = []
259-
for raw_zone in raw_zones:
260-
if not isinstance(raw_zone, dict):
261-
raise RoutineExecutionError("Scene zone entry is not an object")
262-
zone_id = _as_int(raw_zone.get("zid"), 0)
263-
if zone_id < 0:
264-
raise RoutineExecutionError("Scene zone entry has invalid zid")
265-
zones.append(
266-
{
267-
"zid": zone_id,
268-
"repeat": max(1, _as_int(raw_zone.get("repeat"), 1)),
269-
}
270-
)
271-
return zones
272-
273-
274-
def _scene_zone_sync_command(entry: dict[str, Any]) -> RoutineCommand | None:
275-
tid = str(entry.get("tid") or "").strip()
276-
if not tid:
277-
return None
278-
raw_zones = entry.get("zones")
279-
if not isinstance(raw_zones, list) or not raw_zones:
280-
return None
281-
zones_with_ranges: list[dict[str, Any]] = []
259+
coords: list[list[int]] = []
282260
for raw_zone in raw_zones:
283261
if not isinstance(raw_zone, dict):
284262
raise RoutineExecutionError("Scene zone entry is not an object")
285263
range_value = raw_zone.get("range")
286264
if not isinstance(range_value, list) or len(range_value) < 4:
287-
continue
288-
zone_id = _as_int(raw_zone.get("zid"), 0)
289-
if zone_id < 0:
290-
raise RoutineExecutionError("Scene zone entry has invalid zid")
291-
zones_with_ranges.append(
292-
{
293-
"zid": zone_id,
294-
"range": [_as_int(value, 0) for value in range_value[:4]],
295-
}
296-
)
297-
if not zones_with_ranges:
298-
return None
299-
return RoutineCommand(
300-
RoborockCommand.SET_SCENES_ZONES,
301-
{"data": [{"tid": tid, "zones": zones_with_ranges}]},
302-
)
265+
raise RoutineExecutionError(
266+
f"Scene zone zid={raw_zone.get('zid')} is missing range coordinates"
267+
)
268+
repeat = max(1, _as_int(raw_zone.get("repeat"), 1))
269+
coords.append([
270+
_as_int(range_value[0], 0),
271+
_as_int(range_value[1], 0),
272+
_as_int(range_value[2], 0),
273+
_as_int(range_value[3], 0),
274+
repeat,
275+
])
276+
return coords
303277

304278

305279
def _single_data_entry(step: RoutineStep) -> dict[str, Any]:
@@ -371,19 +345,12 @@ def commands_for_step(step: RoutineStep) -> list[RoutineCommand]:
371345
]
372346
if step.method == "do_scenes_zones":
373347
entry = _single_data_entry(step)
374-
repeat = max(1, _as_int(entry.get("repeat"), 1))
375-
sync_command = _scene_zone_sync_command(entry)
376-
if sync_command is None:
377-
raise RoutineExecutionError(
378-
f"Zone step {step.step_id} is missing range coordinates for tid={entry.get('tid')!r}; "
379-
"cannot execute zone cleaning without SET_SCENES_ZONES sync data"
380-
)
348+
zone_coords = _zone_coord_params(entry)
381349
return [
382350
*_settings_commands(entry),
383-
sync_command,
384351
RoutineCommand(
385352
RoborockCommand.APP_ZONED_CLEAN,
386-
[{"zones": _zone_ids(entry), "repeat": repeat}],
353+
zone_coords,
387354
),
388355
]
389356
if step.method == "do_scenes_app_start":
@@ -619,7 +586,7 @@ async def wait_for_step_complete(self) -> None:
619586

620587
if not is_ready:
621588
saw_activity = True
622-
if sent_resume and state != 8:
589+
if sent_resume and state not in (8, 23, 26):
623590
sent_resume = False
624591
elif saw_cleaning:
625592
return
@@ -941,14 +908,6 @@ async def _run_scene(self, *, scene: dict[str, Any], steps: list[RoutineStep]) -
941908
routine_command.command.value,
942909
exc,
943910
)
944-
else:
945-
if (
946-
routine_command.command == RoborockCommand.SET_SCENES_ZONES
947-
and self._context.zone_ranges_store is not None
948-
):
949-
self._context.zone_ranges_store.merge_set_scenes_zones_request(
950-
routine_command.params,
951-
)
952911
if waits_for_step_complete:
953912
logger.info("Waiting for ready state step=%s scene=%s", step.step_id, _scene_name(scene))
954913
await client.wait_for_step_complete()

tests/test_routine_runner.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,8 @@ async def wait_for_step_complete(self) -> None:
253253
)
254254
assert sent_commands[1] == (RoborockCommand.SET_CUSTOM_MODE, [108])
255255
assert sent_commands[2] == (
256-
RoborockCommand.SET_SCENES_ZONES,
257-
{"data": [{"tid": "1773791700088", "zones": [{"zid": 8, "range": [32800, 22750, 34550, 25350]}]}]},
258-
)
259-
assert sent_commands[3] == (
260256
RoborockCommand.APP_ZONED_CLEAN,
261-
[{"zones": [{"zid": 8, "repeat": 1}], "repeat": 1}],
257+
[[32800, 22750, 34550, 25350, 1]],
262258
)
263259

264260
asyncio.run(exercise())
@@ -460,3 +456,5 @@ async def exercise() -> None:
460456
assert len(client.sent_commands) == 2
461457

462458
asyncio.run(exercise())
459+
460+

0 commit comments

Comments
 (0)