Skip to content

feat: Add initial Q10 support - #709

Closed
allenporter wants to merge 6 commits into
Python-roborock:mainfrom
allenporter:q10
Closed

feat: Add initial Q10 support#709
allenporter wants to merge 6 commits into
Python-roborock:mainfrom
allenporter:q10

Conversation

@allenporter

Copy link
Copy Markdown
Contributor

Add initial Q10 device support. This device works a bit different than q7 so the protocol and channel are forked.

  • Add CLI support for sending commands
  • Subscribe to messages with basic parsing/printing the debug log, but no capturing state
  • Listen to messages with a message stream and a while loop rather than callbacks (aiomqtt like)
  • Add trait commands for start clean/stop/pause/resume/return to dock/etc.

CopilotAI review requested due to automatic review settings December 27, 2025 05:04

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 Q10 devices using the B01 protocol. The implementation forks the Q7 protocol and channel code to accommodate differences in how Q10 devices handle commands and responses, introduces a message streaming pattern for asynchronous message processing, and provides CLI support for sending commands.

Key Changes

  • Forked B01 protocol implementation into separate Q7 and Q10 modules with distinct message encoding/decoding logic
  • Added streaming message subscription pattern (subscribe_stream) as an alternative to callback-based subscriptions
  • Implemented Q10 trait commands (start/pause/resume/stop clean, return to dock) with basic message processing loop

Reviewed changes

Copilot reviewed 24 out of 27 changed files in this pull request and generated 14 comments.

Show a summary per file
FileDescription
tests/protocols/testdata/b01_protocol/q10/*.jsonTest data files containing sample Q10 protocol messages for different device states
tests/protocols/test_b01_q10_protocol.pyProtocol encoding/decoding tests for Q10 messages
tests/protocols/test_b01_q07_protocol.pyUpdated imports to use refactored Q7-specific protocol module
tests/protocols/snapshots/test_b01_q10_protocol.ambrSnapshot assertions for Q10 protocol message decoding
tests/fixtures/channel_fixtures.pyAdded subscribe_stream method to FakeChannel for testing streaming patterns
tests/devices/traits/b01/q7/test_init.pyUpdated imports to use refactored Q7-specific modules
tests/devices/traits/b01/q10/test_init.pyTests for Q10 trait API (subscription, command sending)
tests/devices/test_mqtt_channel.pyTest for subscribe_stream functionality
tests/data/test_code_mappings.pyTests for new enum helper methods (from_code, from_name, from_value)
roborock/protocols/b01_q7_protocol.pyRefactored Q7 protocol with method-based command encoding
roborock/protocols/b01_q10_protocol.pyNew Q10 protocol with simpler code-based command encoding (no padding)
roborock/devices/traits/traits_mixin.pyAdded b01_q10_properties trait field
roborock/devices/traits/b01/q7/init.pyUpdated imports for refactored Q7 channel module
roborock/devices/traits/b01/q10/init.pyQ10 trait implementation with command methods and message processing loop
roborock/devices/traits/b01/init.pyExported Q10PropertiesApi
roborock/devices/mqtt_channel.pyAdded subscribe_stream method for async iteration over messages
roborock/devices/device_manager.pyAdded Q10 device detection and trait creation for "ss" model variants
roborock/devices/device.pyAdded Q10 properties lifecycle management (start/close)
roborock/devices/b01_q7_channel.pyUpdated imports for refactored Q7 protocol module
roborock/devices/b01_q10_channel.pyNew channel wrapper for Q10 with send_command and stream_decoded_responses
roborock/data/code_mappings.pyAdded from_name and from_value helper methods to RoborockModeEnum
roborock/cli.pyAdded B01_Q10 command support with command parsing and error handling improvements
Comments suppressed due to low confidence (1)

tests/devices/traits/b01/q7/test_init.py:19

  • Incorrect import: B01_VERSION is being imported from roborock.protocols.b01_q10_protocol instead of roborock.protocols.b01_q7_protocol. This should be importing from the Q7 protocol module to match the refactored code structure where Q7 and Q10 have separate protocol implementations.

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

Comment threadroborock/devices/traits/b01/q10/__init__.py Outdated
Comment threadroborock/devices/traits/b01/q10/__init__.py Outdated
Comment threadroborock/cli.py Outdated
Comment threadroborock/cli.py Outdated
Comment threadroborock/devices/mqtt_channel.py
Comment threadroborock/devices/traits/b01/q10/__init__.py
Comment threadroborock/data/code_mappings.py
Comment threadroborock/protocols/b01_q10_protocol.py Outdated
Comment threadtests/protocols/__snapshots__/test_b01_q10_protocol.ambr
Comment threadroborock/devices/traits/b01/q10/__init__.py
@allenporter
allenporter marked this pull request as draft December 27, 2025 15:56
allenporter added a commit to allenporter/python-roborock that referenced this pull request Dec 29, 2025
allenporter added a commit that referenced this pull request Dec 29, 2025
* fix: Add b01 q10 protocol encoding/decoding and tests
Pulled from #692 and #709
* fix: Support unknown q10 DPS enum codes
allenporter added a commit to allenporter/python-roborock that referenced this pull request Dec 29, 2025
Add the ability to send commands to roborock CLI. This adds a single trait for sending commands, using a blend of approaches from Python-roborock#692 and Python-roborock#709
allenporter added a commit that referenced this pull request Dec 30, 2025
* feat: Recognize Q10 devices and add a command trait
Add the ability to send commands to roborock CLI. This adds a single trait for sending commands, using a blend of approaches from #692 and #709
* chore: Add end to end tests for Q10 devices
Moves the mock API responses to json files to make them easier to collect for new device types and modify in tests.
* chore: Remove unused timeout field
@cadavre

cadavre commented Jan 15, 2026

Copy link
Copy Markdown

As a context, when you try to add Q10 with current live version you get:

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 761, in __async_setup_with_context
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/roborock/__init__.py", line 66, in async_setup_entry
device_manager = await create_device_manager(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<13 lines>...
)
^
File "/usr/local/lib/python3.13/site-packages/roborock/devices/device_manager.py", line 248, in create_device_manager
await manager.discover_devices()
File "/usr/local/lib/python3.13/site-packages/roborock/devices/device_manager.py", line 102, in discover_devices
new_device = self._device_creator(home_data, device, product)
File "/usr/local/lib/python3.13/site-packages/roborock/devices/device_manager.py", line 231, in device_creator
raise NotImplementedError(
f"Device {device.name} has unsupported version B01_{product.model.strip('.')[-1]}"
)
NotImplementedError: Device Roborock Q10 PF+ has unsupported version B01_9

If you need a tester with Q10 PF+ when a beta version will be ready – you know where to find me!

@allenporter

Copy link
Copy Markdown
ContributorAuthor

As a context, when you try to add Q10 with current live version you get:

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 761, in __async_setup_with_context
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/roborock/__init__.py", line 66, in async_setup_entry
device_manager = await create_device_manager(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<13 lines>...
)
^
File "/usr/local/lib/python3.13/site-packages/roborock/devices/device_manager.py", line 248, in create_device_manager
await manager.discover_devices()
File "/usr/local/lib/python3.13/site-packages/roborock/devices/device_manager.py", line 102, in discover_devices
new_device = self._device_creator(home_data, device, product)
File "/usr/local/lib/python3.13/site-packages/roborock/devices/device_manager.py", line 231, in device_creator
raise NotImplementedError(
f"Device {device.name} has unsupported version B01_{product.model.strip('.')[-1]}"
)
NotImplementedError: Device Roborock Q10 PF+ has unsupported version B01_9

Yep, that's why we're working on this PR!

@allenporter

Copy link
Copy Markdown
ContributorAuthor

Next step on this is to merge or start over based on https://github.com/Python-roborock/python-roborock/pull/721/files

@lboue

Copy link
Copy Markdown
Contributor

Now that the #721 request has been merged, what will be the next step?

@allenporter

Copy link
Copy Markdown
ContributorAuthor

Now that the #721 request has been merged, what will be the next step?

I believe I mentioned the next step above which is to either merge that PR into this or start over with a new PR with some of the features here added.

@allenporter

allenporter commented Jan 24, 2026

Copy link
Copy Markdown
ContributorAuthor

Happy to chat with you more if were looking to make contributions, they are very much welcome. if you're asking because you want support in your device, point heard that this is still very much desired.

@lboue

lboue commented Jan 26, 2026

Copy link
Copy Markdown
Contributor

Happy to chat with you more if were looking to make contributions, they are very much welcome. if you're asking because you want support in your device, point heard that this is still very much desired.

Yes, I would like to contribute. Is there a Discord server where we could communicate more easily?

@allenporter

Copy link
Copy Markdown
ContributorAuthor

Other PRs are taking this forward

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.

4 participants

@allenporter@cadavre@lboue