feat: Add initial Q10 support for Status Trait#769
feat: Add initial Q10 support for Status Trait#769allenporter merged 7 commits intoPython-roborock:mainfrom
Conversation
For now there is a central refresh mechanism for all traits which can be revisited in the future. The properties API listens for updates and fans them out to traits, which listen for apporopriate DPS values they are responsible for. This adds a way to map dps values to dataclass fields, and reuses the exisitng Roborock base data for parsing updates.
For now there is a central refresh mechanism for all traits which can be revisited in the future. The properties API listens for updates and fans them out to traits, which listen for apporopriate DPS values they are responsible for. This adds a way to map dps values to dataclass fields, and reuses the exisitng Roborock base data for parsing updates.
…rock into q10-status-trait
There was a problem hiding this comment.
Pull request overview
This PR adds initial support for the Status trait in Q10 B01 devices, implementing a streaming-based architecture for property updates. The implementation follows a trait-based pattern where device Data Points (DPS) are mapped to dataclass fields using metadata annotations, and a central subscription loop distributes updates to individual traits.
Changes:
- Added StatusTrait for Q10 devices with support for battery, status, fan level, water level, cleaning mode, and other status fields
- Implemented a streaming architecture using subscribe_stream() method for processing continuous device messages
- Refactored RoborockBase.convert_dict() into a reusable static method to support trait updates
- Added DpsDataConverter utility for mapping DPS values to dataclass fields using metadata annotations
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/devices/traits/b01/q10/test_status.py | Comprehensive tests for StatusTrait streaming updates and refresh functionality |
| roborock/devices/transport/mqtt_channel.py | Added subscribe_stream() async generator for consuming message streams |
| roborock/devices/traits/b01/q10/status.py | StatusTrait implementation wrapping Q10Status dataclass |
| roborock/devices/traits/b01/q10/common.py | DpsDataConverter utility for mapping DPS to dataclass fields |
| roborock/devices/traits/b01/q10/init.py | Q10PropertiesApi with lifecycle management and subscription loop |
| roborock/devices/rpc/b01_q10_channel.py | stream_decoded_responses() generator for decoded DPS messages |
| roborock/devices/device.py | Integration of Q10 properties lifecycle in device connect/close |
| roborock/data/containers.py | Refactored convert_dict() as reusable static method |
| roborock/data/b01_q10/b01_q10_containers.py | Q10Status dataclass with DPS metadata annotations |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Lash-L
left a comment
There was a problem hiding this comment.
Looks awesome - just a few small comments. most are not actionable
| data: str | ||
|
|
||
|
|
||
| @dataclass |
There was a problem hiding this comment.
Not needed here - but I wonder if there is a way we can avoid having to do dataclass. Pydantic base models don't, but we do which is odd
| @classmethod | ||
| def from_dataclass(cls, dataclass_type: type[RoborockBase]): | ||
| """Initialize the converter for a specific RoborockBase-derived class.""" | ||
| dps_type_map: dict[B01_Q10_DP, type] = {} |
There was a problem hiding this comment.
Nothing wrong here - just stylistically(the naming), B01_Q10_DP feels off. I think it was me who originally added it, but maybe we should change as a follow up
There was a problem hiding this comment.
I think just like DataPoint could work given its in a module, but yeah, happy to address in a followup.
allenporter
left a comment
There was a problem hiding this comment.
Addressed feedback
|
Lgtm - thanks great approach |
For now there is a central refresh mechanism for all traits which can be revisited in the future. The properties API listens for updates and fans them out to traits, which listen for apporopriate DPS values they are responsible for. This adds a way to map dps values to dataclass fields, and reuses the exisitng Roborock base data for parsing updates. Comments have been added to the code base to describe how additional traits can be added following this pattern.
This is modeled after the ideas we explored in #709 and #692 but has been even further simplified.
issue #767