roborock-cli 0.1.1__py3-none-any.whl
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.
- roborock_cli/__init__.py +3 -0
- roborock_cli/__main__.py +76 -0
- roborock_cli/_vendor/VERSION +6 -0
- roborock_cli/_vendor/__init__.py +0 -0
- roborock_cli/_vendor/roborock/__init__.py +27 -0
- roborock_cli/_vendor/roborock/broadcast_protocol.py +114 -0
- roborock_cli/_vendor/roborock/callbacks.py +130 -0
- roborock_cli/_vendor/roborock/cli.py +1338 -0
- roborock_cli/_vendor/roborock/const.py +84 -0
- roborock_cli/_vendor/roborock/data/__init__.py +9 -0
- roborock_cli/_vendor/roborock/data/b01_q10/__init__.py +2 -0
- roborock_cli/_vendor/roborock/data/b01_q10/b01_q10_code_mappings.py +213 -0
- roborock_cli/_vendor/roborock/data/b01_q10/b01_q10_containers.py +102 -0
- roborock_cli/_vendor/roborock/data/b01_q7/__init__.py +2 -0
- roborock_cli/_vendor/roborock/data/b01_q7/b01_q7_code_mappings.py +303 -0
- roborock_cli/_vendor/roborock/data/b01_q7/b01_q7_containers.py +302 -0
- roborock_cli/_vendor/roborock/data/code_mappings.py +198 -0
- roborock_cli/_vendor/roborock/data/containers.py +530 -0
- roborock_cli/_vendor/roborock/data/dyad/__init__.py +2 -0
- roborock_cli/_vendor/roborock/data/dyad/dyad_code_mappings.py +102 -0
- roborock_cli/_vendor/roborock/data/dyad/dyad_containers.py +28 -0
- roborock_cli/_vendor/roborock/data/v1/__init__.py +3 -0
- roborock_cli/_vendor/roborock/data/v1/v1_clean_modes.py +192 -0
- roborock_cli/_vendor/roborock/data/v1/v1_code_mappings.py +644 -0
- roborock_cli/_vendor/roborock/data/v1/v1_containers.py +800 -0
- roborock_cli/_vendor/roborock/data/zeo/__init__.py +2 -0
- roborock_cli/_vendor/roborock/data/zeo/zeo_code_mappings.py +138 -0
- roborock_cli/_vendor/roborock/data/zeo/zeo_containers.py +0 -0
- roborock_cli/_vendor/roborock/device_features.py +668 -0
- roborock_cli/_vendor/roborock/devices/README.md +41 -0
- roborock_cli/_vendor/roborock/devices/__init__.py +11 -0
- roborock_cli/_vendor/roborock/devices/cache.py +143 -0
- roborock_cli/_vendor/roborock/devices/device.py +240 -0
- roborock_cli/_vendor/roborock/devices/device_manager.py +269 -0
- roborock_cli/_vendor/roborock/devices/file_cache.py +79 -0
- roborock_cli/_vendor/roborock/devices/rpc/__init__.py +14 -0
- roborock_cli/_vendor/roborock/devices/rpc/a01_channel.py +94 -0
- roborock_cli/_vendor/roborock/devices/rpc/b01_q10_channel.py +57 -0
- roborock_cli/_vendor/roborock/devices/rpc/b01_q7_channel.py +101 -0
- roborock_cli/_vendor/roborock/devices/rpc/v1_channel.py +457 -0
- roborock_cli/_vendor/roborock/devices/traits/__init__.py +28 -0
- roborock_cli/_vendor/roborock/devices/traits/a01/__init__.py +191 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/__init__.py +12 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q10/__init__.py +76 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q10/command.py +32 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q10/common.py +115 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q10/status.py +32 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q10/vacuum.py +81 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q7/__init__.py +136 -0
- roborock_cli/_vendor/roborock/devices/traits/b01/q7/clean_summary.py +75 -0
- roborock_cli/_vendor/roborock/devices/traits/traits_mixin.py +64 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/__init__.py +344 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/child_lock.py +29 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/clean_summary.py +83 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/command.py +38 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/common.py +172 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/consumeable.py +48 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/device_features.py +74 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/do_not_disturb.py +41 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/dust_collection_mode.py +13 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/flow_led_status.py +29 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/home.py +285 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/led_status.py +43 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/map_content.py +83 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/maps.py +80 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/network_info.py +55 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/rooms.py +105 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/routines.py +26 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/smart_wash_params.py +13 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/status.py +101 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/valley_electricity_timer.py +44 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/volume.py +27 -0
- roborock_cli/_vendor/roborock/devices/traits/v1/wash_towel_mode.py +13 -0
- roborock_cli/_vendor/roborock/devices/transport/__init__.py +8 -0
- roborock_cli/_vendor/roborock/devices/transport/channel.py +32 -0
- roborock_cli/_vendor/roborock/devices/transport/local_channel.py +295 -0
- roborock_cli/_vendor/roborock/devices/transport/mqtt_channel.py +118 -0
- roborock_cli/_vendor/roborock/diagnostics.py +166 -0
- roborock_cli/_vendor/roborock/exceptions.py +95 -0
- roborock_cli/_vendor/roborock/map/__init__.py +7 -0
- roborock_cli/_vendor/roborock/map/map_parser.py +123 -0
- roborock_cli/_vendor/roborock/mqtt/__init__.py +10 -0
- roborock_cli/_vendor/roborock/mqtt/health_manager.py +60 -0
- roborock_cli/_vendor/roborock/mqtt/roborock_session.py +463 -0
- roborock_cli/_vendor/roborock/mqtt/session.py +108 -0
- roborock_cli/_vendor/roborock/protocol.py +558 -0
- roborock_cli/_vendor/roborock/protocols/__init__.py +3 -0
- roborock_cli/_vendor/roborock/protocols/a01_protocol.py +74 -0
- roborock_cli/_vendor/roborock/protocols/b01_q10_protocol.py +87 -0
- roborock_cli/_vendor/roborock/protocols/b01_q7_protocol.py +81 -0
- roborock_cli/_vendor/roborock/protocols/v1_protocol.py +271 -0
- roborock_cli/_vendor/roborock/py.typed +0 -0
- roborock_cli/_vendor/roborock/roborock_message.py +246 -0
- roborock_cli/_vendor/roborock/roborock_typing.py +382 -0
- roborock_cli/_vendor/roborock/util.py +54 -0
- roborock_cli/_vendor/roborock/web_api.py +761 -0
- roborock_cli/cli.py +715 -0
- roborock_cli/connection.py +202 -0
- roborock_cli/helpers.py +71 -0
- roborock_cli/server.py +759 -0
- roborock_cli/setup_auth.py +92 -0
- roborock_cli-0.1.1.dist-info/METADATA +172 -0
- roborock_cli-0.1.1.dist-info/RECORD +106 -0
- roborock_cli-0.1.1.dist-info/WHEEL +4 -0
- roborock_cli-0.1.1.dist-info/entry_points.txt +2 -0
- roborock_cli-0.1.1.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from collections import namedtuple
|
|
5
|
+
from enum import Enum, IntEnum, StrEnum
|
|
6
|
+
from typing import Any, Self
|
|
7
|
+
|
|
8
|
+
_LOGGER = logging.getLogger(__name__)
|
|
9
|
+
completed_warnings = set()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RoborockEnum(IntEnum):
|
|
13
|
+
"""Roborock Enum for codes with int values"""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def name(self) -> str:
|
|
17
|
+
return super().name.lower()
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def _missing_(cls: type[RoborockEnum], key) -> RoborockEnum:
|
|
21
|
+
if hasattr(cls, "unknown"):
|
|
22
|
+
warning = f"Missing {cls.__name__} code: {key} - defaulting to 'unknown'"
|
|
23
|
+
if warning not in completed_warnings:
|
|
24
|
+
completed_warnings.add(warning)
|
|
25
|
+
_LOGGER.warning(warning)
|
|
26
|
+
return cls.unknown # type: ignore
|
|
27
|
+
default_value = next(item for item in cls)
|
|
28
|
+
warning = f"Missing {cls.__name__} code: {key} - defaulting to {default_value}"
|
|
29
|
+
if warning not in completed_warnings:
|
|
30
|
+
completed_warnings.add(warning)
|
|
31
|
+
_LOGGER.warning(warning)
|
|
32
|
+
return default_value
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def as_dict(cls: type[RoborockEnum]):
|
|
36
|
+
return {i.name: i.value for i in cls if i.name != "missing"}
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def as_enum_dict(cls: type[RoborockEnum]):
|
|
40
|
+
return {i.value: i for i in cls if i.name != "missing"}
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def values(cls: type[RoborockEnum]) -> list[int]:
|
|
44
|
+
return list(cls.as_dict().values())
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def keys(cls: type[RoborockEnum]) -> list[str]:
|
|
48
|
+
return list(cls.as_dict().keys())
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def items(cls: type[RoborockEnum]):
|
|
52
|
+
return cls.as_dict().items()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class RoborockModeEnum(StrEnum):
|
|
56
|
+
"""A custom StrEnum that also stores an integer code for each member."""
|
|
57
|
+
|
|
58
|
+
code: int
|
|
59
|
+
"""The integer code associated with the enum member."""
|
|
60
|
+
|
|
61
|
+
def __new__(cls, value: str, code: int) -> Self:
|
|
62
|
+
"""Creates a new enum member."""
|
|
63
|
+
member = str.__new__(cls, value)
|
|
64
|
+
member._value_ = value
|
|
65
|
+
member.code = code
|
|
66
|
+
return member
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def from_code(cls, code: int) -> Self:
|
|
70
|
+
for member in cls:
|
|
71
|
+
if member.code == code:
|
|
72
|
+
return member
|
|
73
|
+
message = f"{code} is not a valid code for {cls.__name__}"
|
|
74
|
+
if message not in completed_warnings:
|
|
75
|
+
completed_warnings.add(message)
|
|
76
|
+
_LOGGER.warning(message)
|
|
77
|
+
raise ValueError(message)
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_code_optional(cls, code: int) -> Self | None:
|
|
81
|
+
"""Gracefully return None if the code does not exist."""
|
|
82
|
+
try:
|
|
83
|
+
return cls.from_code(code)
|
|
84
|
+
except ValueError:
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def from_value(cls, value: str) -> Self:
|
|
89
|
+
"""Find enum member by string value (case-insensitive)."""
|
|
90
|
+
for member in cls:
|
|
91
|
+
if member.value.lower() == value.lower():
|
|
92
|
+
return member
|
|
93
|
+
raise ValueError(f"{value} is not a valid value for {cls.__name__}")
|
|
94
|
+
|
|
95
|
+
@classmethod
|
|
96
|
+
def from_name(cls, name: str) -> Self:
|
|
97
|
+
"""Find enum member by name (case-insensitive)."""
|
|
98
|
+
for member in cls:
|
|
99
|
+
if member.name.lower() == name.lower():
|
|
100
|
+
return member
|
|
101
|
+
raise ValueError(f"{name} is not a valid name for {cls.__name__}")
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def keys(cls) -> list[str]:
|
|
105
|
+
"""Returns a list of all member values."""
|
|
106
|
+
return [member.value for member in cls]
|
|
107
|
+
|
|
108
|
+
def __eq__(self, other: Any) -> bool:
|
|
109
|
+
if isinstance(other, str):
|
|
110
|
+
return self.value == other or self.name == other
|
|
111
|
+
if isinstance(other, int):
|
|
112
|
+
return self.code == other
|
|
113
|
+
return super().__eq__(other)
|
|
114
|
+
|
|
115
|
+
def __hash__(self) -> int:
|
|
116
|
+
"""Hash a RoborockModeEnum.
|
|
117
|
+
|
|
118
|
+
It is critical that you do not mix RoborockModeEnums with raw strings or ints in hashed situations
|
|
119
|
+
(i.e. sets or keys in dictionaries)
|
|
120
|
+
"""
|
|
121
|
+
return hash((self.code, self._value_))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
ProductInfo = namedtuple("ProductInfo", ["nickname", "short_models"])
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class RoborockProductNickname(Enum):
|
|
128
|
+
# Coral Series
|
|
129
|
+
CORAL = ProductInfo(nickname="Coral", short_models=("a20", "a21"))
|
|
130
|
+
CORALPRO = ProductInfo(nickname="CoralPro", short_models=("a143", "a144"))
|
|
131
|
+
|
|
132
|
+
# Pearl Series
|
|
133
|
+
PEARL = ProductInfo(nickname="Pearl", short_models=("a74", "a75"))
|
|
134
|
+
PEARLC = ProductInfo(nickname="PearlC", short_models=("a103", "a104"))
|
|
135
|
+
PEARLE = ProductInfo(nickname="PearlE", short_models=("a167", "a168"))
|
|
136
|
+
PEARLELITE = ProductInfo(nickname="PearlELite", short_models=("a169", "a170"))
|
|
137
|
+
PEARLPLUS = ProductInfo(nickname="PearlPlus", short_models=("a86", "a87"))
|
|
138
|
+
PEARLPLUSS = ProductInfo(nickname="PearlPlusS", short_models=("a116", "a117", "a136"))
|
|
139
|
+
PEARLS = ProductInfo(nickname="PearlS", short_models=("a100", "a101"))
|
|
140
|
+
PEARLSLITE = ProductInfo(nickname="PearlSLite", short_models=("a122", "a123"))
|
|
141
|
+
|
|
142
|
+
# Ruby Series
|
|
143
|
+
RUBYPLUS = ProductInfo(nickname="RubyPlus", short_models=("t4", "s4"))
|
|
144
|
+
RUBYSC = ProductInfo(nickname="RubySC", short_models=("p5", "a08"))
|
|
145
|
+
RUBYSE = ProductInfo(nickname="RubySE", short_models=("a19",))
|
|
146
|
+
RUBYSLITE = ProductInfo(nickname="RubySLite", short_models=("p6", "s5e", "a05"))
|
|
147
|
+
|
|
148
|
+
# Tanos Series
|
|
149
|
+
TANOS = ProductInfo(nickname="Tanos", short_models=("t6", "s6"))
|
|
150
|
+
TANOSE = ProductInfo(nickname="TanosE", short_models=("t7", "a11"))
|
|
151
|
+
TANOSS = ProductInfo(nickname="TanosS", short_models=("a14", "a15"))
|
|
152
|
+
TANOSSC = ProductInfo(nickname="TanosSC", short_models=("a39", "a40"))
|
|
153
|
+
TANOSSE = ProductInfo(nickname="TanosSE", short_models=("a33", "a34"))
|
|
154
|
+
TANOSSMAX = ProductInfo(nickname="TanosSMax", short_models=("a52",))
|
|
155
|
+
TANOSSLITE = ProductInfo(nickname="TanosSLite", short_models=("a37", "a38"))
|
|
156
|
+
TANOSSPLUS = ProductInfo(nickname="TanosSPlus", short_models=("a23", "a24"))
|
|
157
|
+
TANOSV = ProductInfo(nickname="TanosV", short_models=("t7p", "a09", "a10"))
|
|
158
|
+
|
|
159
|
+
# Topaz Series
|
|
160
|
+
TOPAZS = ProductInfo(nickname="TopazS", short_models=("a29", "a30", "a76"))
|
|
161
|
+
TOPAZSC = ProductInfo(nickname="TopazSC", short_models=("a64", "a65"))
|
|
162
|
+
TOPAZSPLUS = ProductInfo(nickname="TopazSPlus", short_models=("a46", "a47", "a66"))
|
|
163
|
+
TOPAZSPOWER = ProductInfo(nickname="TopazSPower", short_models=("a62",))
|
|
164
|
+
TOPAZSV = ProductInfo(nickname="TopazSV", short_models=("a26", "a27"))
|
|
165
|
+
|
|
166
|
+
# Ultron Series
|
|
167
|
+
ULTRON = ProductInfo(nickname="Ultron", short_models=("a50", "a51"))
|
|
168
|
+
ULTRONE = ProductInfo(nickname="UltronE", short_models=("a72", "a84"))
|
|
169
|
+
ULTRONLITE = ProductInfo(nickname="UltronLite", short_models=("a73", "a85"))
|
|
170
|
+
ULTRONSC = ProductInfo(nickname="UltronSC", short_models=("a94", "a95"))
|
|
171
|
+
ULTRONSE = ProductInfo(nickname="UltronSE", short_models=("a124", "a125", "a139", "a140"))
|
|
172
|
+
ULTRONSPLUS = ProductInfo(nickname="UltronSPlus", short_models=("a68", "a69", "a70"))
|
|
173
|
+
ULTRONSV = ProductInfo(nickname="UltronSV", short_models=("a96", "a97"))
|
|
174
|
+
|
|
175
|
+
# Verdelite Series
|
|
176
|
+
VERDELITE = ProductInfo(nickname="Verdelite", short_models=("a146", "a147"))
|
|
177
|
+
|
|
178
|
+
# Vivian Series
|
|
179
|
+
VIVIAN = ProductInfo(nickname="Vivian", short_models=("a134", "a135", "a155", "a156"))
|
|
180
|
+
VIVIANC = ProductInfo(nickname="VivianC", short_models=("a158", "a159"))
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
SHORT_MODEL_TO_ENUM = {model: product for product in RoborockProductNickname for model in product.value.short_models}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class RoborockCategory(Enum):
|
|
187
|
+
"""Describes the category of the device."""
|
|
188
|
+
|
|
189
|
+
WET_DRY_VAC = "roborock.wetdryvac"
|
|
190
|
+
VACUUM = "robot.vacuum.cleaner"
|
|
191
|
+
WASHING_MACHINE = "roborock.wm"
|
|
192
|
+
MOWER = "roborock.mower"
|
|
193
|
+
UNKNOWN = "UNKNOWN"
|
|
194
|
+
|
|
195
|
+
@classmethod
|
|
196
|
+
def _missing_(cls, value):
|
|
197
|
+
_LOGGER.warning("Missing code %s from category", value)
|
|
198
|
+
return RoborockCategory.UNKNOWN
|