-
Notifications
You must be signed in to change notification settings - Fork 69
feat: Implement v1 streaming data updates #799
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -53,15 +53,18 @@ | |||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import logging | ||||||||||||||||||||||||||||||||||||
| from collections.abc import Callable | ||||||||||||||||||||||||||||||||||||
| from dataclasses import dataclass, field, fields | ||||||||||||||||||||||||||||||||||||
| from typing import Any, get_args | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| from roborock.data.containers import HomeData, HomeDataProduct, RoborockBase | ||||||||||||||||||||||||||||||||||||
| from roborock.data.v1.v1_code_mappings import RoborockDockTypeCode | ||||||||||||||||||||||||||||||||||||
| from roborock.devices.cache import DeviceCache | ||||||||||||||||||||||||||||||||||||
| from roborock.devices.traits import Trait | ||||||||||||||||||||||||||||||||||||
| from roborock.exceptions import RoborockException | ||||||||||||||||||||||||||||||||||||
| from roborock.map.map_parser import MapParserConfig | ||||||||||||||||||||||||||||||||||||
| from roborock.protocols.v1_protocol import V1RpcChannel | ||||||||||||||||||||||||||||||||||||
| from roborock.protocols.v1_protocol import V1RpcChannel, decode_data_protocol_message | ||||||||||||||||||||||||||||||||||||
| from roborock.roborock_message import RoborockDataProtocol, RoborockMessage | ||||||||||||||||||||||||||||||||||||
| from roborock.web_api import UserWebApiClient | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| from . import ( | ||||||||||||||||||||||||||||||||||||
|
|
@@ -176,6 +179,7 @@ def __init__( | |||||||||||||||||||||||||||||||||||
| rpc_channel: V1RpcChannel, | ||||||||||||||||||||||||||||||||||||
| mqtt_rpc_channel: V1RpcChannel, | ||||||||||||||||||||||||||||||||||||
| map_rpc_channel: V1RpcChannel, | ||||||||||||||||||||||||||||||||||||
| add_dps_listener: Callable[[Callable[[dict[RoborockDataProtocol, Any]], None]], Callable[[], None]], | ||||||||||||||||||||||||||||||||||||
| web_api: UserWebApiClient, | ||||||||||||||||||||||||||||||||||||
| device_cache: DeviceCache, | ||||||||||||||||||||||||||||||||||||
| map_parser_config: MapParserConfig | None = None, | ||||||||||||||||||||||||||||||||||||
|
|
@@ -189,6 +193,8 @@ def __init__( | |||||||||||||||||||||||||||||||||||
| self._web_api = web_api | ||||||||||||||||||||||||||||||||||||
| self._device_cache = device_cache | ||||||||||||||||||||||||||||||||||||
| self._region = region | ||||||||||||||||||||||||||||||||||||
| self._unsub: Callable[[], None] | None = None | ||||||||||||||||||||||||||||||||||||
| self._add_dps_listener = add_dps_listener | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| self.device_features = DeviceFeaturesTrait(product, self._device_cache) | ||||||||||||||||||||||||||||||||||||
| self.status = StatusTrait(self.device_features, region=self._region) | ||||||||||||||||||||||||||||||||||||
|
|
@@ -227,6 +233,27 @@ def _get_rpc_channel(self, trait: V1TraitMixin) -> V1RpcChannel: | |||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||
| return self._rpc_channel | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| async def start(self) -> None: | ||||||||||||||||||||||||||||||||||||
| """Start the properties API and discover features.""" | ||||||||||||||||||||||||||||||||||||
| if self._unsub: | ||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||
| await self.discover_features() | ||||||||||||||||||||||||||||||||||||
| self._unsub = self._add_dps_listener(self._on_dps_update) | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| def close(self) -> None: | ||||||||||||||||||||||||||||||||||||
| if self._unsub: | ||||||||||||||||||||||||||||||||||||
| self._unsub() | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+240
to
+245
|
||||||||||||||||||||||||||||||||||||
| await self.discover_features() | |
| self._unsub = self._add_dps_listener(self._on_dps_update) | |
| def close(self) -> None: | |
| if self._unsub: | |
| self._unsub() | |
| # Avoid registering multiple listeners if start is called more than once | |
| if getattr(self, "_unsub", None): | |
| return | |
| await self.discover_features() | |
| self._unsub = self._add_dps_listener(self._on_dps_update) | |
| def close(self) -> None: | |
| unsub = getattr(self, "_unsub", None) | |
| if unsub: | |
| unsub() | |
| self._unsub = None |
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.
device_creatortypeschannelas theChannelprotocol, but then passeschannel.add_dps_listenerintov1.create(...).Channeldoesn’t defineadd_dps_listener, so this will fail mypy (which is enabled via pre-commit). Consider either (a) extending theChannelprotocol to includeadd_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., aV1Channelprotocol withadd_dps_listener).