Skip to content

feat: add Q10 map management controls - #934

Merged
allenporter merged 2 commits into
Python-roborock:mainfrom
hCoureau:feat/q10-map-controls
Nov 8, 2026
Merged

allenporter merged 2 commits into
Python-roborock:mainfrom
hCoureau:feat/q10-map-controls

Conversation

@hCoureau

@hCoureau hCoureau commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Add typed Q10 map restrictions and virtual walls in common Roborock coordinates, complete-collection replacement setters, room rename and saved-map apply. Device pushes remain authoritative; commands do not optimistically update the read models.

Restriction types use RoborockEnum with an unknown fallback. Writes reject unsupported types and validate geometry, coordinate ranges, collection sizes and room-name UTF-8 lengths. Replacement writes do not require a prior restriction snapshot.

Validation

  • Full pytest suites on Python 3.11 and 3.14: 2,080 passed, 53 xfailed on each. The repository’s default configuration excludes 11 MQTT-broker tests.
  • Focused suites: 109 passed.
  • All pre-commit checks and wheel/source distribution builds passed.

Rebuilt independently on upstream main (8e471dc, 7.15.2), without cumulative feature dependencies. No physical-device validation was run for this revision. Related: #767.

@hCoureau

Copy link
Copy Markdown
Contributor Author

On hold following the review feedback on #933: please do not review the current cumulative diff.

Once the read-only map stack lands, this draft will be rebased and repartitioned into focused changes:

  1. common-coordinate points plus typed/read-only restriction and wall models
  2. restricted-zone and virtual-wall encoders/replacement setters
  3. room rename and saved-map apply controls

Each part will be submitted sequentially against main, with its own focused tests and reviewer guide.

@lboue

lboue commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

@hCoureau This branch has conflicts that must be resolved.

@hCoureau
hCoureau marked this pull request as ready for review September 8, 2026 06:31
@hCoureau

hCoureau commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Resolved the merge conflicts with current main in 24002af by merging main and retaining its accepted 30-second Q10 CLI map-push timeout. The map-management changes are preserved. GitHub now reports this PR as conflict-free, and I marked it ready for review.

Validation: 1,150 tests passed, 92 snapshots passed, all pre-commit hooks passed, and sdist/wheel builds passed. GitHub CI was triggered for the new head. Required maintainer approval still applies.

#933 has already merged. This branch still contains the stacked Q10 archive/obstacle/current-room work, which remains visible for maintainer review. Conflict resolution and validation performed with OpenAI Codex assistance.

@lboue

lboue commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

@allenporter PR #934 has been conflict-free since Sep 10, and everything checks out:

  • 1,150 tests ✅
  • Physical device validation ✅
  • Pre-commit checks ✅
  • Conflicts resolved ✅

Ready for your review and merge approval when you get to it.

@umutbozdag

umutbozdag commented Oct 1, 2026 •

Copy link
Copy Markdown

Physical-device validation of the restriction/wall write path, on an ss07
(roborock.vacuum.ss07, sold locally as "Roborock S8 Pro", label RRA0TAL),
firmware 03.13.00, python-roborock 7.12.0:

  • Restricted zones: a DP 55-format blob sent bare as {"dps": {"54": "<b64>"}}
    is silently ignored (no DP 55 push, no change in the app). Wrapped in dpCommon as
    {"dps": {"101": {"54": "<b64>"}}} it is applied: the robot echoes it on DP 55
    within ~1 s and the app shows the change. This matches the COMMON wrapping in
    set_restricted_zones.
  • Virtual walls: same behaviour, {"101": {"56": "<b64>"}} is applied and echoed on DP 57.
  • Encoding: 38-byte zone records with version byte 1; AQA= / AA== for empty lists.
    Re-encoding the device's own DP 55/57 reports is byte-identical.
  • A new no-mop zone (type 2) written from scratch was accepted, echoed and rendered.
  • Re-sending an unchanged blob produced no DP 55/57 push.

Not tested: room rename, saved-map apply. Happy to run this branch itself on
the device if that helps.

Update: also exercised add and delete from a client through the same dpCommon
path. Adding a second no-mop zone, then removing it and the only virtual wall
(DP 56 written as AA==) were each echoed on DP 55/57, and the official app
showed every change.

@allenporter allenporter left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Conducting this code review following our /review skill using Antigravity (AGY) and Gemini 4 Argon.

The wire encoding for DP 54 (restricted zones), DP 56 (virtual walls), DP 58 (room rename), and DP 61 (apply) looks well-verified against device captures.

Main areas to align with our repository conventions:

  1. Public domain models (RoborockBase) and resilient enums (RoborockEnum):

    • Q10RestrictionType should subclass RoborockEnum with unknown = -1 (rather than IntEnum) so unknown wire codes fall back to Q10RestrictionType.unknown instead of catching ValueError and typing Q10RestrictedZone.type as int.
    • Q10RestrictedZone and Q10VirtualWall are public trait models on MapContentTrait and should be @dataclass models subclassing RoborockBase (only Q10RoborockPoint is exempt from RoborockBase for coordinate hashability).
  2. Remove defensive runtime isinstance checks on statically typed parameters:

    • See inline comments in roborock/protocols/b01_q10_protocol.py.
  3. Remove is_replaceable_zone_blob precondition on set_restricted_zones:

    • set_restricted_zones(zones) replaces the complete restricted-zone list on the device without merging existing state, so it shouldn't require self._map_dps.restricted_zone_up to have been received first (matching set_virtual_walls).
  4. Test cleanup:

    • Remove the duplicate test_upstream_* tests in tests/data/b01_q10/test_b01_q10_containers.py and use the fake channel instead of patch.object(q10_api.command, "send") in tests/devices/traits/b01/q10/test_map.py.

Comment thread roborock/map/b01_q10_overlays.py Resolved
Comment thread roborock/devices/traits/b01/q10/map.py Resolved
Comment thread roborock/protocols/b01_q10_protocol.py Resolved
@Lash-L

Lash-L commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

Marking as draft until Allen's comments are handled

@Lash-L
Lash-L marked this pull request as draft October 31, 2026 01:57
@hCoureau
hCoureau force-pushed the feat/q10-map-controls branch from fe0bfaa to 7bfe699 Compare November 7, 2026 19:04
@hCoureau
hCoureau marked this pull request as ready for review November 7, 2026 19:07
allenporter
allenporter previously approved these changes Nov 8, 2026
@allenporter
allenporter merged commit 99e47d2 into Python-roborock:main Nov 8, 2026
9 checks passed
@hCoureau
hCoureau deleted the feat/q10-map-controls branch November 8, 2026 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants