feat: live Q7 (B01) map updates from unsolicited map pushes - #912
Open
andig wants to merge 1 commit into
Open
Conversation
andig
force-pushed
the
feat/q7-live-map-push
branch
from
August 4, 2026 10:34
05bcb82 to
06c7845
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds support for Roborock Q7 (B01 / sc-class) devices to keep map rendering up-to-date by subscribing to unsolicited protocol-301 MAP_RESPONSE pushes and flowing those frames into the Q7 MapContentTrait cache + update listeners for the lifetime of a connected device.
Changes:
- Add
Q7MapRpcChannel.subscribe_map_pushes()and wire it intoB01Q7Channelto decode pushedMAP_RESPONSEframes. - Extend Q7
MapContentTraitwithupdate_from_push()+ listener notifications to update cached map/image from pushed frames. - Start/stop Q7 map-push subscription via
Q7PropertiesApi.start()/close()and hook those intoRoborockDevice.connect()/close(), with tests covering push updates and parse-failure behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/devices/traits/b01/q7/test_map_content.py | Adds unit tests for push-driven map cache updates and parse-failure behavior. |
| tests/devices/traits/b01/q7/conftest.py | Extends FakeQ7Channel with a subscribe_map_pushes() test hook. |
| roborock/devices/traits/b01/q7/map_content.py | Adds push update handling, caching, and update listener notifications for Q7 map content. |
| roborock/devices/traits/b01/q7/init.py | Adds start()/close() lifecycle methods to manage the map-push subscription. |
| roborock/devices/rpc/b01_q7_channel.py | Introduces subscribe_map_pushes() to decode unsolicited MAP_RESPONSE frames via the map key. |
| roborock/devices/device.py | Wires Q7 properties start()/close() into device connect/close lifecycle. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Q7 devices stream full SCMap frames (protocol 301) on their own during cleaning — no polling or request is needed. Verified against a live Q7 Series (roborock.vacuum.sc05): a short clean produced a pushed frame roughly every 10 seconds. - B01Q7Channel.subscribe_map_pushes() decodes unsolicited MAP_RESPONSE frames with the device map key. - MapContentTrait.update_from_push() re-parses pushed frames and notifies update listeners; malformed frames are dropped without clearing the cached map. - Q7PropertiesApi.start()/close() subscribe for the device lifetime, wired up in RoborockDevice.connect()/close() like V1 and Q10. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
andig
force-pushed
the
feat/q7-live-map-push
branch
from
August 4, 2026 10:41
06c7845 to
2584105
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Q7 (B01) devices stream full SCMap frames (protocol 301
MAP_RESPONSE) on their own during cleaning — no polling, request or heartbeat needed. This wires those pushes intoMapContentTraitso the rendered map stays current for the device lifetime.Relevant to #827: the DP-110 heartbeat discussion there applies to Q10/ss-class devices. Verified from a plain MQTT subscription that sc-class Q7s (
roborock.vacuum.sc05, fw 03.01.80) push a ~25 KBmapType: 0frame roughly every 10 s during a clean (alongsideprop.postDPS updates), so Q7 needs no heartbeat at all. Also the Q7 side of #739.Changes
B01Q7Channel.subscribe_map_pushes(): decodes unsolicitedMAP_RESPONSEframes with the device map key; undecodable frames are logged and skipped.MapContentTrait.update_from_push(): re-parses pushed frames, updates the cached image/map data and notifies update listeners (TraitUpdateListener); malformed frames are dropped without clearing the cached map.Q7PropertiesApi.start()/close(): subscribe for the device lifetime, wired intoRoborockDevice.connect()/close()like V1 and Q10.Validation
ruff check/formatclean.sc05: a 45 s clean delivered 4 pushed frames through the new path, with the robot pose moving across frames and returning to the dock.Independent of (but designed together with) the companion map-geometry PR #911 — with both, the pushed frames carry live robot pose and path, giving a live map without polling.
🤖 Generated with Claude Code