Repository navigation
feat: add Q10 customized cleaning controls #935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
hCoureau
wants to merge
55
commits into
Python-roborock:main
Choose a base branch
from
hCoureau:feat/q10-cleaning-controls
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
8dd3423
fix: keep Q10 map vectors stable during live updates
hCoureau 83d9cc4
feat: add Q10 archived map details
hCoureau fe91ec7
fix: request Q10 maps without starting cleaning
hCoureau 89e2cc3
feat: expose Q10 read-only map archives
hCoureau 8adcbb0
feat: render Q10 map obstacle markers
hCoureau 889a0bc
feat: expose Q10 current cleaning room
hCoureau 417ad58
feat: add Q10 map management controls
hCoureau 59bae34
feat: add Q10 customized cleaning protocol
hCoureau 2fdcc45
feat: control Q10 customized room cleaning
hCoureau b8bdf3a
fix: request Q10 maps without starting cleaning
hCoureau 95d268e
feat: parse Q10 archived map packets
hCoureau eaac141
feat: expose Q10 map archives
hCoureau 2161763
feat: render Q10 map obstacle markers
hCoureau cd2621d
feat: expose Q10 current cleaning room
hCoureau ded170d
chore: merge main and resolve Q10 CLI timeout conflict
hCoureau 24002af
chore: merge main and resolve Q10 CLI timeout conflict
hCoureau 1a4ffde
chore: merge main for Q10 archive review fixes
hCoureau cbd6abc
refactor: give Q10 clean-record maps ownership of historical paths
hCoureau 3f8ec38
fix: integrate Q10 archive review changes and upstream timeout
hCoureau 9a68c0d
fix: integrate Q10 archive review changes into obstacle maps
hCoureau 8293fae
fix: update Q10 current room with reviewed archive stack
hCoureau d2e5d2c
chore: update Q10 map controls with main
hCoureau b290dac
fix: resolve Q10 cleaning control conflicts with upstream
hCoureau 60248c4
fix: assert historical paths are exclusive to clean-record maps
hCoureau 8d52982
fix: update current-room tests for clean-record map types
hCoureau d6979b4
fix: narrow clean-record packet types in obstacle tests
hCoureau bc85283
fix: align current-room tests with clean-record packet types
hCoureau 4eb0b9b
refactor: compose Q10 clean-record details and address parser review
hCoureau 49dfd31
refactor: consume composed Q10 clean-record details
hCoureau 4f1c94d
fix: reconcile Q10 map controls with upstream position support
hCoureau dd92094
refactor: compose archived obstacle maps with historical paths
hCoureau 565c7d0
fix: preserve immutable Q10 points in model conformance checks
hCoureau b74637b
fix: integrate reviewed archive composition into current-room maps
hCoureau f0b1a06
fix: include standalone Q10 point conformance correction
hCoureau ac6d83b
fix: include standalone Q10 point conformance correction
hCoureau d4dbd86
fix: include standalone Q10 point conformance correction
hCoureau db54bd3
fix: include standalone Q10 point conformance correction
hCoureau 5604243
fix: include standalone Q10 point conformance correction
hCoureau e0f7ad7
fix: integrate upstream Q10 actions and snapshot cleaning settings
hCoureau f5abe2a
fix: include standalone Q10 point conformance correction
hCoureau 15f17ca
chore: sort imports after conformance fix integration
hCoureau 7f8846c
chore: sort imports after conformance fix integration
hCoureau 3d3a337
Merge remote-tracking branch 'upstream/main' into fix/pr936-review
hCoureau 9d5d9fe
Merge branch 'fix/pr936-review' into fix/pr937-review
hCoureau 569e6b3
fix: bound Q10 archive selections and preserve response correlation
hCoureau f7dfee3
Merge branch 'fix/pr937-review' into fix/pr938-conflicts
hCoureau 3f49800
Merge branch 'fix/pr938-conflicts' into fix/pr939-review
hCoureau 7a1349e
fix: integrate reviewed Q10 archive lifecycle into map controls
hCoureau 9475398
fix: preserve map validity throughout Q10 room cleaning
hCoureau 9b5e77d
Merge remote-tracking branch 'upstream/main' into fix/pr937-review
hCoureau d6b7c59
test: split Q10 archive decoder cases
hCoureau f157a8c
Merge branch 'fix/pr937-review' into fix/pr938-conflicts
hCoureau 33b5af5
Merge branch 'fix/pr938-conflicts' into fix/pr939-review
hCoureau fe0bfaa
Merge branch 'fix/pr939-review' into fix/pr934-conflicts
hCoureau 6c8075d
Merge branch 'fix/pr934-conflicts' into fix/pr935-review
hCoureau File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,13 @@ | |
| from roborock.data.containers import RoborockBase | ||
| from roborock.devices.rpc.b01_q10_channel import B01Q10Channel | ||
| from roborock.devices.traits import Trait | ||
| from roborock.map.b01_q10_map_parser import Q10MapPacket, Q10TracePacket | ||
| from roborock.map.b01_q10_map_parser import ( | ||
| B01Q10MapParserConfig, | ||
| Q10CleanRecordDetail, | ||
| Q10MapPacket, | ||
| Q10MapPacketKind, | ||
| Q10TracePacket, | ||
| ) | ||
| from roborock.protocols.b01_q10_protocol import Q10DpsUpdate, Q10Message | ||
|
|
||
| from .button_light import ButtonLightTrait | ||
|
|
@@ -22,6 +28,7 @@ | |
| from .maps import MapsTrait | ||
| from .network_info import NetworkInfoTrait | ||
| from .remote import RemoteTrait | ||
| from .room_cleaning import RoomCleaningTrait | ||
| from .status import StatusTrait | ||
| from .vacuum import VacuumTrait | ||
| from .volume import SoundVolumeTrait | ||
|
|
@@ -37,6 +44,7 @@ | |
| "MapContentTrait", | ||
| "MapsTrait", | ||
| "NetworkInfoTrait", | ||
| "RoomCleaningTrait", | ||
| "SoundVolumeTrait", | ||
| "StatusTrait", | ||
| ] | ||
|
|
@@ -59,6 +67,9 @@ class Q10PropertiesApi(Trait): | |
| remote: RemoteTrait | ||
| """Trait for sending remote control related commands to Q10 devices.""" | ||
|
|
||
| room_cleaning: RoomCleaningTrait | ||
| """Trait for customized per-room cleaning settings and commands.""" | ||
|
|
||
| volume: SoundVolumeTrait | ||
| """Trait for reading / setting the speaker volume.""" | ||
|
|
||
|
|
@@ -92,11 +103,19 @@ class Q10PropertiesApi(Trait): | |
| clean_history: CleanHistoryTrait | ||
| """Trait for fetching the device clean-record history (``dpCleanRecord``).""" | ||
|
|
||
| def __init__(self, channel: B01Q10Channel) -> None: | ||
| def __init__( | ||
| self, | ||
| channel: B01Q10Channel, | ||
| *, | ||
| model: str | None = None, | ||
| map_parser_config: B01Q10MapParserConfig, | ||
| ) -> None: | ||
| """Initialize the B01Props API.""" | ||
| self._channel = channel | ||
| self.command = CommandTrait(channel) | ||
| advanced_cleaning_supported = model is None or model == "roborock.vacuum.ss07" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove |
||
| self.remote = RemoteTrait(self.command) | ||
| self.room_cleaning = RoomCleaningTrait(self.command, supported=advanced_cleaning_supported) | ||
| self.status = StatusTrait() | ||
| self.volume = SoundVolumeTrait(self.command) | ||
| self.child_lock = ChildLockTrait(self.command) | ||
|
|
@@ -106,10 +125,23 @@ def __init__(self, channel: B01Q10Channel) -> None: | |
| self.network_info = NetworkInfoTrait() | ||
| self.consumable = ConsumableTrait() | ||
| self._map_dps = MapDpsTrait() | ||
| self.maps = MapsTrait(self.command) | ||
| self.map = MapContentTrait(self._map_dps, self.maps, self.command) | ||
| self.vacuum = VacuumTrait(self.command, self.status, self.map) | ||
| self.clean_history = CleanHistoryTrait(self.command) | ||
| self.maps = MapsTrait( | ||
| self.command, | ||
| map_parser_config=map_parser_config, | ||
| map_changed_callback=self.room_cleaning.invalidate, | ||
| ) | ||
| self.map = MapContentTrait( | ||
| self._map_dps, | ||
| self.command, | ||
| map_parser_config=map_parser_config, | ||
| ) | ||
| self.clean_history = CleanHistoryTrait( | ||
| self.command, | ||
| map_parser_config=map_parser_config, | ||
| ) | ||
| self.vacuum = VacuumTrait( | ||
| self.command, self.status, self.map, advanced_cleaning_supported=advanced_cleaning_supported | ||
| ) | ||
| # Read-model traits updated from the device's DPS push stream. | ||
| self._updatable_traits = [ | ||
| self.status, | ||
|
|
@@ -122,6 +154,7 @@ def __init__(self, channel: B01Q10Channel) -> None: | |
| self.clean_history, | ||
| self._map_dps, | ||
| self.maps, | ||
| self.room_cleaning, | ||
| ] | ||
| self._subscribe_task: asyncio.Task[None] | None = None | ||
|
|
||
|
|
@@ -131,6 +164,9 @@ async def start(self) -> None: | |
|
|
||
| async def close(self) -> None: | ||
| """Close any resources held by the trait.""" | ||
| self.room_cleaning.close() | ||
| self.maps.close() | ||
| self.clean_history.close() | ||
| await self.vacuum.close() | ||
| if self._subscribe_task is not None: | ||
| self._subscribe_task.cancel() | ||
|
|
@@ -143,7 +179,8 @@ async def close(self) -> None: | |
| async def refresh(self) -> None: | ||
| """Refresh all traits.""" | ||
| # Sending REQUEST_DPS causes the device to publish its ordinary status | ||
| # values. Map-list and map-content refreshes have separate schedules. | ||
| # values. Map, map-list, and customized-room settings have separate | ||
| # refresh methods so callers can schedule those larger responses. | ||
| await self.command.send(B01_Q10_DP.REQUEST_DPS, params={}) | ||
|
|
||
| async def _subscribe_loop(self) -> None: | ||
|
|
@@ -158,7 +195,12 @@ def _handle_message(self, message: Q10Message) -> None: | |
| Map-list DPS responses and other DPS updates feed the read-model traits. | ||
| """ | ||
| if isinstance(message, Q10MapPacket): | ||
| self.map.update_from_map_packet(message) | ||
| if message.kind is Q10MapPacketKind.CURRENT: | ||
| self.map.update_from_map_packet(message) | ||
| elif message.kind is Q10MapPacketKind.SAVED_MAP_DETAIL: | ||
| self.maps.update_from_map_packet(message) | ||
| elif isinstance(message, Q10CleanRecordDetail): | ||
| self.clean_history.update_from_detail(message) | ||
| elif isinstance(message, Q10TracePacket): | ||
| self.map.update_from_trace_packet(message) | ||
| elif isinstance(message, Q10DpsUpdate): | ||
|
|
@@ -179,6 +221,15 @@ def as_dict(self) -> dict[str, Any]: | |
| return result | ||
|
|
||
|
|
||
| def create(channel: B01Q10Channel) -> Q10PropertiesApi: | ||
| def create( | ||
| channel: B01Q10Channel, | ||
| *, | ||
| model: str | None = None, | ||
| map_parser_config: B01Q10MapParserConfig | None = None, | ||
| ) -> Q10PropertiesApi: | ||
| """Create traits for B01 devices.""" | ||
| return Q10PropertiesApi(channel) | ||
| return Q10PropertiesApi( | ||
| channel, | ||
| model=model, | ||
| map_parser_config=map_parser_config or B01Q10MapParserConfig(), | ||
| ) | ||
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
UNKNOWN = "unknown", -1toYXCleanLineand map unknown wire codes to.UNKNOWNindecode_room_clean_settingsso we only need a singleQ10RoomCleanSettings(RoborockBase)model with concrete enum types (instead of a secondQ10ReportedRoomCleanSettingsclass with| intunions).