feat: Implement v1 streaming data updates#799
feat: Implement v1 streaming data updates#799allenporter merged 1 commit intoPython-roborock:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Implements streaming “push” updates for V1 devices by decoding incoming DPS (data protocol) payloads and applying them to relevant V1 traits, enabling near-real-time status/consumable updates without polling.
Changes:
- Add
decode_data_protocol_message()to parse V1 DPS push messages intoRoborockDataProtocol -> valuemappings. - Introduce a DPS-to-dataclass-field mapping mechanism (
DpsDataConverter) plus trait update listeners to apply streaming updates. - Wire V1 channel MQTT subscriptions to emit DPS updates and have
PropertiesApi.start()register a listener to update traits.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
roborock/protocols/v1_protocol.py |
Adds DPS decoding helper and decode_data_protocol_message() for V1 push updates. |
roborock/devices/rpc/v1_channel.py |
Always subscribes to MQTT and emits decoded DPS updates to registered listeners. |
roborock/devices/traits/v1/common.py |
Adds TraitUpdateListener + DpsDataConverter to support streaming field updates. |
roborock/devices/traits/v1/status.py |
Applies DPS updates to StatusTrait and notifies listeners. |
roborock/devices/traits/v1/consumeable.py |
Adds DPS update support to ConsumableTrait. |
roborock/devices/traits/v1/__init__.py |
Adds start() to register DPS listener and dispatch updates to traits. |
roborock/devices/device.py |
Starts/stops V1 properties streaming lifecycle on connect/close. |
roborock/devices/device_manager.py |
Passes add_dps_listener from channel into V1 trait creation. |
roborock/data/v1/v1_containers.py |
Annotates selected dataclass fields with dps metadata for streaming updates. |
roborock/roborock_message.py |
Adjusts RoborockEnum import location. |
tests/protocols/test_v1_protocol.py |
Adds unit tests for decoding V1 data protocol push messages. |
tests/devices/traits/v1/test_status.py |
Adds unit tests for status updates + update listeners. |
tests/devices/traits/v1/fixtures.py / tests/devices/test_v1_device.py |
Updates fixtures to satisfy new add_dps_listener constructor parameter. |
tests/devices/rpc/test_v1_channel.py |
Updates expectation: MQTT subscription is established even with local connection. |
tests/e2e/__snapshots__/test_device_manager.ambr |
Snapshot updated for additional MQTT traffic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| datetime.datetime.now(datetime.UTC) - self._last_network_info_refresh > NETWORK_INFO_REFRESH_INTERVAL | ||
| ): | ||
| return False | ||
| return True | ||
|
|
||
| def _on_mqtt_message(self, message: RoborockMessage) -> None: | ||
| """Handle incoming MQTT messages.""" | ||
| self._logger.debug("V1Channel received MQTT message: %s", message) | ||
| if self._callback: | ||
| self._callback(message) | ||
| try: | ||
| if datapoints := decode_data_protocol_message(message): | ||
| self._dps_listeners(datapoints) | ||
| except RoborockException as e: |
There was a problem hiding this comment.
New DPS listener plumbing (add_dps_listener + decoding/dispatch in _on_mqtt_message) doesn’t appear to have direct test coverage (no tests assert that a pushed MQTT message results in DPS callbacks firing). Adding a unit test around V1Channel._on_mqtt_message (or an integration-style test that PropertiesApi.start() updates StatusTrait via a simulated MQTT message) would help prevent regressions in the streaming update path.
| channel.rpc_channel, | ||
| channel.mqtt_rpc_channel, | ||
| channel.map_rpc_channel, | ||
| channel.add_dps_listener, |
There was a problem hiding this comment.
device_creator types channel as the Channel protocol, but then passes channel.add_dps_listener into v1.create(...). Channel doesn’t define add_dps_listener, so this will fail mypy (which is enabled via pre-commit). Consider either (a) extending the Channel protocol to include add_dps_listener (possibly as an optional/no-op for non-V1 channels), or (b) using a more specific protocol/type for V1 channels in this match arm (e.g., a V1Channel protocol with add_dps_listener).
8aa14ae to
2e87350
Compare
ccbeabf to
bc5e1fd
Compare
4c2af3e to
f3839fb
Compare
…es using `dps` metadata and add corresponding update listeners. Uses `dps` metadata and add corresponding update listeners. This uses the same dps converter patern used by q10, but does not share code explicitly. This also renames discover_features to start in v1 properties.
8786494 to
a437bcc
Compare
This implements a listener that will receive streaming updates to data protocol messages. This sets the mapping for each field using the
dpsmetadata and adds corresponding update listeners to the associated traints.This uses the same dps converter pattern used by q10, but does not share code explicitly.