python-roborock 2.9.5__tar.gz → 2.9.7__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.5 → python_roborock-2.9.7}/PKG-INFO +1 -1
  2. {python_roborock-2.9.5 → python_roborock-2.9.7}/pyproject.toml +1 -1
  3. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/api.py +4 -11
  4. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/cloud_api.py +7 -5
  5. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/local_api.py +11 -8
  6. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/util.py +3 -3
  7. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_1_apis/roborock_client_v1.py +3 -7
  8. {python_roborock-2.9.5 → python_roborock-2.9.7}/LICENSE +0 -0
  9. {python_roborock-2.9.5 → python_roborock-2.9.7}/README.md +0 -0
  10. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/__init__.py +0 -0
  11. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/cli.py +0 -0
  12. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/code_mappings.py +0 -0
  13. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/command_cache.py +0 -0
  14. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/const.py +0 -0
  15. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/containers.py +0 -0
  16. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/exceptions.py +0 -0
  17. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/protocol.py +0 -0
  18. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/py.typed +0 -0
  19. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/roborock_future.py +0 -0
  20. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/roborock_message.py +0 -0
  21. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/roborock_typing.py +0 -0
  22. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_1_apis/__init__.py +0 -0
  23. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
  24. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  25. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_a01_apis/__init__.py +0 -0
  26. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
  27. {python_roborock-2.9.5 → python_roborock-2.9.7}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
  28. {python_roborock-2.9.5 → python_roborock-2.9.7}/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.5
3
+ Version: 2.9.7
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.5"
3
+ version = "2.9.7"
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,7 @@ from .roborock_future import RoborockFuture
21
21
  from .roborock_message import (
22
22
  RoborockMessage,
23
23
  )
24
- from .util import get_next_int, get_running_loop_or_create_one
24
+ from .util import get_next_int
25
25
 
26
26
  _LOGGER = logging.getLogger(__name__)
27
27
  KEEPALIVE = 60
@@ -35,7 +35,6 @@ class RoborockClient(ABC):
35
35
 
36
36
  def __init__(self, device_info: DeviceData) -> None:
37
37
  """Initialize RoborockClient."""
38
- self.event_loop = get_running_loop_or_create_one()
39
38
  self.device_info = device_info
40
39
  self._nonce = secrets.token_bytes(16)
41
40
  self._waiting_queue: dict[int, RoborockFuture] = {}
@@ -47,12 +46,6 @@ class RoborockClient(ABC):
47
46
  }
48
47
  self.is_available: bool = True
49
48
 
50
- def __del__(self) -> None:
51
- self.release()
52
-
53
- def release(self) -> None:
54
- self.sync_disconnect()
55
-
56
49
  async def async_release(self) -> None:
57
50
  await self.async_disconnect()
58
51
 
@@ -65,12 +58,12 @@ class RoborockClient(ABC):
65
58
  """Connect to the Roborock device."""
66
59
 
67
60
  @abstractmethod
68
- def sync_disconnect(self) -> Any:
61
+ async def async_disconnect(self) -> Any:
69
62
  """Disconnect from the Roborock device."""
70
63
 
71
64
  @abstractmethod
72
- async def async_disconnect(self) -> Any:
73
- """Disconnect from the Roborock device."""
65
+ def is_connected(self) -> bool:
66
+ """Return True if the client is connected to the device."""
74
67
 
75
68
  @abstractmethod
76
69
  def on_message_received(self, messages: list[RoborockMessage]) -> None:
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
3
4
  import logging
4
5
  import threading
5
6
  from abc import ABC
@@ -121,7 +122,7 @@ class RoborockMqttClient(RoborockClient, ABC):
121
122
  """Check if the mqtt client is connected."""
122
123
  return self._mqtt_client.is_connected()
123
124
 
124
- def sync_disconnect(self) -> Any:
125
+ def _sync_disconnect(self) -> Any:
125
126
  if not self.is_connected():
126
127
  return None
127
128
 
@@ -139,7 +140,7 @@ class RoborockMqttClient(RoborockClient, ABC):
139
140
 
140
141
  return disconnected_future
141
142
 
142
- def sync_connect(self) -> Any:
143
+ def _sync_connect(self) -> Any:
143
144
  if self.is_connected():
144
145
  self._mqtt_client.maybe_restart_loop()
145
146
  return None
@@ -155,14 +156,15 @@ class RoborockMqttClient(RoborockClient, ABC):
155
156
 
156
157
  async def async_disconnect(self) -> None:
157
158
  async with self._mutex:
158
- if disconnected_future := self.sync_disconnect():
159
+ if disconnected_future := self._sync_disconnect():
159
160
  # There are no errors set on this future
160
161
  await disconnected_future
161
- await self.event_loop.run_in_executor(None, self._mqtt_client.loop_stop)
162
+ loop = asyncio.get_running_loop()
163
+ await loop.run_in_executor(None, self._mqtt_client.loop_stop)
162
164
 
163
165
  async def async_connect(self) -> None:
164
166
  async with self._mutex:
165
- if connected_future := self.sync_connect():
167
+ if connected_future := self._sync_connect():
166
168
  try:
167
169
  await connected_future
168
170
  except VacuumError as err:
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import logging
5
5
  from abc import ABC
6
- from asyncio import Lock, TimerHandle, Transport
6
+ from asyncio import Lock, TimerHandle, Transport, get_running_loop
7
7
  from collections.abc import Callable
8
8
  from dataclasses import dataclass
9
9
 
@@ -61,7 +61,7 @@ class RoborockLocalClient(RoborockClient, ABC):
61
61
 
62
62
  def _connection_lost(self, exc: Exception | None):
63
63
  """Called when the transport connection is lost."""
64
- self.sync_disconnect()
64
+ self._sync_disconnect()
65
65
  self.on_connection_lost(exc)
66
66
 
67
67
  def is_connected(self):
@@ -72,17 +72,19 @@ class RoborockLocalClient(RoborockClient, ABC):
72
72
  await self.ping()
73
73
  except RoborockException:
74
74
  pass
75
- self.keep_alive_task = self.event_loop.call_later(10, lambda: asyncio.create_task(self.keep_alive_func()))
75
+ loop = asyncio.get_running_loop()
76
+ self.keep_alive_task = loop.call_later(10, lambda: asyncio.create_task(self.keep_alive_func()))
76
77
 
77
78
  async def async_connect(self) -> None:
78
79
  should_ping = False
79
80
  async with self._mutex:
80
81
  try:
81
82
  if not self.is_connected():
82
- self.sync_disconnect()
83
+ self._sync_disconnect()
83
84
  async with async_timeout.timeout(self.queue_timeout):
84
85
  self._logger.debug(f"Connecting to {self.host}")
85
- self.transport, _ = await self.event_loop.create_connection( # type: ignore
86
+ loop = get_running_loop()
87
+ self.transport, _ = await loop.create_connection( # type: ignore
86
88
  lambda: self._local_protocol, self.host, 58867
87
89
  )
88
90
  self._logger.info(f"Connected to {self.host}")
@@ -93,8 +95,9 @@ class RoborockLocalClient(RoborockClient, ABC):
93
95
  await self.hello()
94
96
  await self.keep_alive_func()
95
97
 
96
- def sync_disconnect(self) -> None:
97
- if self.transport and self.event_loop.is_running():
98
+ def _sync_disconnect(self) -> None:
99
+ loop = asyncio.get_running_loop()
100
+ if self.transport and loop.is_running():
98
101
  self._logger.debug(f"Disconnecting from {self.host}")
99
102
  self.transport.close()
100
103
  if self.keep_alive_task:
@@ -102,7 +105,7 @@ class RoborockLocalClient(RoborockClient, ABC):
102
105
 
103
106
  async def async_disconnect(self) -> None:
104
107
  async with self._mutex:
105
- self.sync_disconnect()
108
+ self._sync_disconnect()
106
109
 
107
110
  async def hello(self):
108
111
  request_id = 1
@@ -74,8 +74,7 @@ def run_sync():
74
74
 
75
75
 
76
76
  class RepeatableTask:
77
- def __init__(self, loop: AbstractEventLoop, callback: Callable[[], Coroutine], interval: int):
78
- self.loop = loop
77
+ def __init__(self, callback: Callable[[], Coroutine], interval: int):
79
78
  self.callback = callback
80
79
  self.interval = interval
81
80
  self._task: TimerHandle | None = None
@@ -86,7 +85,8 @@ class RepeatableTask:
86
85
  response = await self.callback()
87
86
  except RoborockException:
88
87
  pass
89
- self._task = self.loop.call_later(self.interval, self._run_task_soon)
88
+ loop = asyncio.get_running_loop()
89
+ self._task = loop.call_later(self.interval, self._run_task_soon)
90
90
  return response
91
91
 
92
92
  def _run_task_soon(self):
@@ -82,11 +82,11 @@ _SendCommandT = Callable[[RoborockCommand | str, list | dict | int | None], Any]
82
82
 
83
83
 
84
84
  class AttributeCache:
85
- def __init__(self, attribute: RoborockAttribute, loop: asyncio.AbstractEventLoop, send_command: _SendCommandT):
85
+ def __init__(self, attribute: RoborockAttribute, send_command: _SendCommandT):
86
86
  self.attribute = attribute
87
87
  self._send_command = send_command
88
88
  self.attribute = attribute
89
- self.task = RepeatableTask(loop, self._async_value, EVICT_TIME)
89
+ self.task = RepeatableTask(self._async_value, EVICT_TIME)
90
90
  self._value: Any = None
91
91
  self._mutex = asyncio.Lock()
92
92
  self.unsupported: bool = False
@@ -156,7 +156,7 @@ class RoborockClientV1(RoborockClient, ABC):
156
156
  super().__init__(device_info)
157
157
  self._status_type: type[Status] = ModelStatus.get(device_info.model, S7MaxVStatus)
158
158
  self.cache: dict[CacheableAttribute, AttributeCache] = {
159
- cacheable_attribute: AttributeCache(attr, self.event_loop, self._send_command)
159
+ cacheable_attribute: AttributeCache(attr, self._send_command)
160
160
  for cacheable_attribute, attr in get_cache_map().items()
161
161
  }
162
162
  if device_info.device.duid not in self._listeners:
@@ -164,10 +164,6 @@ class RoborockClientV1(RoborockClient, ABC):
164
164
  self.listener_model = self._listeners[device_info.device.duid]
165
165
  self._endpoint = endpoint
166
166
 
167
- def release(self):
168
- super().release()
169
- [item.stop() for item in self.cache.values()]
170
-
171
167
  async def async_release(self) -> None:
172
168
  await super().async_release()
173
169
  [item.stop() for item in self.cache.values()]
File without changes