python-roborock 2.34.1__tar.gz → 2.34.2__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-2.34.1 → python_roborock-2.34.2}/PKG-INFO +1 -1
- {python_roborock-2.34.1 → python_roborock-2.34.2}/pyproject.toml +1 -1
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/api.py +0 -4
- python_roborock-2.34.1/roborock/local_api.py → python_roborock-2.34.2/roborock/version_1_apis/roborock_local_client_v1.py +66 -13
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +3 -3
- python_roborock-2.34.1/roborock/version_1_apis/roborock_local_client_v1.py +0 -73
- {python_roborock-2.34.1 → python_roborock-2.34.2}/LICENSE +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/README.md +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/__init__.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/cli.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/cloud_api.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/code_mappings.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/command_cache.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/const.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/containers.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/device_features.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/README.md +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/__init__.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/a01_channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/b01_channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/cache.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/device.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/device_manager.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/local_channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/mqtt_channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/b01/__init__.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/b01/props.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/dyad.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/status.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/trait.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/zeo.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/v1_channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/v1_rpc_channel.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/exceptions.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/mqtt/session.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocol.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocols/b01_protocol.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/py.typed +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/roborock_future.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/roborock_message.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/roborock_typing.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/util.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/__init__.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/roborock_client_v1.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/__init__.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
- {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/web_api.py +0 -0
|
@@ -116,7 +116,3 @@ class RoborockClient(ABC):
|
|
|
116
116
|
request_id = new_id
|
|
117
117
|
self._waiting_queue[request_id] = queue
|
|
118
118
|
return asyncio.ensure_future(self._wait_response(request_id, queue))
|
|
119
|
-
|
|
120
|
-
@abstractmethod
|
|
121
|
-
async def send_message(self, roborock_message: RoborockMessage):
|
|
122
|
-
"""Send a message to the Roborock device."""
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
import asyncio
|
|
4
2
|
import logging
|
|
5
|
-
from abc import ABC
|
|
6
3
|
from asyncio import Lock, TimerHandle, Transport, get_running_loop
|
|
7
4
|
from collections.abc import Callable
|
|
8
5
|
from dataclasses import dataclass
|
|
9
6
|
|
|
10
7
|
import async_timeout
|
|
11
8
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from .
|
|
9
|
+
from .. import CommandVacuumError, DeviceData, RoborockCommand
|
|
10
|
+
from ..api import RoborockClient
|
|
11
|
+
from ..exceptions import RoborockConnectionException, RoborockException, VacuumError
|
|
12
|
+
from ..protocol import Decoder, Encoder, create_local_decoder, create_local_encoder
|
|
13
|
+
from ..protocols.v1_protocol import encode_local_payload
|
|
14
|
+
from ..roborock_message import RoborockMessage, RoborockMessageProtocol
|
|
15
|
+
from ..util import RoborockLoggerAdapter
|
|
16
|
+
from .roborock_client_v1 import CLOUD_REQUIRED, RoborockClientV1
|
|
17
17
|
|
|
18
18
|
_LOGGER = logging.getLogger(__name__)
|
|
19
19
|
|
|
@@ -34,10 +34,10 @@ class _LocalProtocol(asyncio.Protocol):
|
|
|
34
34
|
self.connection_lost_cb(exc)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
class
|
|
38
|
-
"""Roborock local client
|
|
37
|
+
class RoborockLocalClientV1(RoborockClientV1, RoborockClient):
|
|
38
|
+
"""Roborock local client for v1 devices."""
|
|
39
39
|
|
|
40
|
-
def __init__(self, device_data: DeviceData):
|
|
40
|
+
def __init__(self, device_data: DeviceData, queue_timeout: int = 4):
|
|
41
41
|
"""Initialize the Roborock local client."""
|
|
42
42
|
if device_data.host is None:
|
|
43
43
|
raise RoborockException("Host is required")
|
|
@@ -47,10 +47,13 @@ class RoborockLocalClient(RoborockClient, ABC):
|
|
|
47
47
|
self.transport: Transport | None = None
|
|
48
48
|
self._mutex = Lock()
|
|
49
49
|
self.keep_alive_task: TimerHandle | None = None
|
|
50
|
+
RoborockClientV1.__init__(self, device_data, "abc")
|
|
50
51
|
RoborockClient.__init__(self, device_data)
|
|
51
52
|
self._local_protocol = _LocalProtocol(self._data_received, self._connection_lost)
|
|
52
53
|
self._encoder: Encoder = create_local_encoder(device_data.device.local_key)
|
|
53
54
|
self._decoder: Decoder = create_local_decoder(device_data.device.local_key)
|
|
55
|
+
self.queue_timeout = queue_timeout
|
|
56
|
+
self._logger = RoborockLoggerAdapter(device_data.device.name, _LOGGER)
|
|
54
57
|
|
|
55
58
|
def _data_received(self, message):
|
|
56
59
|
"""Called when data is received from the transport."""
|
|
@@ -109,7 +112,7 @@ class RoborockLocalClient(RoborockClient, ABC):
|
|
|
109
112
|
request_id = 1
|
|
110
113
|
protocol = RoborockMessageProtocol.HELLO_REQUEST
|
|
111
114
|
try:
|
|
112
|
-
return await self.
|
|
115
|
+
return await self._send_message(
|
|
113
116
|
RoborockMessage(
|
|
114
117
|
protocol=protocol,
|
|
115
118
|
seq=request_id,
|
|
@@ -122,7 +125,7 @@ class RoborockLocalClient(RoborockClient, ABC):
|
|
|
122
125
|
async def ping(self) -> None:
|
|
123
126
|
request_id = 2
|
|
124
127
|
protocol = RoborockMessageProtocol.PING_REQUEST
|
|
125
|
-
return await self.
|
|
128
|
+
return await self._send_message(
|
|
126
129
|
RoborockMessage(
|
|
127
130
|
protocol=protocol,
|
|
128
131
|
seq=request_id,
|
|
@@ -137,3 +140,53 @@ class RoborockLocalClient(RoborockClient, ABC):
|
|
|
137
140
|
self.transport.write(data)
|
|
138
141
|
except Exception as e:
|
|
139
142
|
raise RoborockException(e) from e
|
|
143
|
+
|
|
144
|
+
async def _send_command(
|
|
145
|
+
self,
|
|
146
|
+
method: RoborockCommand | str,
|
|
147
|
+
params: list | dict | int | None = None,
|
|
148
|
+
):
|
|
149
|
+
if method in CLOUD_REQUIRED:
|
|
150
|
+
raise RoborockException(f"Method {method} is not supported over local connection")
|
|
151
|
+
|
|
152
|
+
roborock_message = encode_local_payload(method, params)
|
|
153
|
+
self._logger.debug("Building message id %s for method %s", roborock_message.get_request_id(), method)
|
|
154
|
+
return await self._send_message(roborock_message)
|
|
155
|
+
|
|
156
|
+
async def _send_message(self, roborock_message: RoborockMessage):
|
|
157
|
+
await self.validate_connection()
|
|
158
|
+
method = roborock_message.get_method()
|
|
159
|
+
params = roborock_message.get_params()
|
|
160
|
+
request_id: int | None
|
|
161
|
+
if not method or not method.startswith("get"):
|
|
162
|
+
request_id = roborock_message.seq
|
|
163
|
+
response_protocol = request_id + 1
|
|
164
|
+
else:
|
|
165
|
+
request_id = roborock_message.get_request_id()
|
|
166
|
+
response_protocol = RoborockMessageProtocol.GENERAL_REQUEST
|
|
167
|
+
if request_id is None:
|
|
168
|
+
raise RoborockException(f"Failed build message {roborock_message}")
|
|
169
|
+
msg = self._encoder(roborock_message)
|
|
170
|
+
if method:
|
|
171
|
+
self._logger.debug(f"id={request_id} Requesting method {method} with {params}")
|
|
172
|
+
# Send the command to the Roborock device
|
|
173
|
+
async_response = self._async_response(request_id, response_protocol)
|
|
174
|
+
self._send_msg_raw(msg)
|
|
175
|
+
diagnostic_key = method if method is not None else "unknown"
|
|
176
|
+
try:
|
|
177
|
+
response = await async_response
|
|
178
|
+
except VacuumError as err:
|
|
179
|
+
self._diagnostic_data[diagnostic_key] = {
|
|
180
|
+
"params": roborock_message.get_params(),
|
|
181
|
+
"error": err,
|
|
182
|
+
}
|
|
183
|
+
raise CommandVacuumError(method, err) from err
|
|
184
|
+
self._diagnostic_data[diagnostic_key] = {
|
|
185
|
+
"params": roborock_message.get_params(),
|
|
186
|
+
"response": response,
|
|
187
|
+
}
|
|
188
|
+
if roborock_message.protocol == RoborockMessageProtocol.GENERAL_REQUEST:
|
|
189
|
+
self._logger.debug(f"id={request_id} Response from method {roborock_message.get_method()}: {response}")
|
|
190
|
+
if response == "retry":
|
|
191
|
+
raise RoborockException(f"Command {method} failed with 'retry' message; Device is busy, try again later")
|
|
192
|
+
return response
|
|
@@ -39,7 +39,7 @@ class RoborockMqttClientA01(RoborockMqttClient, RoborockClientA01):
|
|
|
39
39
|
self.queue_timeout = queue_timeout
|
|
40
40
|
self._logger = RoborockLoggerAdapter(device_info.device.name, _LOGGER)
|
|
41
41
|
|
|
42
|
-
async def
|
|
42
|
+
async def _send_message(self, roborock_message: RoborockMessage):
|
|
43
43
|
await self.validate_connection()
|
|
44
44
|
response_protocol = RoborockMessageProtocol.RPC_RESPONSE
|
|
45
45
|
|
|
@@ -67,11 +67,11 @@ class RoborockMqttClientA01(RoborockMqttClient, RoborockClientA01):
|
|
|
67
67
|
message = encode_mqtt_payload(
|
|
68
68
|
{RoborockDyadDataProtocol.ID_QUERY: str([int(protocol) for protocol in dyad_data_protocols])}
|
|
69
69
|
)
|
|
70
|
-
return await self.
|
|
70
|
+
return await self._send_message(message)
|
|
71
71
|
|
|
72
72
|
async def set_value(
|
|
73
73
|
self, protocol: RoborockDyadDataProtocol | RoborockZeoProtocol, value: typing.Any
|
|
74
74
|
) -> dict[int, typing.Any]:
|
|
75
75
|
"""Set a value for a specific protocol on the A01 device."""
|
|
76
76
|
message = encode_mqtt_payload({protocol: value})
|
|
77
|
-
return await self.
|
|
77
|
+
return await self._send_message(message)
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
from roborock.local_api import RoborockLocalClient
|
|
4
|
-
|
|
5
|
-
from .. import CommandVacuumError, DeviceData, RoborockCommand, RoborockException
|
|
6
|
-
from ..exceptions import VacuumError
|
|
7
|
-
from ..protocols.v1_protocol import encode_local_payload
|
|
8
|
-
from ..roborock_message import RoborockMessage, RoborockMessageProtocol
|
|
9
|
-
from ..util import RoborockLoggerAdapter
|
|
10
|
-
from .roborock_client_v1 import CLOUD_REQUIRED, RoborockClientV1
|
|
11
|
-
|
|
12
|
-
_LOGGER = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class RoborockLocalClientV1(RoborockLocalClient, RoborockClientV1):
|
|
16
|
-
"""Roborock local client for v1 devices."""
|
|
17
|
-
|
|
18
|
-
def __init__(self, device_data: DeviceData, queue_timeout: int = 4):
|
|
19
|
-
"""Initialize the Roborock local client."""
|
|
20
|
-
RoborockLocalClient.__init__(self, device_data)
|
|
21
|
-
RoborockClientV1.__init__(self, device_data, "abc")
|
|
22
|
-
self.queue_timeout = queue_timeout
|
|
23
|
-
self._logger = RoborockLoggerAdapter(device_data.device.name, _LOGGER)
|
|
24
|
-
|
|
25
|
-
async def _send_command(
|
|
26
|
-
self,
|
|
27
|
-
method: RoborockCommand | str,
|
|
28
|
-
params: list | dict | int | None = None,
|
|
29
|
-
):
|
|
30
|
-
if method in CLOUD_REQUIRED:
|
|
31
|
-
raise RoborockException(f"Method {method} is not supported over local connection")
|
|
32
|
-
|
|
33
|
-
roborock_message = encode_local_payload(method, params)
|
|
34
|
-
self._logger.debug("Building message id %s for method %s", roborock_message.get_request_id(), method)
|
|
35
|
-
return await self.send_message(roborock_message)
|
|
36
|
-
|
|
37
|
-
async def send_message(self, roborock_message: RoborockMessage):
|
|
38
|
-
await self.validate_connection()
|
|
39
|
-
method = roborock_message.get_method()
|
|
40
|
-
params = roborock_message.get_params()
|
|
41
|
-
request_id: int | None
|
|
42
|
-
if not method or not method.startswith("get"):
|
|
43
|
-
request_id = roborock_message.seq
|
|
44
|
-
response_protocol = request_id + 1
|
|
45
|
-
else:
|
|
46
|
-
request_id = roborock_message.get_request_id()
|
|
47
|
-
response_protocol = RoborockMessageProtocol.GENERAL_REQUEST
|
|
48
|
-
if request_id is None:
|
|
49
|
-
raise RoborockException(f"Failed build message {roborock_message}")
|
|
50
|
-
msg = self._encoder(roborock_message)
|
|
51
|
-
if method:
|
|
52
|
-
self._logger.debug(f"id={request_id} Requesting method {method} with {params}")
|
|
53
|
-
# Send the command to the Roborock device
|
|
54
|
-
async_response = self._async_response(request_id, response_protocol)
|
|
55
|
-
self._send_msg_raw(msg)
|
|
56
|
-
diagnostic_key = method if method is not None else "unknown"
|
|
57
|
-
try:
|
|
58
|
-
response = await async_response
|
|
59
|
-
except VacuumError as err:
|
|
60
|
-
self._diagnostic_data[diagnostic_key] = {
|
|
61
|
-
"params": roborock_message.get_params(),
|
|
62
|
-
"error": err,
|
|
63
|
-
}
|
|
64
|
-
raise CommandVacuumError(method, err) from err
|
|
65
|
-
self._diagnostic_data[diagnostic_key] = {
|
|
66
|
-
"params": roborock_message.get_params(),
|
|
67
|
-
"response": response,
|
|
68
|
-
}
|
|
69
|
-
if roborock_message.protocol == RoborockMessageProtocol.GENERAL_REQUEST:
|
|
70
|
-
self._logger.debug(f"id={request_id} Response from method {roborock_message.get_method()}: {response}")
|
|
71
|
-
if response == "retry":
|
|
72
|
-
raise RoborockException(f"Command {method} failed with 'retry' message; Device is busy, try again later")
|
|
73
|
-
return response
|
|
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
|
|
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-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/roborock_client_v1.py
RENAMED
|
File without changes
|
{python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/roborock_mqtt_client_v1.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/roborock_client_a01.py
RENAMED
|
File without changes
|
|
File without changes
|