Skip to content

feat: add Q10 map management controls - #934

Open
hCoureau wants to merge 47 commits into
Python-roborock:mainfrom
hCoureau:feat/q10-map-controls
Open

hCoureau wants to merge 47 commits into
Python-roborock:mainfrom
hCoureau:feat/q10-map-controls

Conversation

@hCoureau

@hCoureau hCoureau commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Q10 map management needs typed overlay data and commands that preserve the device's authoritative state. This adds read-only restrictions and walls, full-collection replacement setters, room rename, and saved-map apply.

Scope and dependencies

This is a cumulative branch containing the archive, obstacle, and current-room work from #937–#939; archive parser support from #936 is merged. It now uses the composed Q10CleanRecordDetail API and shares the archive lifecycle fixes with those PRs.

After the archive stack lands, the planned partition is:

  1. Typed read-only restriction and virtual-wall models.
  2. Restriction/wall encoders and full-collection replacement setters.
  3. Room rename and saved-map apply controls.

The common-coordinate Q10RoborockPoint, current position, zoned cleaning, and goto support are already upstream through #908. This branch reuses that coordinate convention. #965 is merged. Upstream main through b3a98b9 (7.12.0) is integrated.

Behavior

  • Public overlay models use common Roborock millimetre coordinates; binary packing stays in the B01 protocol layer.
  • Coordinates must align to the 5 mm vector grid and fit signed 16-bit wire values.
  • Restriction and wall writes replace the complete collection. Restriction replacement requires a complete, representable DP 55 snapshot; missing, malformed, or unsupported polygon snapshots are rejected before publishing.
  • Encoders validate geometry, cardinality, coordinate ranges, and collection sizes. Unknown restriction type bytes are preserved.
  • Device pushes remain authoritative. Saved-map apply changes the active map asynchronously; select requests a preview.

Allen’s follow-up feedback on merged #936 is addressed by separate clean-record and saved-map decoder tests, with no conditional assertions.

Validation

Validation of fe0bfaa:

  • uv run pytest -q on Python 3.13: 1,575 passed, 53 xfailed, 92 snapshots passed.
  • All pre-commit hooks passed, including Ruff, mypy, codespell, and structured-file checks.
  • uv build passed for both wheel and sdist.
  • The affected cumulative protocol suite passed on Python 3.11 and 3.14: 96 passed, 10 snapshots passed on each version. The full cumulative suite passed on both versions before this test-only follow-up and merge.

No physical-device run was performed for this revision.

Earlier physical Q10 S5+ validation exercised temporary no-go zones, virtual walls, room rename, and saved-map apply/readback, then restored the original values. A single saved map prevented validation of a cross-map transition. An earlier wheel was also exercised in Home Assistant.

Limitations

Inherited archive requests now have bounded waits and teardown recovery. Clean-history selection remains blocked after an uncertain outcome until the abandoned response is drained, because responses carry no record ID. Room split/merge, map deletion/reset, and map rename are outside this contribution. Customized cleaning controls are tracked in #935.

No credentials, personal room labels, floorplans, or private packet captures are included. Related: #767.

@hCoureau hCoureau mentioned this pull request Aug 31, 2026
8 of 23 tasks
@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.

This branch has not been deployed

No deployments
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.

3 participants