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.
- {python_roborock-2.29.0 → python_roborock-2.30.0}/PKG-INFO +1 -1
- {python_roborock-2.29.0 → python_roborock-2.30.0}/pyproject.toml +1 -1
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/containers.py +45 -77
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/device_features.py +139 -1
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/roborock_typing.py +0 -176
- {python_roborock-2.29.0 → python_roborock-2.30.0}/LICENSE +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/README.md +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/__init__.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/api.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/cli.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/cloud_api.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/code_mappings.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/command_cache.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/const.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/README.md +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/__init__.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/a01_channel.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/channel.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/device.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/device_manager.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/local_channel.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/mqtt_channel.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/dyad.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/status.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/trait.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/traits/zeo.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/v1_channel.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/devices/v1_rpc_channel.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/exceptions.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/local_api.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/mqtt/__init__.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/mqtt/roborock_session.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/mqtt/session.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/protocol.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/protocols/a01_protocol.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/protocols/v1_protocol.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/py.typed +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/roborock_future.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/roborock_message.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/util.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/__init__.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_client_v1.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/__init__.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
- {python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/web_api.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
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
|
|
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
|
|
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
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
146
|
+
result[key] = RoborockBase._convert_to_class_obj(subtype, value)
|
|
147
|
+
break
|
|
186
148
|
except Exception:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_client_v1.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_1_apis/roborock_mqtt_client_v1.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_roborock-2.29.0 → python_roborock-2.30.0}/roborock/version_a01_apis/roborock_client_a01.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|