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.
Files changed (53) hide show
  1. {python_roborock-2.34.1 → python_roborock-2.34.2}/PKG-INFO +1 -1
  2. {python_roborock-2.34.1 → python_roborock-2.34.2}/pyproject.toml +1 -1
  3. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/api.py +0 -4
  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
  5. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +3 -3
  6. python_roborock-2.34.1/roborock/version_1_apis/roborock_local_client_v1.py +0 -73
  7. {python_roborock-2.34.1 → python_roborock-2.34.2}/LICENSE +0 -0
  8. {python_roborock-2.34.1 → python_roborock-2.34.2}/README.md +0 -0
  9. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/__init__.py +0 -0
  10. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/cli.py +0 -0
  11. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/cloud_api.py +0 -0
  12. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/code_mappings.py +0 -0
  13. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/command_cache.py +0 -0
  14. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/const.py +0 -0
  15. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/containers.py +0 -0
  16. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/device_features.py +0 -0
  17. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/README.md +0 -0
  18. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/__init__.py +0 -0
  19. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/a01_channel.py +0 -0
  20. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/b01_channel.py +0 -0
  21. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/cache.py +0 -0
  22. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/channel.py +0 -0
  23. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/device.py +0 -0
  24. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/device_manager.py +0 -0
  25. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/local_channel.py +0 -0
  26. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/mqtt_channel.py +0 -0
  27. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/b01/__init__.py +0 -0
  28. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/b01/props.py +0 -0
  29. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/dyad.py +0 -0
  30. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/status.py +0 -0
  31. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/trait.py +0 -0
  32. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/traits/zeo.py +0 -0
  33. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/v1_channel.py +0 -0
  34. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/devices/v1_rpc_channel.py +0 -0
  35. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/exceptions.py +0 -0
  36. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/mqtt/__init__.py +0 -0
  37. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/mqtt/roborock_session.py +0 -0
  38. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/mqtt/session.py +0 -0
  39. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocol.py +0 -0
  40. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocols/a01_protocol.py +0 -0
  41. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocols/b01_protocol.py +0 -0
  42. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/protocols/v1_protocol.py +0 -0
  43. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/py.typed +0 -0
  44. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/roborock_future.py +0 -0
  45. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/roborock_message.py +0 -0
  46. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/roborock_typing.py +0 -0
  47. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/util.py +0 -0
  48. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/__init__.py +0 -0
  49. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/roborock_client_v1.py +0 -0
  50. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  51. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/__init__.py +0 -0
  52. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
  53. {python_roborock-2.34.1 → python_roborock-2.34.2}/roborock/web_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-roborock
3
- Version: 2.34.1
3
+ Version: 2.34.2
4
4
  Summary: A package to control Roborock vacuums.
5
5
  Home-page: https://github.com/humbertogontijo/python-roborock
6
6
  License: GPL-3.0-only
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-roborock"
3
- version = "2.34.1"
3
+ version = "2.34.2"
4
4
  description = "A package to control Roborock vacuums."
5
5
  authors = ["humbertogontijo <humbertogontijo@users.noreply.github.com>"]
6
6
  license = "GPL-3.0-only"
@@ -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 . import DeviceData
13
- from .api import RoborockClient
14
- from .exceptions import RoborockConnectionException, RoborockException
15
- from .protocol import Decoder, Encoder, create_local_decoder, create_local_encoder
16
- from .roborock_message import RoborockMessage, RoborockMessageProtocol
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 RoborockLocalClient(RoborockClient, ABC):
38
- """Roborock local client base class."""
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.send_message(
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.send_message(
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 send_message(self, roborock_message: RoborockMessage):
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.send_message(message)
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.send_message(message)
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