Skip to content

feat: Add initial Q10 support for Status Trait - #769

Merged
allenporter merged 7 commits into
Python-roborock:mainfrom
allenporter:q10-status-trait
Feb 15, 2026
Merged

feat: Add initial Q10 support for Status Trait#769
allenporter merged 7 commits into
Python-roborock:mainfrom
allenporter:q10-status-trait

Conversation

@allenporter

Copy link
Copy Markdown
Contributor

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

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.
CopilotAI review requested due to automatic review settings February 14, 2026 17:45
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.

CopilotAI 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.

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
FileDescription
tests/devices/traits/b01/q10/test_status.pyComprehensive tests for StatusTrait streaming updates and refresh functionality
roborock/devices/transport/mqtt_channel.pyAdded subscribe_stream() async generator for consuming message streams
roborock/devices/traits/b01/q10/status.pyStatusTrait implementation wrapping Q10Status dataclass
roborock/devices/traits/b01/q10/common.pyDpsDataConverter utility for mapping DPS to dataclass fields
roborock/devices/traits/b01/q10/init.pyQ10PropertiesApi with lifecycle management and subscription loop
roborock/devices/rpc/b01_q10_channel.pystream_decoded_responses() generator for decoded DPS messages
roborock/devices/device.pyIntegration of Q10 properties lifecycle in device connect/close
roborock/data/containers.pyRefactored convert_dict() as reusable static method
roborock/data/b01_q10/b01_q10_containers.pyQ10Status dataclass with DPS metadata annotations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadtests/devices/traits/b01/q10/test_status.py Outdated
Comment threadtests/devices/traits/b01/q10/test_status.py Outdated
Comment threadroborock/devices/traits/b01/q10/__init__.py
Comment threadroborock/devices/traits/b01/q10/common.py Outdated
Comment threadroborock/data/b01_q10/b01_q10_containers.py Outdated
Comment threadroborock/devices/traits/b01/q10/status.py Outdated

@Lash-LLash-L left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks awesome - just a few small comments. most are not actionable

data: str


@dataclass

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

Comment threadroborock/devices/rpc/b01_q10_channel.py Outdated
Comment threadroborock/devices/traits/b01/q10/__init__.py Outdated
@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] = {}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I think just like DataPoint could work given its in a module, but yeah, happy to address in a followup.

@allenporterallenporter left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Addressed feedback

@Lash-L

Copy link
Copy Markdown
Collaborator

Lgtm - thanks great approach

@allenporter
allenporter merged commit 38d336b into Python-roborock:mainFeb 15, 2026
7 checks passed
Sign up for freeto 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

@allenporter@Lash-L