python-roborock 0.6.14__tar.gz → 0.6.15__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-roborock
3
- Version: 0.6.14
3
+ Version: 0.6.15
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 = "0.6.14"
3
+ version = "0.6.15"
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"
@@ -40,6 +40,7 @@ from .exceptions import RoborockException, RoborockTimeout, VacuumError
40
40
  from .roborock_future import RoborockFuture
41
41
  from .roborock_message import RoborockMessage
42
42
  from .typing import RoborockCommand, RoborockDeviceProp, RoborockDockSummary
43
+ from .util import unpack_list
43
44
 
44
45
  _LOGGER = logging.getLogger(__name__)
45
46
  QUEUE_TIMEOUT = 4
@@ -190,6 +191,14 @@ class RoborockClient:
190
191
  clean_summary = await self.send_command(device_id, RoborockCommand.GET_CLEAN_SUMMARY)
191
192
  if isinstance(clean_summary, dict):
192
193
  return CleanSummary.from_dict(clean_summary)
194
+ elif isinstance(clean_summary, list):
195
+ clean_time, clean_area, clean_count, records = unpack_list(clean_summary, 4)
196
+ return CleanSummary(
197
+ clean_time=clean_time,
198
+ clean_area=clean_area,
199
+ clean_count=clean_count,
200
+ records=records
201
+ )
193
202
  elif isinstance(clean_summary, int):
194
203
  return CleanSummary(clean_time=clean_summary)
195
204
  except RoborockTimeout as e:
@@ -244,6 +253,7 @@ class RoborockClient:
244
253
  async def get_dock_summary(self, device_id: str, dock_type: RoborockEnum) -> RoborockDockSummary | None:
245
254
  """Gets the status summary from the dock with the methods available for a given dock.
246
255
 
256
+ :param device_id: Device id
247
257
  :param dock_type: RoborockDockTypeCode"""
248
258
  try:
249
259
  commands: list[
@@ -258,9 +268,7 @@ class RoborockClient:
258
268
  self.get_wash_towel_mode(device_id),
259
269
  self.get_smart_wash_params(device_id),
260
270
  ]
261
- [dust_collection_mode, wash_towel_mode, smart_wash_params] = (
262
- list(await asyncio.gather(*commands)) + [None, None]
263
- )[:3]
271
+ [dust_collection_mode, wash_towel_mode, smart_wash_params] = unpack_list(list(await asyncio.gather(*commands)), 3)
264
272
 
265
273
  return RoborockDockSummary(dust_collection_mode, wash_towel_mode, smart_wash_params)
266
274
  except RoborockTimeout as e:
@@ -47,9 +47,11 @@ def decamelize_obj(d: dict | list, ignore_keys: list[str]):
47
47
 
48
48
  @dataclass
49
49
  class RoborockBase:
50
+ _ignore_keys = [] # type: ignore
51
+
50
52
  @classmethod
51
53
  def from_dict(cls, data: dict[str, Any]):
52
- ignore_keys = cls._ignore_keys if hasattr(cls, "_ignore_keys") else []
54
+ ignore_keys = cls._ignore_keys
53
55
  return from_dict(cls, decamelize_obj(data, ignore_keys), config=Config(cast=[Enum]))
54
56
 
55
57
  def as_dict(self) -> dict:
@@ -60,7 +60,7 @@ class RoborockMessage:
60
60
  return data_point_response.get("method")
61
61
  return None
62
62
 
63
- def get_params(self) -> list | None:
63
+ def get_params(self) -> list | dict | None:
64
64
  protocol = self.protocol
65
65
  if protocol in [4, 101, 102]:
66
66
  payload = json.loads(self.payload.decode())
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing
3
+ from typing import Optional
4
4
  from dataclasses import dataclass
5
5
  from enum import Enum
6
6
 
@@ -117,6 +117,12 @@ class RoborockCommand(str, Enum):
117
117
  GET_ROOM_MAPPING = "get_room_mapping"
118
118
  NAME_SEGMENT = "name_segment"
119
119
  SET_TIMEZONE = "set_timezone"
120
+ GET_HOMESEC_CONNECT_STATUS = "get_homesec_connect_status"
121
+ START_CAMERA_PREVIEW = "start_camera_preview"
122
+ GET_TURN_SERVER = "get_turn_server"
123
+ GET_DEVICE_ICE = "get_device_ice"
124
+ START_VOICE_CHAT = "start_voice_chat"
125
+ SEND_SDP_TO_ROBOT = "send_sdp_to_robot"
120
126
 
121
127
 
122
128
  @dataclass
@@ -200,7 +206,11 @@ CommandInfoMap: dict[RoborockCommand, CommandInfo] = {
200
206
  RoborockCommand.SET_SERVER_TIMER: CommandInfo(prefix=b"\x00\x00\x00\xc7"),
201
207
  RoborockCommand.GET_ROOM_MAPPING: CommandInfo(prefix=b"\x00\x00\x00w"),
202
208
  RoborockCommand.NAME_SEGMENT: CommandInfo(prefix=b"\x00\x00\x027"),
203
- RoborockCommand.SET_TIMEZONE: CommandInfo(prefix=b"\x00\x00\x00\x97")
209
+ RoborockCommand.SET_TIMEZONE: CommandInfo(prefix=b"\x00\x00\x00\x97"),
210
+ RoborockCommand.GET_HOMESEC_CONNECT_STATUS: CommandInfo(prefix=b"\x00\x00\x00\x87"),
211
+ RoborockCommand.START_CAMERA_PREVIEW: CommandInfo(prefix=b"\x00\x00\x00\x87"),
212
+ RoborockCommand.GET_TURN_SERVER: CommandInfo(prefix=b"\x00\x00\x00\x77"),
213
+ RoborockCommand.GET_DEVICE_ICE: CommandInfo(prefix=b"\x00\x00\x00\x77"),
204
214
  # TODO discover prefix for following commands
205
215
  # RoborockCommand.APP_GET_DRYER_SETTING: CommandInfo(prefix=b'\x00\x00\x00w'),
206
216
  # RoborockCommand.APP_SET_DRYER_SETTING: CommandInfo(prefix=b'\x00\x00\x00w'),
@@ -214,26 +224,21 @@ CommandInfoMap: dict[RoborockCommand, CommandInfo] = {
214
224
  }
215
225
 
216
226
 
227
+ @dataclass
217
228
  class RoborockDockSummary:
218
- def __init__(
219
- self,
220
- dust_collection_mode: DustCollectionMode,
221
- wash_towel_mode: WashTowelMode,
222
- smart_wash_params: SmartWashParams,
223
- ) -> None:
224
- self.dust_collection_mode = dust_collection_mode
225
- self.wash_towel_mode = wash_towel_mode
226
- self.smart_wash_params = smart_wash_params
229
+ dust_collection_mode: Optional[DustCollectionMode] = None
230
+ wash_towel_mode: Optional[WashTowelMode] = None
231
+ smart_wash_params: Optional[SmartWashParams] = None
227
232
 
228
233
 
229
234
  @dataclass
230
235
  class RoborockDeviceProp:
231
- status: typing.Optional[Status] = None
232
- dnd_timer: typing.Optional[DNDTimer] = None
233
- clean_summary: typing.Optional[CleanSummary] = None
234
- consumable: typing.Optional[Consumable] = None
235
- last_clean_record: typing.Optional[CleanRecord] = None
236
- dock_summary: typing.Optional[RoborockDockSummary] = None
236
+ status: Optional[Status] = None
237
+ dnd_timer: Optional[DNDTimer] = None
238
+ clean_summary: Optional[CleanSummary] = None
239
+ consumable: Optional[Consumable] = None
240
+ last_clean_record: Optional[CleanRecord] = None
241
+ dock_summary: Optional[RoborockDockSummary] = None
237
242
 
238
243
  def update(self, device_prop: "RoborockDeviceProp"):
239
244
  if device_prop.status:
@@ -1,7 +1,14 @@
1
+ from __future__ import annotations
2
+
1
3
  import asyncio
2
4
  import functools
3
5
  from asyncio import AbstractEventLoop
6
+ from typing import TypeVar
7
+
8
+ T = TypeVar("T")
4
9
 
10
+ def unpack_list(value: list[T], size: int) -> list[T | None]:
11
+ return (value + [None] * size)[:size]
5
12
 
6
13
  def get_running_loop_or_create_one() -> AbstractEventLoop:
7
14
  try: