python-roborock 2.29.0__tar.gz → 2.30.0__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 (48) hide show
  1. {python_roborock-2.29.0 → python_roborock-2.30.0}/PKG-INFO +1 -1
  2. {python_roborock-2.29.0 → python_roborock-2.30.0}/pyproject.toml +1 -1
  3. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/containers.py +45 -77
  4. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/device_features.py +139 -1
  5. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/roborock_typing.py +0 -176
  6. {python_roborock-2.29.0 → python_roborock-2.30.0}/LICENSE +0 -0
  7. {python_roborock-2.29.0 → python_roborock-2.30.0}/README.md +0 -0
  8. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/__init__.py +0 -0
  9. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/api.py +0 -0
  10. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/cli.py +0 -0
  11. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/cloud_api.py +0 -0
  12. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/code_mappings.py +0 -0
  13. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/command_cache.py +0 -0
  14. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/const.py +0 -0
  15. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/README.md +0 -0
  16. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/__init__.py +0 -0
  17. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/a01_channel.py +0 -0
  18. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/channel.py +0 -0
  19. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/device.py +0 -0
  20. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/device_manager.py +0 -0
  21. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/local_channel.py +0 -0
  22. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/mqtt_channel.py +0 -0
  23. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/dyad.py +0 -0
  24. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/status.py +0 -0
  25. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/trait.py +0 -0
  26. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/zeo.py +0 -0
  27. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/v1_channel.py +0 -0
  28. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/v1_rpc_channel.py +0 -0
  29. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/exceptions.py +0 -0
  30. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/local_api.py +0 -0
  31. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/mqtt/__init__.py +0 -0
  32. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/mqtt/roborock_session.py +0 -0
  33. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/mqtt/session.py +0 -0
  34. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/protocol.py +0 -0
  35. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/protocols/a01_protocol.py +0 -0
  36. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/protocols/v1_protocol.py +0 -0
  37. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/py.typed +0 -0
  38. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/roborock_future.py +0 -0
  39. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/roborock_message.py +0 -0
  40. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/util.py +0 -0
  41. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/__init__.py +0 -0
  42. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_client_v1.py +0 -0
  43. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
  44. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  45. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/__init__.py +0 -0
  46. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
  47. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
  48. {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/web_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-roborock
3
- Version: 2.29.0
3
+ Version: 2.30.0
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.29.0"
3
+ version = "2.30.0"
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"
@@ -1,9 +1,9 @@
1
- from __future__ import annotations
2
-
1
+ import dataclasses
3
2
  import datetime
4
3
  import json
5
4
  import logging
6
5
  import re
6
+ import types
7
7
  from dataclasses import asdict, dataclass, field
8
8
  from datetime import timezone
9
9
  from enum import Enum
@@ -95,105 +95,73 @@ from .exceptions import RoborockException
95
95
  _LOGGER = logging.getLogger(__name__)
96
96
 
97
97
 
98
- def camelize(s: str):
98
+ def _camelize(s: str):
99
99
  first, *others = s.split("_")
100
100
  if len(others) == 0:
101
101
  return s
102
102
  return "".join([first.lower(), *map(str.title, others)])
103
103
 
104
104
 
105
- def decamelize(s: str):
105
+ def _decamelize(s: str):
106
106
  return re.sub("([A-Z]+)", "_\\1", s).lower()
107
107
 
108
108
 
109
- def decamelize_obj(d: dict | list, ignore_keys: list[str]):
110
- if isinstance(d, RoborockBase):
111
- d = d.as_dict()
112
- if isinstance(d, list):
113
- return [decamelize_obj(i, ignore_keys) if isinstance(i, dict | list) else i for i in d]
114
- return {
115
- (decamelize(a) if a not in ignore_keys else a): decamelize_obj(b, ignore_keys)
116
- if isinstance(b, dict | list)
117
- else b
118
- for a, b in d.items()
119
- }
120
-
121
-
122
109
  @dataclass
123
110
  class RoborockBase:
124
111
  _ignore_keys = [] # type: ignore
125
- is_cached = False
126
112
 
127
113
  @staticmethod
128
- def convert_to_class_obj(type, value):
129
- try:
130
- class_type = eval(type)
131
- if get_origin(class_type) is list:
132
- return_list = []
133
- cls_type = get_args(class_type)[0]
134
- for obj in value:
135
- if issubclass(cls_type, RoborockBase):
136
- return_list.append(cls_type.from_dict(obj))
137
- elif cls_type in {str, int, float}:
138
- return_list.append(cls_type(obj))
139
- else:
140
- return_list.append(cls_type(**obj))
141
- return return_list
142
- if issubclass(class_type, RoborockBase):
143
- converted_value = class_type.from_dict(value)
144
- else:
145
- converted_value = class_type(value)
146
- return converted_value
147
- except NameError as err:
148
- _LOGGER.exception(err)
149
- except ValueError as err:
150
- _LOGGER.exception(err)
151
- except Exception as err:
152
- _LOGGER.exception(err)
153
- raise Exception("Fail")
114
+ def _convert_to_class_obj(class_type: type, value):
115
+ if get_origin(class_type) is list:
116
+ sub_type = get_args(class_type)[0]
117
+ return [RoborockBase._convert_to_class_obj(sub_type, obj) for obj in value]
118
+ if get_origin(class_type) is dict:
119
+ _, value_type = get_args(class_type) # assume keys are only basic types
120
+ return {k: RoborockBase._convert_to_class_obj(value_type, v) for k, v in value.items()}
121
+ if issubclass(class_type, RoborockBase):
122
+ return class_type.from_dict(value)
123
+ if class_type is Any:
124
+ return value
125
+ return class_type(value) # type: ignore[call-arg]
154
126
 
155
127
  @classmethod
156
128
  def from_dict(cls, data: dict[str, Any]):
157
- if isinstance(data, dict):
158
- ignore_keys = cls._ignore_keys
159
- data = decamelize_obj(data, ignore_keys)
160
- cls_annotations: dict[str, str] = {}
161
- for base in reversed(cls.__mro__):
162
- cls_annotations.update(getattr(base, "__annotations__", {}))
163
- remove_keys = []
164
- for key, value in data.items():
165
- if key not in cls_annotations:
166
- remove_keys.append(key)
167
- continue
168
- if value == "None" or value is None:
169
- data[key] = None
170
- continue
171
- field_type: str = cls_annotations[key]
172
- if "|" in field_type:
173
- # It's a union
174
- types = field_type.split("|")
175
- for type in types:
176
- if "None" in type or "Any" in type:
177
- continue
178
- try:
179
- data[key] = RoborockBase.convert_to_class_obj(type, value)
180
- break
181
- except Exception:
182
- ...
183
- else:
129
+ """Create an instance of the class from a dictionary."""
130
+ if not isinstance(data, dict):
131
+ return None
132
+ field_types = {field.name: field.type for field in dataclasses.fields(cls)}
133
+ result: dict[str, Any] = {}
134
+ for key, value in data.items():
135
+ key = _decamelize(key)
136
+ if (field_type := field_types.get(key)) is None:
137
+ continue
138
+ if value == "None" or value is None:
139
+ result[key] = None
140
+ continue
141
+ if isinstance(field_type, types.UnionType):
142
+ for subtype in get_args(field_type):
143
+ if subtype is types.NoneType:
144
+ continue
184
145
  try:
185
- data[key] = RoborockBase.convert_to_class_obj(field_type, value)
146
+ result[key] = RoborockBase._convert_to_class_obj(subtype, value)
147
+ break
186
148
  except Exception:
187
- ...
188
- for key in remove_keys:
189
- del data[key]
190
- return cls(**data)
149
+ _LOGGER.exception(f"Failed to convert {key} with value {value} to type {subtype}")
150
+ continue
151
+ else:
152
+ try:
153
+ result[key] = RoborockBase._convert_to_class_obj(field_type, value)
154
+ except Exception:
155
+ _LOGGER.exception(f"Failed to convert {key} with value {value} to type {field_type}")
156
+ continue
157
+
158
+ return cls(**result)
191
159
 
192
160
  def as_dict(self) -> dict:
193
161
  return asdict(
194
162
  self,
195
163
  dict_factory=lambda _fields: {
196
- camelize(key): value.value if isinstance(value, Enum) else value
164
+ _camelize(key): value.value if isinstance(value, Enum) else value
197
165
  for (key, value) in _fields
198
166
  if value is not None
199
167
  },
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from dataclasses import dataclass, field, fields
4
- from enum import IntEnum
4
+ from enum import IntEnum, StrEnum
5
5
  from typing import Any
6
6
 
7
7
  from roborock import RoborockProductNickname
@@ -59,6 +59,121 @@ class NewFeatureStrBit(IntEnum):
59
59
  EGG_DANCE_MODE = 87
60
60
 
61
61
 
62
+ class ProductFeatures(StrEnum):
63
+ REMOTE_BACK = "remote_back"
64
+ CLEANMODE_MAXPLUS = "cleanmode_maxplus"
65
+ CLEANMODE_PURECLEANMOP = "cleanmode_purecleanmop"
66
+ CLEANMODE_NONE_PURECLEANMOP_WITH_MAXPLUS = "cleanmode_none_purecleanmop_with_maxplus"
67
+ MOP_ELECTRONIC_MODULE = "mop_electronic_module"
68
+ MOP_SHAKE_MODULE = "mop_shake_module"
69
+ MOP_SPIN_MODULE = "mop_spin_module"
70
+ DEFAULT_MAP3D = "map3d"
71
+ DEFAULT_CLEANMODECUSTOM = "custom_cleanmode"
72
+ REALTIMEVIDEO = "realtimevideo"
73
+ REALTIMEVIDEO_LIVECALL = "realtimevideo_livecall"
74
+ REALTIMEVIDEO_RECORDANDSHORTCUT = "realtimevideo_livecall"
75
+ CAMERA_SINGLELINE = "camera_singleline"
76
+ CAMERA_DUALLINE = "camera_dualline"
77
+ CAMERA_RGB = "camera_rgb"
78
+ CAMERA_DOUBLERGB = "camera_doublergb"
79
+ AIRECOGNITION_SETTING = "airecognition_setting"
80
+ AIRECOGNITION_SCENE = "airecognition_scene"
81
+ AIRECOGNITION_PET = "airecognition_pet"
82
+ AIRECOGNITION_OBSTACLE = "airecognition_obstacle"
83
+
84
+
85
+ # The following combinations are pulled directly from decompiled source code.
86
+ AIRECOGNITION_OBSTACLE = [ProductFeatures.AIRECOGNITION_OBSTACLE]
87
+ RGB_CAMERA_FEATURES = [
88
+ ProductFeatures.CAMERA_RGB,
89
+ ProductFeatures.AIRECOGNITION_SETTING,
90
+ ProductFeatures.AIRECOGNITION_SCENE,
91
+ ProductFeatures.AIRECOGNITION_PET,
92
+ ProductFeatures.AIRECOGNITION_OBSTACLE,
93
+ ProductFeatures.REALTIMEVIDEO,
94
+ ProductFeatures.REALTIMEVIDEO_LIVECALL,
95
+ ProductFeatures.REALTIMEVIDEO_RECORDANDSHORTCUT,
96
+ ]
97
+ DOUBLE_RGB_CAMERA_FEATURES = [
98
+ ProductFeatures.CAMERA_DOUBLERGB,
99
+ ProductFeatures.AIRECOGNITION_SETTING,
100
+ ProductFeatures.AIRECOGNITION_PET,
101
+ ProductFeatures.AIRECOGNITION_OBSTACLE,
102
+ ProductFeatures.REALTIMEVIDEO,
103
+ ]
104
+ SINGLE_LINE_CAMERA_FEATURES = [
105
+ ProductFeatures.CAMERA_SINGLELINE,
106
+ ProductFeatures.AIRECOGNITION_SETTING,
107
+ ProductFeatures.AIRECOGNITION_OBSTACLE,
108
+ ]
109
+ DUAL_LINE_CAMERA_FEATURES = [
110
+ ProductFeatures.CAMERA_DUALLINE,
111
+ ProductFeatures.AIRECOGNITION_SETTING,
112
+ ProductFeatures.AIRECOGNITION_OBSTACLE,
113
+ ProductFeatures.AIRECOGNITION_PET,
114
+ ]
115
+
116
+ NEW_DEFAULT_FEATURES = [ProductFeatures.REMOTE_BACK, ProductFeatures.CLEANMODE_MAXPLUS]
117
+
118
+
119
+ PEARL_FEATURES = NEW_DEFAULT_FEATURES + SINGLE_LINE_CAMERA_FEATURES + [ProductFeatures.MOP_SPIN_MODULE]
120
+ PEARL_PLUS_FEATURES = NEW_DEFAULT_FEATURES + RGB_CAMERA_FEATURES + [ProductFeatures.MOP_SPIN_MODULE]
121
+ ULTRON_FEATURES = NEW_DEFAULT_FEATURES + DUAL_LINE_CAMERA_FEATURES + [ProductFeatures.MOP_SHAKE_MODULE]
122
+ ULTRONSV_FEATURES = NEW_DEFAULT_FEATURES + RGB_CAMERA_FEATURES + [ProductFeatures.MOP_SHAKE_MODULE]
123
+ TANOSS_FEATURES = NEW_DEFAULT_FEATURES + [ProductFeatures.MOP_SHAKE_MODULE]
124
+ TOPAZSPOWER_FEATURES = NEW_DEFAULT_FEATURES + [ProductFeatures.MOP_SHAKE_MODULE]
125
+
126
+ product_feature_map = {
127
+ RoborockProductNickname.PEARL: PEARL_FEATURES,
128
+ RoborockProductNickname.PEARLS: PEARL_FEATURES,
129
+ RoborockProductNickname.PEARLPLUS: PEARL_PLUS_FEATURES,
130
+ RoborockProductNickname.VIVIAN: PEARL_PLUS_FEATURES,
131
+ RoborockProductNickname.CORAL: PEARL_PLUS_FEATURES,
132
+ RoborockProductNickname.ULTRON: ULTRON_FEATURES,
133
+ RoborockProductNickname.ULTRONE: [ProductFeatures.CLEANMODE_NONE_PURECLEANMOP_WITH_MAXPLUS],
134
+ RoborockProductNickname.ULTRONSV: ULTRONSV_FEATURES,
135
+ RoborockProductNickname.TOPAZSPOWER: TOPAZSPOWER_FEATURES,
136
+ RoborockProductNickname.TANOSS: TANOSS_FEATURES,
137
+ RoborockProductNickname.PEARLC: PEARL_FEATURES,
138
+ RoborockProductNickname.PEARLPLUSS: PEARL_PLUS_FEATURES,
139
+ RoborockProductNickname.PEARLSLITE: PEARL_FEATURES,
140
+ RoborockProductNickname.PEARLE: PEARL_FEATURES,
141
+ RoborockProductNickname.PEARLELITE: PEARL_FEATURES,
142
+ RoborockProductNickname.VIVIANC: PEARL_PLUS_FEATURES,
143
+ RoborockProductNickname.CORALPRO: PEARL_PLUS_FEATURES,
144
+ RoborockProductNickname.ULTRONLITE: SINGLE_LINE_CAMERA_FEATURES
145
+ + [ProductFeatures.CLEANMODE_NONE_PURECLEANMOP_WITH_MAXPLUS, ProductFeatures.MOP_ELECTRONIC_MODULE],
146
+ RoborockProductNickname.ULTRONSC: ULTRON_FEATURES,
147
+ RoborockProductNickname.ULTRONSE: [
148
+ ProductFeatures.CLEANMODE_NONE_PURECLEANMOP_WITH_MAXPLUS,
149
+ ProductFeatures.MOP_ELECTRONIC_MODULE,
150
+ ],
151
+ RoborockProductNickname.ULTRONSPLUS: ULTRON_FEATURES,
152
+ RoborockProductNickname.VERDELITE: ULTRONSV_FEATURES,
153
+ RoborockProductNickname.TOPAZS: NEW_DEFAULT_FEATURES + [ProductFeatures.MOP_SHAKE_MODULE],
154
+ RoborockProductNickname.TOPAZSPLUS: NEW_DEFAULT_FEATURES
155
+ + DUAL_LINE_CAMERA_FEATURES
156
+ + [ProductFeatures.MOP_SHAKE_MODULE],
157
+ RoborockProductNickname.TOPAZSC: TOPAZSPOWER_FEATURES + SINGLE_LINE_CAMERA_FEATURES,
158
+ RoborockProductNickname.TOPAZSV: NEW_DEFAULT_FEATURES + RGB_CAMERA_FEATURES + [ProductFeatures.MOP_SHAKE_MODULE],
159
+ RoborockProductNickname.TANOSSPLUS: TANOSS_FEATURES + DUAL_LINE_CAMERA_FEATURES,
160
+ RoborockProductNickname.TANOSSLITE: [ProductFeatures.MOP_ELECTRONIC_MODULE],
161
+ RoborockProductNickname.TANOSSC: [],
162
+ RoborockProductNickname.TANOSSE: [],
163
+ RoborockProductNickname.TANOSSMAX: NEW_DEFAULT_FEATURES
164
+ + DUAL_LINE_CAMERA_FEATURES
165
+ + [ProductFeatures.MOP_SHAKE_MODULE],
166
+ RoborockProductNickname.TANOS: [ProductFeatures.REMOTE_BACK],
167
+ RoborockProductNickname.TANOSE: [ProductFeatures.MOP_ELECTRONIC_MODULE, ProductFeatures.REMOTE_BACK],
168
+ RoborockProductNickname.TANOSV: DOUBLE_RGB_CAMERA_FEATURES
169
+ + [ProductFeatures.REMOTE_BACK, ProductFeatures.MOP_ELECTRONIC_MODULE],
170
+ RoborockProductNickname.RUBYPLUS: [],
171
+ RoborockProductNickname.RUBYSC: [],
172
+ RoborockProductNickname.RUBYSE: [],
173
+ RoborockProductNickname.RUBYSLITE: [ProductFeatures.MOP_ELECTRONIC_MODULE],
174
+ }
175
+
176
+
62
177
  @dataclass
63
178
  class DeviceFeatures:
64
179
  """Represents the features supported by a Roborock device."""
@@ -290,6 +405,24 @@ class DeviceFeatures:
290
405
  )
291
406
  is_support_mop_back_pwm_set: bool = field(metadata={"model_whitelist": [RoborockProductNickname.PEARL]})
292
407
  is_collect_dust_mode_supported: bool = field(metadata={"model_blacklist": [RoborockProductNickname.PEARL]})
408
+ is_support_water_mode: bool = field(
409
+ metadata={
410
+ "product_features": [
411
+ ProductFeatures.MOP_ELECTRONIC_MODULE,
412
+ ProductFeatures.MOP_SHAKE_MODULE,
413
+ ProductFeatures.MOP_SPIN_MODULE,
414
+ ]
415
+ }
416
+ )
417
+ is_pure_clean_mop_supported: bool = field(metadata={"product_features": [ProductFeatures.CLEANMODE_PURECLEANMOP]})
418
+ is_new_remote_view_supported: bool = field(metadata={"product_features": [ProductFeatures.REMOTE_BACK]})
419
+ is_max_plus_mode_supported: bool = field(metadata={"product_features": [ProductFeatures.CLEANMODE_MAXPLUS]})
420
+ is_none_pure_clean_mop_with_max_plus: bool = field(
421
+ metadata={"product_features": [ProductFeatures.CLEANMODE_NONE_PURECLEANMOP_WITH_MAXPLUS]}
422
+ )
423
+ is_clean_route_setting_supported: bool = field(
424
+ metadata={"product_features": [ProductFeatures.MOP_SHAKE_MODULE, ProductFeatures.MOP_SPIN_MODULE]}
425
+ )
293
426
 
294
427
  @classmethod
295
428
  def from_feature_flags(
@@ -357,6 +490,11 @@ class DeviceFeatures:
357
490
  kwargs[f.name] = True
358
491
  else:
359
492
  kwargs[f.name] = product_nickname not in blacklist
493
+ elif (product_features := f.metadata.get("product_features")) is not None:
494
+ if product_nickname is not None:
495
+ available_features = product_feature_map.get(product_nickname, [])
496
+ if any(feat in available_features for feat in product_features): # type: ignore
497
+ kwargs[f.name] = True
360
498
 
361
499
  return cls(**kwargs)
362
500
 
@@ -271,182 +271,6 @@ class RoborockCommand(str, Enum):
271
271
  APP_GET_ROBOT_SETTING = "app_get_robot_setting"
272
272
 
273
273
 
274
- @dataclass
275
- class CommandInfo:
276
- params: list | dict | int | None = None
277
-
278
-
279
- CommandInfoMap: dict[RoborockCommand | None, CommandInfo] = {
280
- RoborockCommand.APP_CHARGE: CommandInfo(params=[]),
281
- RoborockCommand.APP_GET_DRYER_SETTING: CommandInfo(params=None),
282
- RoborockCommand.APP_GET_INIT_STATUS: CommandInfo(params=[]),
283
- RoborockCommand.APP_GOTO_TARGET: CommandInfo(params=[25000, 24850]),
284
- RoborockCommand.APP_PAUSE: CommandInfo(params=[]),
285
- RoborockCommand.APP_RC_END: CommandInfo(params=[]),
286
- RoborockCommand.APP_RC_MOVE: CommandInfo(params=None),
287
- RoborockCommand.APP_RC_START: CommandInfo(params=[]),
288
- RoborockCommand.APP_RC_STOP: CommandInfo(params=[]),
289
- RoborockCommand.APP_SEGMENT_CLEAN: CommandInfo(params=[{"segments": 16, "repeat": 2}]),
290
- # RoborockCommand.APP_SEGMENT_CLEAN: CommandInfo(prefix=b"\x00\x00\x00\x87", params=None),
291
- RoborockCommand.APP_SET_DRYER_SETTING: CommandInfo(params=None),
292
- RoborockCommand.APP_SET_SMART_CLIFF_FORBIDDEN: CommandInfo(params={"zones": [], "map_index": 0}),
293
- RoborockCommand.APP_SPOT: CommandInfo(params=[]),
294
- RoborockCommand.APP_START: CommandInfo(params=None),
295
- # RoborockCommand.APP_START: CommandInfo(prefix=b"\x00\x00\x00\x87", params=[{"use_new_map": 1}]),
296
- RoborockCommand.APP_START_COLLECT_DUST: CommandInfo(params=None),
297
- RoborockCommand.APP_START_WASH: CommandInfo(params=None),
298
- RoborockCommand.APP_STAT: CommandInfo(
299
- params=[
300
- {
301
- "ver": "0.1",
302
- "data": [
303
- {
304
- "times": [1682723478],
305
- "data": {
306
- "region": "America/Sao_Paulo",
307
- "pluginVersion": "2820",
308
- "mnc": "*",
309
- "os": "ios",
310
- "osVersion": "16.1",
311
- "mcc": "not-cn",
312
- "language": "en_BR",
313
- "mobileBrand": "*",
314
- "appType": "roborock",
315
- "mobileModel": "iPhone13,1",
316
- },
317
- "type": 2,
318
- }
319
- ],
320
- }
321
- ],
322
- ),
323
- RoborockCommand.APP_STOP: CommandInfo(params=[]),
324
- RoborockCommand.APP_STOP_WASH: CommandInfo(params=None),
325
- RoborockCommand.APP_WAKEUP_ROBOT: CommandInfo(params=[]),
326
- RoborockCommand.APP_ZONED_CLEAN: CommandInfo(params=[[24900, 25100, 26300, 26450, 1]]),
327
- RoborockCommand.CHANGE_SOUND_VOLUME: CommandInfo(params=None),
328
- RoborockCommand.CLOSE_DND_TIMER: CommandInfo(params=[]),
329
- RoborockCommand.CLOSE_VALLEY_ELECTRICITY_TIMER: CommandInfo(params=[]),
330
- RoborockCommand.DNLD_INSTALL_SOUND: CommandInfo(
331
- params={"url": "https://awsusor0.fds.api.xiaomi.com/app/topazsv/voice-pkg/package/en.pkg", "sid": 3, "sver": 5},
332
- ),
333
- RoborockCommand.ENABLE_LOG_UPLOAD: CommandInfo(params=[9, 2]),
334
- RoborockCommand.END_EDIT_MAP: CommandInfo(params=[]),
335
- RoborockCommand.FIND_ME: CommandInfo(params=None),
336
- RoborockCommand.GET_CAMERA_STATUS: CommandInfo(params=[]),
337
- RoborockCommand.GET_CARPET_CLEAN_MODE: CommandInfo(params=[]),
338
- RoborockCommand.GET_CARPET_MODE: CommandInfo(params=[]),
339
- RoborockCommand.GET_CHILD_LOCK_STATUS: CommandInfo(params=[]),
340
- RoborockCommand.GET_CLEAN_RECORD: CommandInfo(params=[1682257961]),
341
- RoborockCommand.GET_CLEAN_RECORD_MAP: CommandInfo(params={"start_time": 1682597877}),
342
- RoborockCommand.GET_CLEAN_SEQUENCE: CommandInfo(params=[]),
343
- RoborockCommand.GET_CLEAN_SUMMARY: CommandInfo(params=[]),
344
- RoborockCommand.GET_COLLISION_AVOID_STATUS: CommandInfo(params=[]),
345
- RoborockCommand.GET_CONSUMABLE: CommandInfo(params=[]),
346
- RoborockCommand.GET_CURRENT_SOUND: CommandInfo(params=[]),
347
- RoborockCommand.GET_CUSTOMIZE_CLEAN_MODE: CommandInfo(params=[]),
348
- RoborockCommand.GET_CUSTOM_MODE: CommandInfo(params=None),
349
- RoborockCommand.GET_DEVICE_ICE: CommandInfo(params=[]),
350
- RoborockCommand.GET_DEVICE_SDP: CommandInfo(params=[]),
351
- RoborockCommand.GET_DND_TIMER: CommandInfo(params=[]),
352
- RoborockCommand.GET_DUST_COLLECTION_MODE: CommandInfo(params=None),
353
- RoborockCommand.GET_FLOW_LED_STATUS: CommandInfo(params=[]),
354
- RoborockCommand.GET_HOMESEC_CONNECT_STATUS: CommandInfo(params=[]),
355
- RoborockCommand.GET_IDENTIFY_FURNITURE_STATUS: CommandInfo(params=[]),
356
- RoborockCommand.GET_IDENTIFY_GROUND_MATERIAL_STATUS: CommandInfo(params=[]),
357
- RoborockCommand.GET_LED_STATUS: CommandInfo(params=[]),
358
- RoborockCommand.GET_MAP_V1: CommandInfo(params={}),
359
- RoborockCommand.GET_MOP_TEMPLATE_PARAMS_SUMMARY: CommandInfo(params={}),
360
- RoborockCommand.GET_MULTI_MAP: CommandInfo(params={"map_index": 0}),
361
- RoborockCommand.GET_MULTI_MAPS_LIST: CommandInfo(params=[]),
362
- RoborockCommand.GET_NETWORK_INFO: CommandInfo(params=[]),
363
- RoborockCommand.GET_PROP: CommandInfo(params=["get_status"]),
364
- RoborockCommand.GET_ROOM_MAPPING: CommandInfo(params=[]),
365
- RoborockCommand.GET_SCENES_VALID_TIDS: CommandInfo(params={}),
366
- RoborockCommand.GET_SERIAL_NUMBER: CommandInfo(params=[]),
367
- RoborockCommand.GET_SERVER_TIMER: CommandInfo(params=[]),
368
- RoborockCommand.GET_SMART_WASH_PARAMS: CommandInfo(params=None),
369
- RoborockCommand.GET_SOUND_PROGRESS: CommandInfo(params=[]),
370
- RoborockCommand.GET_SOUND_VOLUME: CommandInfo(params=[]),
371
- RoborockCommand.GET_STATUS: CommandInfo(params=None),
372
- RoborockCommand.GET_TIMEZONE: CommandInfo(params=[]),
373
- RoborockCommand.GET_TURN_SERVER: CommandInfo(params=[]),
374
- RoborockCommand.GET_VALLEY_ELECTRICITY_TIMER: CommandInfo(params=[]),
375
- RoborockCommand.GET_WASH_TOWEL_MODE: CommandInfo(params=None),
376
- RoborockCommand.LOAD_MULTI_MAP: CommandInfo(params=None),
377
- RoborockCommand.NAME_SEGMENT: CommandInfo(params=None),
378
- RoborockCommand.REUNION_SCENES: CommandInfo(params={"data": [{"tid": "1687830208457"}]}),
379
- RoborockCommand.RESET_CONSUMABLE: CommandInfo(params=None),
380
- RoborockCommand.RESUME_SEGMENT_CLEAN: CommandInfo(params=None),
381
- RoborockCommand.RESUME_ZONED_CLEAN: CommandInfo(params=None),
382
- RoborockCommand.RETRY_REQUEST: CommandInfo(params={"retry_id": 439374, "retry_count": 8, "method": "save_map"}),
383
- RoborockCommand.SAVE_MAP: CommandInfo(
384
- params={
385
- "data": [
386
- [1, 25043, 24952, 26167, 24952],
387
- [0, 25043, 25514, 26167, 25514, 26167, 24390, 25043, 24390],
388
- [2, 25038, 26782, 26162, 26782, 26162, 25658, 25038, 25658],
389
- [100, 0],
390
- ],
391
- "need_retry": 1,
392
- },
393
- ),
394
- RoborockCommand.SEND_ICE_TO_ROBOT: CommandInfo(
395
- params={
396
- "app_ice": "eyJjYW5kaWRhdGUiOiAiY2FuZGlkYXRlOjE1MzE5NzE5NTEgMSB1ZHAgNDE4MTk5MDMgNTQuMTc0LjE4Ni4yNDkgNTQxNzU"
397
- "gdHlwIHJlbGF5IHJhZGRyIDE3Ny4xOC4xMzQuOTkgcnBvcnQgNjQ2OTEgZ2VuZXJhdGlvbiAwIHVmcmFnIDVOMVogbmV0d2"
398
- "9yay1pZCAxIG5ldHdvcmstY29zdCAxMCIsICJzZHBNTGluZUluZGV4IjogMSwgInNkcE1pZCI6ICIxIn0="
399
- },
400
- ),
401
- RoborockCommand.SET_APP_TIMEZONE: CommandInfo(params=["America/Sao_Paulo", 2]),
402
- RoborockCommand.SET_CAMERA_STATUS: CommandInfo(params=[3493]),
403
- RoborockCommand.SET_CARPET_CLEAN_MODE: CommandInfo(params={"carpet_clean_mode": 0}),
404
- RoborockCommand.SET_CARPET_MODE: CommandInfo(
405
- params=[{"enable": 1, "current_high": 500, "current_integral": 450, "current_low": 400, "stall_time": 10}],
406
- ),
407
- RoborockCommand.SET_CHILD_LOCK_STATUS: CommandInfo(params={"lock_status": 0}),
408
- RoborockCommand.SET_CLEAN_MOTOR_MODE: CommandInfo(
409
- params=[{"fan_power": 106, "mop_mode": 302, "water_box_mode": 204}]
410
- ),
411
- RoborockCommand.SET_COLLISION_AVOID_STATUS: CommandInfo(params={"status": 1}),
412
- RoborockCommand.SET_CUSTOMIZE_CLEAN_MODE: CommandInfo(params={"data": [], "need_retry": 1}),
413
- RoborockCommand.SET_CUSTOM_MODE: CommandInfo(params=[108]),
414
- RoborockCommand.SET_DND_TIMER: CommandInfo(params=[22, 0, 8, 0]),
415
- RoborockCommand.SET_DUST_COLLECTION_MODE: CommandInfo(params=None),
416
- RoborockCommand.SET_FDS_ENDPOINT: CommandInfo(params=["awsusor0.fds.api.xiaomi.com"]),
417
- RoborockCommand.SET_FLOW_LED_STATUS: CommandInfo(params={"status": 1}),
418
- RoborockCommand.SET_IDENTIFY_FURNITURE_STATUS: CommandInfo(params={"status": 1}),
419
- RoborockCommand.SET_IDENTIFY_GROUND_MATERIAL_STATUS: CommandInfo(params={"status": 1}),
420
- RoborockCommand.SET_LED_STATUS: CommandInfo(params=[1]),
421
- RoborockCommand.SET_MOP_MODE: CommandInfo(params=None),
422
- RoborockCommand.SET_SCENES_SEGMENTS: CommandInfo(
423
- params={"data": [{"tid": "1687831528786", "segs": [{"sid": 22}, {"sid": 18}]}]}
424
- ),
425
- RoborockCommand.SET_SCENES_ZONES: CommandInfo(
426
- params={"data": [{"zones": [{"zid": 0, "range": [27700, 23750, 30850, 26900]}], "tid": "1687831073722"}]}
427
- ),
428
- RoborockCommand.SET_SERVER_TIMER: CommandInfo(
429
- params={
430
- "data": [["1687793948482", ["39 12 * * 0,1,2,3,4,5,6", ["start_clean", 106, "0", -1]]]],
431
- "need_retry": 1,
432
- }
433
- ),
434
- RoborockCommand.SET_SMART_WASH_PARAMS: CommandInfo(params=None),
435
- RoborockCommand.SET_TIMEZONE: CommandInfo(params=["America/Sao_Paulo"]),
436
- RoborockCommand.SET_VALLEY_ELECTRICITY_TIMER: CommandInfo(params=[0, 0, 8, 0]),
437
- RoborockCommand.SET_WASH_TOWEL_MODE: CommandInfo(params=None),
438
- RoborockCommand.SET_WATER_BOX_CUSTOM_MODE: CommandInfo(params=[203]),
439
- RoborockCommand.START_CAMERA_PREVIEW: CommandInfo(params={"client_id": "443f8636", "quality": "SD"}),
440
- RoborockCommand.START_EDIT_MAP: CommandInfo(params=[]),
441
- RoborockCommand.START_WASH_THEN_CHARGE: CommandInfo(params=None),
442
- RoborockCommand.STOP_CAMERA_PREVIEW: CommandInfo(params={"client_id": "443f8636"}),
443
- RoborockCommand.SWITCH_WATER_MARK: CommandInfo(params={"waterMark": "OFF"}),
444
- RoborockCommand.TEST_SOUND_VOLUME: CommandInfo(params=None),
445
- RoborockCommand.UPD_SERVER_TIMER: CommandInfo(params=[["1687793948482", "off"]]),
446
- RoborockCommand.DEL_SERVER_TIMER: CommandInfo(params=["1687793948482"]),
447
- }
448
-
449
-
450
274
  @dataclass
451
275
  class DockSummary(RoborockBase):
452
276
  dust_collection_mode: DustCollectionMode | None = None