python-roborock 2.9.2__tar.gz → 2.9.3__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 (28) hide show
  1. {python_roborock-2.9.2 → python_roborock-2.9.3}/PKG-INFO +1 -1
  2. {python_roborock-2.9.2 → python_roborock-2.9.3}/pyproject.toml +1 -1
  3. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/api.py +0 -9
  4. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/cloud_api.py +0 -9
  5. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_1_apis/roborock_client_v1.py +21 -9
  6. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_a01_apis/roborock_client_a01.py +3 -1
  7. {python_roborock-2.9.2 → python_roborock-2.9.3}/LICENSE +0 -0
  8. {python_roborock-2.9.2 → python_roborock-2.9.3}/README.md +0 -0
  9. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/__init__.py +0 -0
  10. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/cli.py +0 -0
  11. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/code_mappings.py +0 -0
  12. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/command_cache.py +0 -0
  13. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/const.py +0 -0
  14. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/containers.py +0 -0
  15. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/exceptions.py +0 -0
  16. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/local_api.py +0 -0
  17. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/protocol.py +0 -0
  18. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/py.typed +0 -0
  19. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/roborock_future.py +0 -0
  20. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/roborock_message.py +0 -0
  21. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/roborock_typing.py +0 -0
  22. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/util.py +0 -0
  23. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_1_apis/__init__.py +0 -0
  24. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
  25. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  26. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_a01_apis/__init__.py +0 -0
  27. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
  28. {python_roborock-2.9.2 → python_roborock-2.9.3}/roborock/web_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: python-roborock
3
- Version: 2.9.2
3
+ Version: 2.9.3
4
4
  Summary: A package to control Roborock vacuums.
5
5
  License: GPL-3.0-only
6
6
  Keywords: roborock,vacuum,homeassistant
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "python-roborock"
3
- version = "2.9.2"
3
+ version = "2.9.3"
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"
@@ -21,7 +21,6 @@ from .roborock_future import RoborockFuture
21
21
  from .roborock_message import (
22
22
  RoborockMessage,
23
23
  )
24
- from .roborock_typing import RoborockCommand
25
24
  from .util import get_next_int, get_running_loop_or_create_one
26
25
 
27
26
  _LOGGER = logging.getLogger(__name__)
@@ -124,11 +123,3 @@ class RoborockClient(ABC):
124
123
  @abstractmethod
125
124
  async def send_message(self, roborock_message: RoborockMessage):
126
125
  """Send a message to the Roborock device."""
127
-
128
- @abstractmethod
129
- async def _send_command(
130
- self,
131
- method: RoborockCommand | str,
132
- params: list | dict | int | None = None,
133
- ):
134
- """Send a command to the Roborock device."""
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import logging
4
4
  import threading
5
- import uuid
6
5
  from abc import ABC
7
6
  from asyncio import Lock
8
7
  from typing import Any
@@ -29,16 +28,10 @@ class _Mqtt(mqtt.Client):
29
28
  """
30
29
 
31
30
  _thread: threading.Thread
32
- _client_id: str
33
31
 
34
32
  def __init__(self) -> None:
35
33
  """Initialize the MQTT client."""
36
34
  super().__init__(protocol=mqtt.MQTTv5)
37
- self.reset_client_id()
38
-
39
- def reset_client_id(self):
40
- """Generate a new client id to make a new session when reconnecting."""
41
- self._client_id = mqtt.base62(uuid.uuid4().int, padding=22)
42
35
 
43
36
  def maybe_restart_loop(self) -> None:
44
37
  """Ensure that the MQTT loop is running in case it previously exited."""
@@ -116,8 +109,6 @@ class RoborockMqttClient(RoborockClient, ABC):
116
109
  try:
117
110
  exc = RoborockException(mqtt.error_string(rc)) if rc != mqtt.MQTT_ERR_SUCCESS else None
118
111
  super().on_connection_lost(exc)
119
- if rc == mqtt.MQTT_ERR_PROTOCOL:
120
- self._mqtt_client.reset_client_id()
121
112
  connection_queue = self._waiting_queue.get(DISCONNECT_REQUEST_ID)
122
113
  if connection_queue:
123
114
  connection_queue.set_result(True)
@@ -4,7 +4,7 @@ import json
4
4
  import math
5
5
  import struct
6
6
  import time
7
- from abc import ABC
7
+ from abc import ABC, abstractmethod
8
8
  from collections.abc import Callable, Coroutine
9
9
  from typing import Any, TypeVar, final
10
10
 
@@ -78,12 +78,15 @@ RT = TypeVar("RT", bound=RoborockBase)
78
78
  EVICT_TIME = 60
79
79
 
80
80
 
81
+ _SendCommandT = Callable[[RoborockCommand | str, list | dict | int | None], Any]
82
+
83
+
81
84
  class AttributeCache:
82
- def __init__(self, attribute: RoborockAttribute, api: RoborockClient):
85
+ def __init__(self, attribute: RoborockAttribute, loop: asyncio.AbstractEventLoop, send_command: _SendCommandT):
83
86
  self.attribute = attribute
84
- self.api = api
87
+ self._send_command = send_command
85
88
  self.attribute = attribute
86
- self.task = RepeatableTask(self.api.event_loop, self._async_value, EVICT_TIME)
89
+ self.task = RepeatableTask(loop, self._async_value, EVICT_TIME)
87
90
  self._value: Any = None
88
91
  self._mutex = asyncio.Lock()
89
92
  self.unsupported: bool = False
@@ -96,7 +99,7 @@ class AttributeCache:
96
99
  if self.unsupported:
97
100
  return None
98
101
  try:
99
- self._value = await self.api._send_command(self.attribute.get_command)
102
+ self._value = await self._send_command(self.attribute.get_command, None)
100
103
  except UnknownMethodError as err:
101
104
  # Limit the amount of times we call unsupported methods
102
105
  self.unsupported = True
@@ -115,21 +118,21 @@ class AttributeCache:
115
118
  async def update_value(self, params) -> None:
116
119
  if self.attribute.set_command is None:
117
120
  raise RoborockException(f"{self.attribute.attribute} have no set command")
118
- response = await self.api._send_command(self.attribute.set_command, params)
121
+ response = await self._send_command(self.attribute.set_command, params)
119
122
  await self._async_value()
120
123
  return response
121
124
 
122
125
  async def add_value(self, params):
123
126
  if self.attribute.add_command is None:
124
127
  raise RoborockException(f"{self.attribute.attribute} have no add command")
125
- response = await self.api._send_command(self.attribute.add_command, params)
128
+ response = await self._send_command(self.attribute.add_command, params)
126
129
  await self._async_value()
127
130
  return response
128
131
 
129
132
  async def close_value(self, params=None) -> None:
130
133
  if self.attribute.close_command is None:
131
134
  raise RoborockException(f"{self.attribute.attribute} have no close command")
132
- response = await self.api._send_command(self.attribute.close_command, params)
135
+ response = await self._send_command(self.attribute.close_command, params)
133
136
  await self._async_value()
134
137
  return response
135
138
 
@@ -153,7 +156,8 @@ class RoborockClientV1(RoborockClient, ABC):
153
156
  super().__init__(device_info)
154
157
  self._status_type: type[Status] = ModelStatus.get(device_info.model, S7MaxVStatus)
155
158
  self.cache: dict[CacheableAttribute, AttributeCache] = {
156
- cacheable_attribute: AttributeCache(attr, self) for cacheable_attribute, attr in get_cache_map().items()
159
+ cacheable_attribute: AttributeCache(attr, self.event_loop, self._send_command)
160
+ for cacheable_attribute, attr in get_cache_map().items()
157
161
  }
158
162
  if device_info.device.duid not in self._listeners:
159
163
  self._listeners[device_info.device.duid] = ListenerModel({}, self.cache)
@@ -364,6 +368,14 @@ class RoborockClientV1(RoborockClient, ABC):
364
368
  )
365
369
  return request_id, timestamp, payload
366
370
 
371
+ @abstractmethod
372
+ async def _send_command(
373
+ self,
374
+ method: RoborockCommand | str,
375
+ params: list | dict | int | None = None,
376
+ ) -> Any:
377
+ """Send a command to the Roborock device."""
378
+
367
379
  def on_message_received(self, messages: list[RoborockMessage]) -> None:
368
380
  try:
369
381
  self._last_device_msg_in = time.monotonic()
@@ -123,10 +123,12 @@ class RoborockClientA01(RoborockClient, ABC):
123
123
  payload = message.payload
124
124
  try:
125
125
  payload = unpad(payload, AES.block_size)
126
- except Exception:
126
+ except Exception as err:
127
+ self._logger.debug("Failed to unpad payload: %s", err)
127
128
  continue
128
129
  payload_json = json.loads(payload.decode())
129
130
  for data_point_number, data_point in payload_json.get("dps").items():
131
+ self._logger.debug("data point number=%s", data_point_number)
130
132
  data_point_protocol: RoborockDyadDataProtocol | RoborockZeoProtocol
131
133
  entries: dict
132
134
  if self.category == RoborockCategory.WET_DRY_VAC:
File without changes