python-roborock 3.3.3__tar.gz → 3.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_roborock-3.3.3 → python_roborock-3.5.0}/PKG-INFO +1 -1
- {python_roborock-3.3.3 → python_roborock-3.5.0}/pyproject.toml +1 -1
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/cli.py +11 -8
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/cache.py +2 -2
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/device_manager.py +51 -27
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/home.py +24 -24
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/web_api.py +18 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/.gitignore +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/LICENSE +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/README.md +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/api.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/broadcast_protocol.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/callbacks.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/cloud_api.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/command_cache.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/const.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q10/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q7/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/code_mappings.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/containers.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/dyad/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/dyad/dyad_code_mappings.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/dyad/dyad_containers.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/v1/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/v1/v1_clean_modes.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/v1/v1_code_mappings.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/v1/v1_containers.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/zeo/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/zeo/zeo_code_mappings.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/zeo/zeo_containers.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/device_features.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/README.md +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/a01_channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/b01_channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/device.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/local_channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/mqtt_channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/a01/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/traits_mixin.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/child_lock.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/clean_summary.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/command.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/common.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/consumeable.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/device_features.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/flow_led_status.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/led_status.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/map_content.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/maps.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/network_info.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/rooms.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/status.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/volume.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/v1_channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/v1_rpc_channel.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/exceptions.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/map/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/map/map_parser.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/mqtt/session.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/protocol.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/protocols/b01_protocol.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/py.typed +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/roborock_future.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/roborock_message.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/roborock_typing.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/util.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/roborock_client_v1.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/roborock_local_client_v1.py +1 -1
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_a01_apis/__init__.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
- {python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-roborock
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: A package to control Roborock vacuums.
|
|
5
5
|
Project-URL: Repository, https://github.com/humbertogontijo/python-roborock
|
|
6
6
|
Project-URL: Documentation, https://python-roborock.readthedocs.io/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-roborock"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.5.0"
|
|
4
4
|
description = "A package to control Roborock vacuums."
|
|
5
5
|
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
|
|
6
6
|
requires-python = ">=3.11, <4"
|
|
@@ -46,7 +46,7 @@ from roborock.data import CombinedMapInfo, DeviceData, HomeData, NetworkInfo, Ro
|
|
|
46
46
|
from roborock.device_features import DeviceFeatures
|
|
47
47
|
from roborock.devices.cache import Cache, CacheData
|
|
48
48
|
from roborock.devices.device import RoborockDevice
|
|
49
|
-
from roborock.devices.device_manager import DeviceManager,
|
|
49
|
+
from roborock.devices.device_manager import DeviceManager, UserParams, create_device_manager
|
|
50
50
|
from roborock.devices.traits import Trait
|
|
51
51
|
from roborock.devices.traits.v1 import V1TraitMixin
|
|
52
52
|
from roborock.devices.traits.v1.consumeable import ConsumableAttribute
|
|
@@ -118,7 +118,7 @@ class ConnectionCache(RoborockBase):
|
|
|
118
118
|
email: str
|
|
119
119
|
home_data: HomeData | None = None
|
|
120
120
|
network_info: dict[str, NetworkInfo] | None = None
|
|
121
|
-
|
|
121
|
+
home_map_info: dict[int, CombinedMapInfo] | None = None
|
|
122
122
|
trait_data: dict[str, Any] | None = None
|
|
123
123
|
|
|
124
124
|
|
|
@@ -135,8 +135,11 @@ class DeviceConnectionManager:
|
|
|
135
135
|
"""Ensure device manager is initialized."""
|
|
136
136
|
if self.device_manager is None:
|
|
137
137
|
cache_data = self.context.cache_data()
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
user_params = UserParams(
|
|
139
|
+
username=cache_data.email,
|
|
140
|
+
user_data=cache_data.user_data,
|
|
141
|
+
)
|
|
142
|
+
self.device_manager = await create_device_manager(user_params, cache=self.context)
|
|
140
143
|
# Cache devices for quick lookup
|
|
141
144
|
devices = await self.device_manager.get_devices()
|
|
142
145
|
self._devices = {device.duid: device for device in devices}
|
|
@@ -267,7 +270,7 @@ class RoborockContext(Cache):
|
|
|
267
270
|
return CacheData(
|
|
268
271
|
home_data=connection_cache.home_data,
|
|
269
272
|
network_info=connection_cache.network_info or {},
|
|
270
|
-
|
|
273
|
+
home_map_info=connection_cache.home_map_info,
|
|
271
274
|
trait_data=connection_cache.trait_data or {},
|
|
272
275
|
)
|
|
273
276
|
|
|
@@ -277,7 +280,7 @@ class RoborockContext(Cache):
|
|
|
277
280
|
connection_cache = self.cache_data()
|
|
278
281
|
connection_cache.home_data = value.home_data
|
|
279
282
|
connection_cache.network_info = value.network_info
|
|
280
|
-
connection_cache.
|
|
283
|
+
connection_cache.home_map_info = value.home_map_info
|
|
281
284
|
connection_cache.trait_data = value.trait_data
|
|
282
285
|
self.update(connection_cache)
|
|
283
286
|
|
|
@@ -717,14 +720,14 @@ async def home(ctx, device_id: str, refresh: bool):
|
|
|
717
720
|
await home_trait.refresh()
|
|
718
721
|
|
|
719
722
|
# Display the discovered home cache
|
|
720
|
-
if home_trait.
|
|
723
|
+
if home_trait.home_map_info:
|
|
721
724
|
cache_summary = {
|
|
722
725
|
map_flag: {
|
|
723
726
|
"name": map_data.name,
|
|
724
727
|
"room_count": len(map_data.rooms),
|
|
725
728
|
"rooms": [{"segment_id": room.segment_id, "name": room.name} for room in map_data.rooms],
|
|
726
729
|
}
|
|
727
|
-
for map_flag, map_data in home_trait.
|
|
730
|
+
for map_flag, map_data in home_trait.home_map_info.items()
|
|
728
731
|
}
|
|
729
732
|
click.echo(dump_json(cache_summary))
|
|
730
733
|
else:
|
|
@@ -22,8 +22,8 @@ class CacheData:
|
|
|
22
22
|
network_info: dict[str, NetworkInfo] = field(default_factory=dict)
|
|
23
23
|
"""Network information indexed by device DUID."""
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
"""Home
|
|
25
|
+
home_map_info: dict[int, CombinedMapInfo] = field(default_factory=dict)
|
|
26
|
+
"""Home map information indexed by map_flag."""
|
|
27
27
|
|
|
28
28
|
device_features: DeviceFeatures | None = None
|
|
29
29
|
"""Device features information."""
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import enum
|
|
5
5
|
import logging
|
|
6
|
-
from collections.abc import
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
from dataclasses import dataclass
|
|
7
8
|
|
|
8
9
|
import aiohttp
|
|
9
10
|
|
|
@@ -18,7 +19,7 @@ from roborock.map.map_parser import MapParserConfig
|
|
|
18
19
|
from roborock.mqtt.roborock_session import create_lazy_mqtt_session
|
|
19
20
|
from roborock.mqtt.session import MqttSession
|
|
20
21
|
from roborock.protocol import create_mqtt_params
|
|
21
|
-
from roborock.web_api import RoborockApiClient
|
|
22
|
+
from roborock.web_api import RoborockApiClient, UserWebApiClient
|
|
22
23
|
|
|
23
24
|
from .cache import Cache, NoCache
|
|
24
25
|
from .channel import Channel
|
|
@@ -30,12 +31,11 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
30
31
|
|
|
31
32
|
__all__ = [
|
|
32
33
|
"create_device_manager",
|
|
33
|
-
"
|
|
34
|
+
"UserParams",
|
|
34
35
|
"DeviceManager",
|
|
35
36
|
]
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
HomeDataApi = Callable[[], Awaitable[HomeData]]
|
|
39
39
|
DeviceCreator = Callable[[HomeData, HomeDataDevice, HomeDataProduct], RoborockDevice]
|
|
40
40
|
|
|
41
41
|
|
|
@@ -53,7 +53,7 @@ class DeviceManager:
|
|
|
53
53
|
|
|
54
54
|
def __init__(
|
|
55
55
|
self,
|
|
56
|
-
|
|
56
|
+
web_api: UserWebApiClient,
|
|
57
57
|
device_creator: DeviceCreator,
|
|
58
58
|
mqtt_session: MqttSession,
|
|
59
59
|
cache: Cache,
|
|
@@ -62,7 +62,7 @@ class DeviceManager:
|
|
|
62
62
|
|
|
63
63
|
This takes ownership of the MQTT session and will close it when the manager is closed.
|
|
64
64
|
"""
|
|
65
|
-
self.
|
|
65
|
+
self._web_api = web_api
|
|
66
66
|
self._cache = cache
|
|
67
67
|
self._device_creator = device_creator
|
|
68
68
|
self._devices: dict[str, RoborockDevice] = {}
|
|
@@ -73,7 +73,7 @@ class DeviceManager:
|
|
|
73
73
|
cache_data = await self._cache.get()
|
|
74
74
|
if not cache_data.home_data:
|
|
75
75
|
_LOGGER.debug("No cached home data found, fetching from API")
|
|
76
|
-
cache_data.home_data = await self.
|
|
76
|
+
cache_data.home_data = await self._web_api.get_home_data()
|
|
77
77
|
await self._cache.set(cache_data)
|
|
78
78
|
home_data = cache_data.home_data
|
|
79
79
|
|
|
@@ -108,45 +108,69 @@ class DeviceManager:
|
|
|
108
108
|
await asyncio.gather(*tasks)
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"""Create a home data API wrapper.
|
|
111
|
+
@dataclass
|
|
112
|
+
class UserParams:
|
|
113
|
+
"""Parameters for creating a new session with Roborock devices.
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
These parameters include the username, user data for authentication,
|
|
116
|
+
and an optional base URL for the Roborock API. The `user_data` and `base_url`
|
|
117
|
+
parameters are obtained from `RoborockApiClient` during the login process.
|
|
118
118
|
"""
|
|
119
|
-
# Note: This will auto discover the API base URL. This can be improved
|
|
120
|
-
# by caching this next to `UserData` if needed to avoid unnecessary API calls.
|
|
121
|
-
client = RoborockApiClient(username=email, base_url=base_url, session=session)
|
|
122
119
|
|
|
123
|
-
|
|
120
|
+
username: str
|
|
121
|
+
"""The username (email) used for logging in."""
|
|
122
|
+
|
|
123
|
+
user_data: UserData
|
|
124
|
+
"""This is the user data containing authentication information."""
|
|
125
|
+
|
|
126
|
+
base_url: str | None = None
|
|
127
|
+
"""Optional base URL for the Roborock API.
|
|
128
|
+
|
|
129
|
+
This is used to speed up connection times by avoiding the need to
|
|
130
|
+
discover the API base URL each time. If not provided, the API client
|
|
131
|
+
will attempt to discover it automatically which may take multiple requests.
|
|
132
|
+
"""
|
|
124
133
|
|
|
125
134
|
|
|
126
|
-
def
|
|
135
|
+
def create_web_api_wrapper(
|
|
136
|
+
user_params: UserParams,
|
|
137
|
+
*,
|
|
138
|
+
cache: Cache | None = None,
|
|
139
|
+
session: aiohttp.ClientSession | None = None,
|
|
140
|
+
) -> UserWebApiClient:
|
|
127
141
|
"""Create a home data API wrapper from an existing API client."""
|
|
128
142
|
|
|
129
|
-
|
|
130
|
-
|
|
143
|
+
# Note: This will auto discover the API base URL. This can be improved
|
|
144
|
+
# by caching this next to `UserData` if needed to avoid unnecessary API calls.
|
|
145
|
+
client = RoborockApiClient(username=user_params.username, base_url=user_params.base_url, session=session)
|
|
131
146
|
|
|
132
|
-
return
|
|
147
|
+
return UserWebApiClient(client, user_params.user_data)
|
|
133
148
|
|
|
134
149
|
|
|
135
150
|
async def create_device_manager(
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
user_params: UserParams,
|
|
152
|
+
*,
|
|
138
153
|
cache: Cache | None = None,
|
|
139
154
|
map_parser_config: MapParserConfig | None = None,
|
|
155
|
+
session: aiohttp.ClientSession | None = None,
|
|
140
156
|
) -> DeviceManager:
|
|
141
157
|
"""Convenience function to create and initialize a DeviceManager.
|
|
142
158
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
159
|
+
Args:
|
|
160
|
+
user_params: Parameters for creating the user session.
|
|
161
|
+
cache: Optional cache implementation to use for caching device data.
|
|
162
|
+
map_parser_config: Optional configuration for parsing maps.
|
|
163
|
+
session: Optional aiohttp ClientSession to use for HTTP requests.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
An initialized DeviceManager with discovered devices.
|
|
146
167
|
"""
|
|
147
168
|
if cache is None:
|
|
148
169
|
cache = NoCache()
|
|
149
170
|
|
|
171
|
+
web_api = create_web_api_wrapper(user_params, session=session, cache=cache)
|
|
172
|
+
user_data = user_params.user_data
|
|
173
|
+
|
|
150
174
|
mqtt_params = create_mqtt_params(user_data.rriot)
|
|
151
175
|
mqtt_session = await create_lazy_mqtt_session(mqtt_params)
|
|
152
176
|
|
|
@@ -176,6 +200,6 @@ async def create_device_manager(
|
|
|
176
200
|
raise NotImplementedError(f"Device {device.name} has unsupported version {device.pv}")
|
|
177
201
|
return RoborockDevice(device, product, channel, trait)
|
|
178
202
|
|
|
179
|
-
manager = DeviceManager(
|
|
203
|
+
manager = DeviceManager(web_api, device_creator, mqtt_session=mqtt_session, cache=cache)
|
|
180
204
|
await manager.discover_devices()
|
|
181
205
|
return manager
|
|
@@ -61,7 +61,7 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
61
61
|
self._maps_trait = maps_trait
|
|
62
62
|
self._rooms_trait = rooms_trait
|
|
63
63
|
self._cache = cache
|
|
64
|
-
self.
|
|
64
|
+
self._home_map_info: dict[int, CombinedMapInfo] | None = None
|
|
65
65
|
|
|
66
66
|
async def discover_home(self) -> None:
|
|
67
67
|
"""Iterate through all maps to discover rooms and cache them.
|
|
@@ -72,12 +72,12 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
72
72
|
cleaning process. This will raise `RoborockDeviceBusy` if the device is
|
|
73
73
|
currently cleaning.
|
|
74
74
|
|
|
75
|
-
After discovery, the home cache will be populated and can be accessed via the `
|
|
75
|
+
After discovery, the home cache will be populated and can be accessed via the `home_map_info` property.
|
|
76
76
|
"""
|
|
77
77
|
cache_data = await self._cache.get()
|
|
78
|
-
if cache_data.
|
|
78
|
+
if cache_data.home_map_info:
|
|
79
79
|
_LOGGER.debug("Home cache already populated, skipping discovery")
|
|
80
|
-
self.
|
|
80
|
+
self._home_map_info = cache_data.home_map_info
|
|
81
81
|
return
|
|
82
82
|
|
|
83
83
|
if self._status_trait.state == RoborockStateCode.cleaning:
|
|
@@ -87,11 +87,11 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
87
87
|
if self._maps_trait.current_map_info is None:
|
|
88
88
|
raise RoborockException("Cannot perform home discovery without current map info")
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
_LOGGER.debug("Home discovery complete, caching data for %d maps", len(
|
|
92
|
-
await self.
|
|
90
|
+
home_map_info = await self._build_home_map_info()
|
|
91
|
+
_LOGGER.debug("Home discovery complete, caching data for %d maps", len(home_map_info))
|
|
92
|
+
await self._update_home_map_info(home_map_info)
|
|
93
93
|
|
|
94
|
-
async def
|
|
94
|
+
async def _refresh_map_info(self, map_info) -> CombinedMapInfo:
|
|
95
95
|
"""Collect room data for a specific map and return CombinedMapInfo."""
|
|
96
96
|
await self._rooms_trait.refresh()
|
|
97
97
|
return CombinedMapInfo(
|
|
@@ -100,9 +100,9 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
100
100
|
rooms=self._rooms_trait.rooms or [],
|
|
101
101
|
)
|
|
102
102
|
|
|
103
|
-
async def
|
|
103
|
+
async def _build_home_map_info(self) -> dict[int, CombinedMapInfo]:
|
|
104
104
|
"""Perform the actual discovery and caching of home data."""
|
|
105
|
-
|
|
105
|
+
home_map_info: dict[int, CombinedMapInfo] = {}
|
|
106
106
|
|
|
107
107
|
# Sort map_info to process the current map last, reducing map switching.
|
|
108
108
|
# False (non-original maps) sorts before True (original map). We ensure
|
|
@@ -120,9 +120,9 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
120
120
|
await self._maps_trait.set_current_map(map_info.map_flag)
|
|
121
121
|
await asyncio.sleep(MAP_SLEEP)
|
|
122
122
|
|
|
123
|
-
map_data = await self.
|
|
124
|
-
|
|
125
|
-
return
|
|
123
|
+
map_data = await self._refresh_map_info(map_info)
|
|
124
|
+
home_map_info[map_info.map_flag] = map_data
|
|
125
|
+
return home_map_info
|
|
126
126
|
|
|
127
127
|
async def refresh(self) -> Self:
|
|
128
128
|
"""Refresh current map's underlying map and room data, updating cache as needed.
|
|
@@ -131,7 +131,7 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
131
131
|
active maps or re-discover the home. It is expected that this will keep
|
|
132
132
|
information up to date for the current map as users switch to that map.
|
|
133
133
|
"""
|
|
134
|
-
if self.
|
|
134
|
+
if self._home_map_info is None:
|
|
135
135
|
raise RoborockException("Cannot refresh home data without home cache, did you call discover_home()?")
|
|
136
136
|
|
|
137
137
|
# Refresh the list of map names/info
|
|
@@ -142,33 +142,33 @@ class HomeTrait(RoborockBase, common.V1TraitMixin):
|
|
|
142
142
|
raise RoborockException("Cannot refresh home data without current map info")
|
|
143
143
|
|
|
144
144
|
# Refresh the current map's room data
|
|
145
|
-
current_map_data = self.
|
|
145
|
+
current_map_data = self._home_map_info.get(map_flag)
|
|
146
146
|
if current_map_data:
|
|
147
|
-
map_data = await self.
|
|
147
|
+
map_data = await self._refresh_map_info(current_map_info)
|
|
148
148
|
if map_data != current_map_data:
|
|
149
|
-
await self.
|
|
149
|
+
await self._update_home_map_info({**self._home_map_info, map_flag: map_data})
|
|
150
150
|
|
|
151
151
|
return self
|
|
152
152
|
|
|
153
153
|
@property
|
|
154
|
-
def
|
|
154
|
+
def home_map_info(self) -> dict[int, CombinedMapInfo] | None:
|
|
155
155
|
"""Returns the map information for all cached maps."""
|
|
156
|
-
return self.
|
|
156
|
+
return self._home_map_info
|
|
157
157
|
|
|
158
158
|
@property
|
|
159
159
|
def current_map_data(self) -> CombinedMapInfo | None:
|
|
160
160
|
"""Returns the map data for the current map."""
|
|
161
161
|
current_map_flag = self._maps_trait.current_map
|
|
162
|
-
if current_map_flag is None or self.
|
|
162
|
+
if current_map_flag is None or self._home_map_info is None:
|
|
163
163
|
return None
|
|
164
|
-
return self.
|
|
164
|
+
return self._home_map_info.get(current_map_flag)
|
|
165
165
|
|
|
166
166
|
def _parse_response(self, response: common.V1ResponseData) -> Self:
|
|
167
167
|
"""This trait does not parse responses directly."""
|
|
168
168
|
raise NotImplementedError("HomeTrait does not support direct command responses")
|
|
169
169
|
|
|
170
|
-
async def
|
|
170
|
+
async def _update_home_map_info(self, home_map_info: dict[int, CombinedMapInfo]) -> None:
|
|
171
171
|
cache_data = await self._cache.get()
|
|
172
|
-
cache_data.
|
|
172
|
+
cache_data.home_map_info = home_map_info
|
|
173
173
|
await self._cache.set(cache_data)
|
|
174
|
-
self.
|
|
174
|
+
self._home_map_info = home_map_info
|
|
@@ -707,3 +707,21 @@ def _get_hawk_authentication(rriot: RRiot, url: str, formdata: dict | None = Non
|
|
|
707
707
|
)
|
|
708
708
|
mac = base64.b64encode(hmac.new(rriot.h.encode(), prestr.encode(), hashlib.sha256).digest()).decode()
|
|
709
709
|
return f'Hawk id="{rriot.u}",s="{rriot.s}",ts="{timestamp}",nonce="{nonce}",mac="{mac}"'
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
class UserWebApiClient:
|
|
713
|
+
"""Wrapper around RoborockApiClient to provide information for a specific user.
|
|
714
|
+
|
|
715
|
+
This binds a RoborockApiClient to a specific user context with the
|
|
716
|
+
provided UserData. This allows for easier access to user-specific data,
|
|
717
|
+
to avoid needing to pass UserData around and mock out the web API.
|
|
718
|
+
"""
|
|
719
|
+
|
|
720
|
+
def __init__(self, web_api: RoborockApiClient, user_data: UserData) -> None:
|
|
721
|
+
"""Initialize the wrapper with the API client and user data."""
|
|
722
|
+
self._web_api = web_api
|
|
723
|
+
self._user_data = user_data
|
|
724
|
+
|
|
725
|
+
async def get_home_data(self) -> HomeData:
|
|
726
|
+
"""Fetch home data using the API client."""
|
|
727
|
+
return await self._web_api.get_home_data_v3(self._user_data)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q10/b01_q10_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/data/b01_q7/b01_q7_code_mappings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/device_features.py
RENAMED
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/do_not_disturb.py
RENAMED
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/dust_collection_mode.py
RENAMED
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/flow_led_status.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/smart_wash_params.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/devices/traits/v1/wash_towel_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/roborock_client_v1.py
RENAMED
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/roborock_local_client_v1.py
RENAMED
|
@@ -210,6 +210,7 @@ class RoborockLocalClientV1(RoborockClientV1, RoborockClient):
|
|
|
210
210
|
version=self.local_protocol_version,
|
|
211
211
|
)
|
|
212
212
|
self._logger.debug("Building message id %s for method %s", request_message.request_id, method)
|
|
213
|
+
await self._validate_connection()
|
|
213
214
|
return await self._send_message(
|
|
214
215
|
roborock_message,
|
|
215
216
|
request_id=request_message.request_id,
|
|
@@ -226,7 +227,6 @@ class RoborockLocalClientV1(RoborockClientV1, RoborockClient):
|
|
|
226
227
|
method: str | None = None,
|
|
227
228
|
params: list | dict | int | None = None,
|
|
228
229
|
) -> RoborockMessage:
|
|
229
|
-
await self._validate_connection()
|
|
230
230
|
msg = self._encoder(roborock_message)
|
|
231
231
|
if method:
|
|
232
232
|
self._logger.debug(f"id={request_id} Requesting method {method} with {params}")
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_1_apis/roborock_mqtt_client_v1.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-3.3.3 → python_roborock-3.5.0}/roborock/version_a01_apis/roborock_client_a01.py
RENAMED
|
File without changes
|
|
File without changes
|