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.
Files changed (106) hide show
  1. roborock_cli/__init__.py +3 -0
  2. roborock_cli/__main__.py +76 -0
  3. roborock_cli/_vendor/VERSION +6 -0
  4. roborock_cli/_vendor/__init__.py +0 -0
  5. roborock_cli/_vendor/roborock/__init__.py +27 -0
  6. roborock_cli/_vendor/roborock/broadcast_protocol.py +114 -0
  7. roborock_cli/_vendor/roborock/callbacks.py +130 -0
  8. roborock_cli/_vendor/roborock/cli.py +1338 -0
  9. roborock_cli/_vendor/roborock/const.py +84 -0
  10. roborock_cli/_vendor/roborock/data/__init__.py +9 -0
  11. roborock_cli/_vendor/roborock/data/b01_q10/__init__.py +2 -0
  12. roborock_cli/_vendor/roborock/data/b01_q10/b01_q10_code_mappings.py +213 -0
  13. roborock_cli/_vendor/roborock/data/b01_q10/b01_q10_containers.py +102 -0
  14. roborock_cli/_vendor/roborock/data/b01_q7/__init__.py +2 -0
  15. roborock_cli/_vendor/roborock/data/b01_q7/b01_q7_code_mappings.py +303 -0
  16. roborock_cli/_vendor/roborock/data/b01_q7/b01_q7_containers.py +302 -0
  17. roborock_cli/_vendor/roborock/data/code_mappings.py +198 -0
  18. roborock_cli/_vendor/roborock/data/containers.py +530 -0
  19. roborock_cli/_vendor/roborock/data/dyad/__init__.py +2 -0
  20. roborock_cli/_vendor/roborock/data/dyad/dyad_code_mappings.py +102 -0
  21. roborock_cli/_vendor/roborock/data/dyad/dyad_containers.py +28 -0
  22. roborock_cli/_vendor/roborock/data/v1/__init__.py +3 -0
  23. roborock_cli/_vendor/roborock/data/v1/v1_clean_modes.py +192 -0
  24. roborock_cli/_vendor/roborock/data/v1/v1_code_mappings.py +644 -0
  25. roborock_cli/_vendor/roborock/data/v1/v1_containers.py +800 -0
  26. roborock_cli/_vendor/roborock/data/zeo/__init__.py +2 -0
  27. roborock_cli/_vendor/roborock/data/zeo/zeo_code_mappings.py +138 -0
  28. roborock_cli/_vendor/roborock/data/zeo/zeo_containers.py +0 -0
  29. roborock_cli/_vendor/roborock/device_features.py +668 -0
  30. roborock_cli/_vendor/roborock/devices/README.md +41 -0
  31. roborock_cli/_vendor/roborock/devices/__init__.py +11 -0
  32. roborock_cli/_vendor/roborock/devices/cache.py +143 -0
  33. roborock_cli/_vendor/roborock/devices/device.py +240 -0
  34. roborock_cli/_vendor/roborock/devices/device_manager.py +269 -0
  35. roborock_cli/_vendor/roborock/devices/file_cache.py +79 -0
  36. roborock_cli/_vendor/roborock/devices/rpc/__init__.py +14 -0
  37. roborock_cli/_vendor/roborock/devices/rpc/a01_channel.py +94 -0
  38. roborock_cli/_vendor/roborock/devices/rpc/b01_q10_channel.py +57 -0
  39. roborock_cli/_vendor/roborock/devices/rpc/b01_q7_channel.py +101 -0
  40. roborock_cli/_vendor/roborock/devices/rpc/v1_channel.py +457 -0
  41. roborock_cli/_vendor/roborock/devices/traits/__init__.py +28 -0
  42. roborock_cli/_vendor/roborock/devices/traits/a01/__init__.py +191 -0
  43. roborock_cli/_vendor/roborock/devices/traits/b01/__init__.py +12 -0
  44. roborock_cli/_vendor/roborock/devices/traits/b01/q10/__init__.py +76 -0
  45. roborock_cli/_vendor/roborock/devices/traits/b01/q10/command.py +32 -0
  46. roborock_cli/_vendor/roborock/devices/traits/b01/q10/common.py +115 -0
  47. roborock_cli/_vendor/roborock/devices/traits/b01/q10/status.py +32 -0
  48. roborock_cli/_vendor/roborock/devices/traits/b01/q10/vacuum.py +81 -0
  49. roborock_cli/_vendor/roborock/devices/traits/b01/q7/__init__.py +136 -0
  50. roborock_cli/_vendor/roborock/devices/traits/b01/q7/clean_summary.py +75 -0
  51. roborock_cli/_vendor/roborock/devices/traits/traits_mixin.py +64 -0
  52. roborock_cli/_vendor/roborock/devices/traits/v1/__init__.py +344 -0
  53. roborock_cli/_vendor/roborock/devices/traits/v1/child_lock.py +29 -0
  54. roborock_cli/_vendor/roborock/devices/traits/v1/clean_summary.py +83 -0
  55. roborock_cli/_vendor/roborock/devices/traits/v1/command.py +38 -0
  56. roborock_cli/_vendor/roborock/devices/traits/v1/common.py +172 -0
  57. roborock_cli/_vendor/roborock/devices/traits/v1/consumeable.py +48 -0
  58. roborock_cli/_vendor/roborock/devices/traits/v1/device_features.py +74 -0
  59. roborock_cli/_vendor/roborock/devices/traits/v1/do_not_disturb.py +41 -0
  60. roborock_cli/_vendor/roborock/devices/traits/v1/dust_collection_mode.py +13 -0
  61. roborock_cli/_vendor/roborock/devices/traits/v1/flow_led_status.py +29 -0
  62. roborock_cli/_vendor/roborock/devices/traits/v1/home.py +285 -0
  63. roborock_cli/_vendor/roborock/devices/traits/v1/led_status.py +43 -0
  64. roborock_cli/_vendor/roborock/devices/traits/v1/map_content.py +83 -0
  65. roborock_cli/_vendor/roborock/devices/traits/v1/maps.py +80 -0
  66. roborock_cli/_vendor/roborock/devices/traits/v1/network_info.py +55 -0
  67. roborock_cli/_vendor/roborock/devices/traits/v1/rooms.py +105 -0
  68. roborock_cli/_vendor/roborock/devices/traits/v1/routines.py +26 -0
  69. roborock_cli/_vendor/roborock/devices/traits/v1/smart_wash_params.py +13 -0
  70. roborock_cli/_vendor/roborock/devices/traits/v1/status.py +101 -0
  71. roborock_cli/_vendor/roborock/devices/traits/v1/valley_electricity_timer.py +44 -0
  72. roborock_cli/_vendor/roborock/devices/traits/v1/volume.py +27 -0
  73. roborock_cli/_vendor/roborock/devices/traits/v1/wash_towel_mode.py +13 -0
  74. roborock_cli/_vendor/roborock/devices/transport/__init__.py +8 -0
  75. roborock_cli/_vendor/roborock/devices/transport/channel.py +32 -0
  76. roborock_cli/_vendor/roborock/devices/transport/local_channel.py +295 -0
  77. roborock_cli/_vendor/roborock/devices/transport/mqtt_channel.py +118 -0
  78. roborock_cli/_vendor/roborock/diagnostics.py +166 -0
  79. roborock_cli/_vendor/roborock/exceptions.py +95 -0
  80. roborock_cli/_vendor/roborock/map/__init__.py +7 -0
  81. roborock_cli/_vendor/roborock/map/map_parser.py +123 -0
  82. roborock_cli/_vendor/roborock/mqtt/__init__.py +10 -0
  83. roborock_cli/_vendor/roborock/mqtt/health_manager.py +60 -0
  84. roborock_cli/_vendor/roborock/mqtt/roborock_session.py +463 -0
  85. roborock_cli/_vendor/roborock/mqtt/session.py +108 -0
  86. roborock_cli/_vendor/roborock/protocol.py +558 -0
  87. roborock_cli/_vendor/roborock/protocols/__init__.py +3 -0
  88. roborock_cli/_vendor/roborock/protocols/a01_protocol.py +74 -0
  89. roborock_cli/_vendor/roborock/protocols/b01_q10_protocol.py +87 -0
  90. roborock_cli/_vendor/roborock/protocols/b01_q7_protocol.py +81 -0
  91. roborock_cli/_vendor/roborock/protocols/v1_protocol.py +271 -0
  92. roborock_cli/_vendor/roborock/py.typed +0 -0
  93. roborock_cli/_vendor/roborock/roborock_message.py +246 -0
  94. roborock_cli/_vendor/roborock/roborock_typing.py +382 -0
  95. roborock_cli/_vendor/roborock/util.py +54 -0
  96. roborock_cli/_vendor/roborock/web_api.py +761 -0
  97. roborock_cli/cli.py +715 -0
  98. roborock_cli/connection.py +202 -0
  99. roborock_cli/helpers.py +71 -0
  100. roborock_cli/server.py +759 -0
  101. roborock_cli/setup_auth.py +92 -0
  102. roborock_cli-0.1.1.dist-info/METADATA +172 -0
  103. roborock_cli-0.1.1.dist-info/RECORD +106 -0
  104. roborock_cli-0.1.1.dist-info/WHEEL +4 -0
  105. roborock_cli-0.1.1.dist-info/entry_points.txt +2 -0
  106. roborock_cli-0.1.1.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,246 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import StrEnum
5
+
6
+ from roborock_cli._vendor.roborock import RoborockEnum
7
+ from roborock_cli._vendor.roborock.util import get_next_int, get_timestamp
8
+
9
+
10
+ class RoborockMessageProtocol(RoborockEnum):
11
+ HELLO_REQUEST = 0
12
+ HELLO_RESPONSE = 1
13
+ PING_REQUEST = 2
14
+ PING_RESPONSE = 3
15
+ GENERAL_REQUEST = 4
16
+ GENERAL_RESPONSE = 5
17
+ RPC_REQUEST = 101
18
+ RPC_RESPONSE = 102
19
+ MAP_RESPONSE = 301
20
+
21
+
22
+ class RoborockDataProtocol(RoborockEnum):
23
+ ERROR_CODE = 120
24
+ STATE = 121
25
+ BATTERY = 122
26
+ FAN_POWER = 123
27
+ WATER_BOX_MODE = 124
28
+ MAIN_BRUSH_WORK_TIME = 125
29
+ SIDE_BRUSH_WORK_TIME = 126
30
+ FILTER_WORK_TIME = 127
31
+ ADDITIONAL_PROPS = 128
32
+ TASK_COMPLETE = 130
33
+ TASK_CANCEL_LOW_POWER = 131
34
+ TASK_CANCEL_IN_MOTION = 132
35
+ CHARGE_STATUS = 133
36
+ DRYING_STATUS = 134
37
+ OFFLINE_STATUS = 135
38
+
39
+ @classmethod
40
+ def _missing_(cls: type[RoborockEnum], key) -> RoborockEnum:
41
+ raise ValueError("%s not a valid key for Data Protocol", key)
42
+
43
+
44
+ class RoborockDyadDataProtocol(RoborockEnum):
45
+ DRYING_STATUS = 134
46
+ START = 200
47
+ STATUS = 201
48
+ SELF_CLEAN_MODE = 202
49
+ SELF_CLEAN_LEVEL = 203
50
+ WARM_LEVEL = 204
51
+ CLEAN_MODE = 205
52
+ SUCTION = 206
53
+ WATER_LEVEL = 207
54
+ BRUSH_SPEED = 208
55
+ POWER = 209
56
+ COUNTDOWN_TIME = 210
57
+ AUTO_SELF_CLEAN_SET = 212
58
+ AUTO_DRY = 213
59
+ MESH_LEFT = 214
60
+ BRUSH_LEFT = 215
61
+ ERROR = 216
62
+ MESH_RESET = 218
63
+ BRUSH_RESET = 219
64
+ VOLUME_SET = 221
65
+ STAND_LOCK_AUTO_RUN = 222
66
+ AUTO_SELF_CLEAN_SET_MODE = 223
67
+ AUTO_DRY_MODE = 224
68
+ SILENT_DRY_DURATION = 225
69
+ SILENT_MODE = 226
70
+ SILENT_MODE_START_TIME = 227
71
+ SILENT_MODE_END_TIME = 228
72
+ RECENT_RUN_TIME = 229
73
+ TOTAL_RUN_TIME = 230
74
+ FEATURE_INFO = 235
75
+ RECOVER_SETTINGS = 236
76
+ DRY_COUNTDOWN = 237
77
+ ID_QUERY = 10000
78
+ F_C = 10001
79
+ SCHEDULE_TASK = 10002
80
+ SND_SWITCH = 10003
81
+ SND_STATE = 10004
82
+ PRODUCT_INFO = 10005
83
+ PRIVACY_INFO = 10006
84
+ OTA_NFO = 10007
85
+ RPC_REQUEST = 10101
86
+ RPC_RESPONSE = 10102
87
+
88
+
89
+ class RoborockZeoProtocol(RoborockEnum):
90
+ START = 200 # rw
91
+ PAUSE = 201 # rw
92
+ SHUTDOWN = 202 # rw
93
+ STATE = 203 # ro
94
+ MODE = 204 # rw
95
+ PROGRAM = 205 # rw
96
+ CHILD_LOCK = 206 # rw
97
+ TEMP = 207 # rw
98
+ RINSE_TIMES = 208 # rw
99
+ SPIN_LEVEL = 209 # rw
100
+ DRYING_MODE = 210 # rw
101
+ DETERGENT_SET = 211 # rw
102
+ SOFTENER_SET = 212 # rw
103
+ DETERGENT_TYPE = 213 # rw
104
+ SOFTENER_TYPE = 214 # rw
105
+ COUNTDOWN = 217 # rw
106
+ WASHING_LEFT = 218 # ro
107
+ DOORLOCK_STATE = 219 # ro
108
+ ERROR = 220 # ro
109
+ CUSTOM_PARAM_SAVE = 221 # rw
110
+ CUSTOM_PARAM_GET = 222 # ro
111
+ SOUND_SET = 223 # rw
112
+ TIMES_AFTER_CLEAN = 224 # ro
113
+ DEFAULT_SETTING = 225 # rw
114
+ DETERGENT_EMPTY = 226 # ro
115
+ SOFTENER_EMPTY = 227 # ro
116
+ LIGHT_SETTING = 229 # rw
117
+ DETERGENT_VOLUME = 230 # rw
118
+ SOFTENER_VOLUME = 231 # rw
119
+ APP_AUTHORIZATION = 232 # rw
120
+ ID_QUERY = 10000
121
+ F_C = 10001
122
+ SND_STATE = 10004
123
+ PRODUCT_INFO = 10005
124
+ PRIVACY_INFO = 10006
125
+ OTA_NFO = 10007
126
+ WASHING_LOG = 10008
127
+ RPC_REQ = 10101
128
+ RPC_RESp = 10102
129
+
130
+
131
+ class RoborockB01Protocol(RoborockEnum):
132
+ RPC_REQUEST = 101
133
+ RPC_RESPONSE = 102
134
+ ERROR_CODE = 120
135
+ STATE = 121
136
+ BATTERY = 122
137
+ FAN_POWER = 123
138
+ WATER_BOX_MODE = 124
139
+ MAIN_BRUSH_LIFE = 125
140
+ SIDE_BRUSH_LIFE = 126
141
+ FILTER_LIFE = 127
142
+ OFFLINE_STATUS = 135
143
+ CLEAN_TIMES = 136
144
+ CLEANING_PREFERENCE = 137
145
+ CLEAN_TASK_TYPE = 138
146
+ BACK_TYPE = 139
147
+ DOCK_TASK_TYPE = 140
148
+ CLEANING_PROGRESS = 141
149
+ FC_STATE = 142
150
+ START_CLEAN_TASK = 201
151
+ START_BACK_DOCK_TASK = 202
152
+ START_DOCK_TASK = 203
153
+ PAUSE = 204
154
+ RESUME = 205
155
+ STOP = 206
156
+ CEIP = 207
157
+
158
+
159
+ class RoborockB01Props(StrEnum):
160
+ """Properties requested by the Roborock B01 model."""
161
+
162
+ STATUS = "status"
163
+ FAULT = "fault"
164
+ WIND = "wind"
165
+ WATER = "water"
166
+ MODE = "mode"
167
+ QUANTITY = "quantity"
168
+ ALARM = "alarm"
169
+ VOLUME = "volume"
170
+ HYPA = "hypa"
171
+ MAIN_BRUSH = "main_brush"
172
+ SIDE_BRUSH = "side_brush"
173
+ MOP_LIFE = "mop_life"
174
+ MAIN_SENSOR = "main_sensor"
175
+ NET_STATUS = "net_status"
176
+ REPEAT_STATE = "repeat_state"
177
+ TANK_STATE = "tank_state"
178
+ SWEEP_TYPE = "sweep_type"
179
+ CLEAN_PATH_PREFERENCE = "clean_path_preference"
180
+ CLOTH_STATE = "cloth_state"
181
+ TIME_ZONE = "time_zone"
182
+ TIME_ZONE_INFO = "time_zone_info"
183
+ LANGUAGE = "language"
184
+ CLEANING_TIME = "cleaning_time"
185
+ REAL_CLEAN_TIME = "real_clean_time"
186
+ CLEANING_AREA = "cleaning_area"
187
+ CUSTOM_TYPE = "custom_type"
188
+ SOUND = "sound"
189
+ WORK_MODE = "work_mode"
190
+ STATION_ACT = "station_act"
191
+ CHARGE_STATE = "charge_state"
192
+ CURRENT_MAP_ID = "current_map_id"
193
+ MAP_NUM = "map_num"
194
+ DUST_ACTION = "dust_action"
195
+ QUIET_IS_OPEN = "quiet_is_open"
196
+ QUIET_BEGIN_TIME = "quiet_begin_time"
197
+ QUIET_END_TIME = "quiet_end_time"
198
+ CLEAN_FINISH = "clean_finish"
199
+ VOICE_TYPE = "voice_type"
200
+ VOICE_TYPE_VERSION = "voice_type_version"
201
+ ORDER_TOTAL = "order_total"
202
+ BUILD_MAP = "build_map"
203
+ PRIVACY = "privacy"
204
+ DUST_AUTO_STATE = "dust_auto_state"
205
+ DUST_FREQUENCY = "dust_frequency"
206
+ CHILD_LOCK = "child_lock"
207
+ MULTI_FLOOR = "multi_floor"
208
+ MAP_SAVE = "map_save"
209
+ LIGHT_MODE = "light_mode"
210
+ GREEN_LASER = "green_laser"
211
+ DUST_BAG_USED = "dust_bag_used"
212
+ ORDER_SAVE_MODE = "order_save_mode"
213
+ MANUFACTURER = "manufacturer"
214
+ BACK_TO_WASH = "back_to_wash"
215
+ CHARGE_STATION_TYPE = "charge_station_type"
216
+ PV_CUT_CHARGE = "pv_cut_charge"
217
+ PV_CHARGING = "pv_charging"
218
+ SERIAL_NUMBER = "serial_number"
219
+ RECOMMEND = "recommend"
220
+ ADD_SWEEP_STATUS = "add_sweep_status"
221
+
222
+
223
+ ROBOROCK_DATA_STATUS_PROTOCOL = [
224
+ RoborockDataProtocol.ERROR_CODE,
225
+ RoborockDataProtocol.STATE,
226
+ RoborockDataProtocol.BATTERY,
227
+ RoborockDataProtocol.FAN_POWER,
228
+ RoborockDataProtocol.WATER_BOX_MODE,
229
+ RoborockDataProtocol.CHARGE_STATUS,
230
+ ]
231
+
232
+ ROBOROCK_DATA_CONSUMABLE_PROTOCOL = [
233
+ RoborockDataProtocol.MAIN_BRUSH_WORK_TIME,
234
+ RoborockDataProtocol.SIDE_BRUSH_WORK_TIME,
235
+ RoborockDataProtocol.FILTER_WORK_TIME,
236
+ ]
237
+
238
+
239
+ @dataclass
240
+ class RoborockMessage:
241
+ protocol: RoborockMessageProtocol
242
+ payload: bytes | None = None
243
+ seq: int = field(default_factory=lambda: get_next_int(100000, 999999))
244
+ version: bytes = b"1.0"
245
+ random: int = field(default_factory=lambda: get_next_int(10000, 99999))
246
+ timestamp: int = field(default_factory=lambda: get_timestamp())
@@ -0,0 +1,382 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import Enum, StrEnum
5
+
6
+ from .data import (
7
+ CleanRecord,
8
+ CleanSummary,
9
+ Consumable,
10
+ DustCollectionMode,
11
+ RoborockBase,
12
+ SmartWashParams,
13
+ Status,
14
+ WashTowelMode,
15
+ )
16
+
17
+
18
+ class RoborockCommand(str, Enum):
19
+ """Enum of all known Roborock V1 protocol commands.
20
+
21
+ These commands can be sent to a device using the `CommandTrait`.
22
+ For example: `device.v1_properties.command.send(RoborockCommand.APP_START)`.
23
+ """
24
+
25
+ ADD_MOP_TEMPLATE_PARAMS = "add_mop_template_params"
26
+ APP_AMETHYST_SELF_CHECK = "app_amethyst_self_check"
27
+ APP_CHARGE = "app_charge"
28
+ APP_DELETE_WIFI = "app_delete_wifi"
29
+ APP_GET_AMETHYST_STATUS = "app_get_amethyst_status"
30
+ APP_GET_CARPET_DEEP_CLEAN_STATUS = "app_get_carpet_deep_clean_status"
31
+ APP_GET_CLEAN_ESTIMATE_INFO = "app_get_clean_estimate_info"
32
+ APP_GET_DRYER_SETTING = "app_get_dryer_setting"
33
+ APP_GET_INIT_STATUS = "app_get_init_status"
34
+ APP_GET_LOCALE = "app_get_locale"
35
+ APP_GET_WIFI_LIST = "app_get_wifi_list"
36
+ APP_GOTO_TARGET = "app_goto_target"
37
+ APP_KEEP_EASTER_EGG = "app_keep_easter_egg"
38
+ APP_PAUSE = "app_pause"
39
+ APP_RC_END = "app_rc_end"
40
+ APP_RC_MOVE = "app_rc_move"
41
+ APP_RC_START = "app_rc_start"
42
+ APP_RC_STOP = "app_rc_stop"
43
+ APP_RESUME_BUILD_MAP = "app_resume_build_map"
44
+ APP_RESUME_PATROL = "app_resume_patrol"
45
+ APP_SEGMENT_CLEAN = "app_segment_clean"
46
+ APP_SET_AMETHYST_STATUS = "app_set_amethyst_status"
47
+ APP_SET_CARPET_DEEP_CLEAN_STATUS = "app_set_carpet_deep_clean_status"
48
+ APP_SET_CROSS_CARPET_CLEANING_STATUS = "app_set_cross_carpet_cleaning_status"
49
+ APP_SET_DOOR_SILL_BLOCKS = "app_set_door_sill_blocks"
50
+ APP_SET_DIRTY_REPLENISH_CLEAN_STATUS = "app_set_dirty_replenish_clean_status"
51
+ APP_SET_DRYER_SETTING = "app_set_dryer_setting"
52
+ APP_SET_DRYER_STATUS = "app_set_dryer_status"
53
+ APP_SET_DYNAMIC_CONFIG = "app_set_dynamic_config"
54
+ APP_SET_IGNORE_STUCK_POINT = "app_set_ignore_stuck_point"
55
+ APP_SET_SMART_CLIFF_FORBIDDEN = "app_set_smart_cliff_forbidden"
56
+ APP_SET_SMART_DOOR_SILL = "app_set_smart_door_sill"
57
+ APP_SPOT = "app_spot"
58
+ APP_START = "app_start"
59
+ APP_START_BUILD_MAP = "app_start_build_map"
60
+ APP_START_COLLECT_DUST = "app_start_collect_dust"
61
+ APP_START_EASTER_EGG = "app_start_easter_egg"
62
+ APP_START_PATROL = "app_start_patrol"
63
+ APP_START_PET_PATROL = "app_start_pet_patrol"
64
+ APP_START_WASH = "app_start_wash"
65
+ APP_STAT = "app_stat"
66
+ APP_STOP = "app_stop"
67
+ APP_STOP_COLLECT_DUST = "app_stop_collect_dust"
68
+ APP_STOP_WASH = "app_stop_wash"
69
+ APP_UPDATE_UNSAVE_MAP = "app_update_unsave_map"
70
+ APP_WAKEUP_ROBOT = "app_wakeup_robot"
71
+ APP_ZONED_CLEAN = "app_zoned_clean"
72
+ CHANGE_SOUND_VOLUME = "change_sound_volume"
73
+ CHECK_HOMESEC_PASSWORD = "check_homesec_password"
74
+ CLOSE_DND_TIMER = "close_dnd_timer"
75
+ CLOSE_VALLEY_ELECTRICITY_TIMER = "close_valley_electricity_timer"
76
+ DEL_CLEAN_RECORD = "del_clean_record"
77
+ DEL_CLEAN_RECORD_MAP_V2 = "del_clean_record_map_v2"
78
+ DEL_MAP = "del_map"
79
+ DEL_MOP_TEMPLATE_PARAMS = "del_mop_template_params"
80
+ DEL_SERVER_TIMER = "del_server_timer"
81
+ DEL_TIMER = "del_timer"
82
+ DNLD_INSTALL_SOUND = "dnld_install_sound"
83
+ ENABLE_HOMESEC_VOICE = "enable_homesec_voice"
84
+ ENABLE_LOG_UPLOAD = "enable_log_upload"
85
+ END_EDIT_MAP = "end_edit_map"
86
+ FIND_ME = "find_me"
87
+ GET_AUTO_DELIVERY_CLEANING_FLUID = "get_auto_delivery_cleaning_fluid"
88
+ GET_CAMERA_STATUS = "get_camera_status"
89
+ GET_CARPET_CLEAN_MODE = "get_carpet_clean_mode"
90
+ GET_CARPET_MODE = "get_carpet_mode"
91
+ GET_CHILD_LOCK_STATUS = "get_child_lock_status"
92
+ GET_CLEAN_FOLLOW_GROUND_MATERIAL_STATUS = "get_clean_follow_ground_material_status"
93
+ GET_CLEAN_MOTOR_MODE = "get_clean_motor_mode"
94
+ GET_CLEAN_RECORD = "get_clean_record"
95
+ GET_CLEAN_RECORD_MAP = "get_clean_record_map"
96
+ GET_CLEAN_SEQUENCE = "get_clean_sequence"
97
+ GET_CLEAN_SUMMARY = "get_clean_summary"
98
+ GET_COLLISION_AVOID_STATUS = "get_collision_avoid_status"
99
+ GET_CONSUMABLE = "get_consumable"
100
+ GET_CURRENT_SOUND = "get_current_sound"
101
+ GET_CUSTOM_MODE = "get_custom_mode"
102
+ GET_CUSTOMIZE_CLEAN_MODE = "get_customize_clean_mode"
103
+ GET_DEVICE_ICE = "get_device_ice"
104
+ GET_DEVICE_SDP = "get_device_sdp"
105
+ GET_DND_TIMER = "get_dnd_timer"
106
+ GET_DOCK_INFO = "get_dock_info"
107
+ GET_DUST_COLLECTION_MODE = "get_dust_collection_mode"
108
+ GET_DUST_COLLECTION_SWITCH_STATUS = "get_dust_collection_switch_status"
109
+ GET_DYNAMIC_DATA = "get_dynamic_data"
110
+ GET_DYNAMIC_MAP_DIFF = "get_dynamic_map_diff"
111
+ GET_FAN_MOTOR_WORK_TIMEOUT = "get_fan_motor_work_timeout"
112
+ GET_FLOW_LED_STATUS = "get_flow_led_status"
113
+ GET_FRESH_MAP = "get_fresh_map"
114
+ GET_FW_FEATURES = "get_fw_features"
115
+ GET_HOMESEC_CONNECT_STATUS = "get_homesec_connect_status"
116
+ GET_IDENTIFY_FURNITURE_STATUS = "get_identify_furniture_status"
117
+ GET_IDENTIFY_GROUND_MATERIAL_STATUS = "get_identify_ground_material_status"
118
+ GET_LED_STATUS = "get_led_status"
119
+ GET_LOG_UPLOAD_STATUS = "get_log_upload_status"
120
+ GET_MAP = "get_map"
121
+ GET_MAP_BEAUTIFICATION_STATUS = "get_map_beautification_status"
122
+ GET_MAP_STATUS = "get_map_status"
123
+ GET_MAP_V1 = "get_map_v1"
124
+ GET_MAP_V2 = "get_map_v2"
125
+ GET_MAP_CALIBRATION = "get_map_calibration" # Custom command
126
+ GET_MOP_MOTOR_STATUS = "get_mop_motor_status"
127
+ GET_MOP_TEMPLATE_PARAMS_BY_ID = "get_mop_template_params_by_id"
128
+ GET_MOP_TEMPLATE_PARAMS_SUMMARY = "get_mop_template_params_summary"
129
+ GET_MULTI_MAP = "get_multi_map"
130
+ GET_MULTI_MAPS_LIST = "get_multi_maps_list"
131
+ GET_NETWORK_INFO = "get_network_info"
132
+ GET_OFFLINE_MAP_STATUS = "get_offline_map_status"
133
+ GET_PERSIST = "get_persist_map"
134
+ GET_PROP = "get_prop"
135
+ GET_RANDOM_PKEY = "get_random_pkey"
136
+ GET_RECOVER_MAP = "get_recover_map"
137
+ GET_RECOVER_MAPS = "get_recover_maps"
138
+ GET_ROOM_MAPPING = "get_room_mapping"
139
+ GET_SCENES_VALID_TIDS = "get_scenes_valid_tids"
140
+ GET_SEGMENT_STATUS = "get_segment_status"
141
+ GET_SERIAL_NUMBER = "get_serial_number"
142
+ GET_SERVER_TIMER = "get_server_timer"
143
+ GET_SMART_WASH_PARAMS = "get_smart_wash_params"
144
+ GET_SOUND_PROGRESS = "get_sound_progress"
145
+ GET_SOUND_VOLUME = "get_sound_volume"
146
+ GET_STATUS = "get_status"
147
+ GET_TESTID = "get_testid"
148
+ GET_TIMER = "get_timer"
149
+ GET_TIMER_DETAIL = "get_timer_detail"
150
+ GET_TIMER_SUMMARY = "get_timer_summary"
151
+ GET_TIMEZONE = "get_timezone"
152
+ GET_TURN_SERVER = "get_turn_server"
153
+ GET_VALLEY_ELECTRICITY_TIMER = "get_valley_electricity_timer"
154
+ GET_WASH_DEBUG_PARAMS = "get_wash_debug_params"
155
+ GET_WASH_TOWEL_MODE = "get_wash_towel_mode"
156
+ GET_WASH_TOWEL_PARAMS = "get_wash_towel_params"
157
+ GET_WATER_BOX_CUSTOM_MODE = "get_water_box_custom_mode"
158
+ LOAD_MULTI_MAP = "load_multi_map"
159
+ MANUAL_BAK_MAP = "manual_bak_map"
160
+ MANUAL_SEGMENT_MAP = "manual_segment_map"
161
+ MERGE_SEGMENT = "merge_segment"
162
+ MOP_MODE = "mop_mode"
163
+ MOP_TEMPLATE_ID = "mop_template_id"
164
+ NAME_MULTI_MAP = "name_multi_map"
165
+ NAME_SEGMENT = "name_segment"
166
+ PLAY_AUDIO = "play_audio"
167
+ RECOVER_MAP = "recover_map"
168
+ RECOVER_MULTI_MAP = "recover_multi_map"
169
+ RESET_CONSUMABLE = "reset_consumable"
170
+ RESET_HOMESEC_PASSWORD = "reset_homesec_password"
171
+ RESET_MAP = "reset_map"
172
+ RESOLVE_ERROR = "resolve_error"
173
+ RESUME_SEGMENT_CLEAN = "resume_segment_clean"
174
+ RESUME_ZONED_CLEAN = "resume_zoned_clean"
175
+ RETRY_REQUEST = "retry_request"
176
+ REUNION_SCENES = "reunion_scenes"
177
+ SAVE_FURNITURES = "save_furnitures"
178
+ SAVE_MAP = "save_map"
179
+ SEND_ICE_TO_ROBOT = "send_ice_to_robot"
180
+ SEND_SDP_TO_ROBOT = "send_sdp_to_robot"
181
+ SET_AIRDRY_HOURS = "set_airdry_hours"
182
+ SET_APP_TIMEZONE = "set_app_timezone"
183
+ SET_AUTO_DELIVERY_CLEANING_FLUID = "set_auto_delivery_cleaning_fluid"
184
+ SET_CAMERA_STATUS = "set_camera_status"
185
+ SET_CARPET_AREA = "set_carpet_area"
186
+ SET_CARPET_CLEAN_MODE = "set_carpet_clean_mode"
187
+ SET_CARPET_MODE = "set_carpet_mode"
188
+ SET_CHILD_LOCK_STATUS = "set_child_lock_status"
189
+ SET_CLEAN_FOLLOW_GROUND_MATERIAL_STATUS = "set_clean_follow_ground_material_status"
190
+ SET_CLEAN_MOTOR_MODE = "set_clean_motor_mode"
191
+ SET_CLEAN_SEQUENCE = "set_clean_sequence"
192
+ SET_CLEAN_REPEAT_TIMES = "set_clean_repeat_times"
193
+ SET_COLLISION_AVOID_STATUS = "set_collision_avoid_status"
194
+ SET_CUSTOM_MODE = "set_custom_mode"
195
+ SET_CUSTOMIZE_CLEAN_MODE = "set_customize_clean_mode"
196
+ SET_DND_TIMER = "set_dnd_timer"
197
+ SET_DND_TIMER_ACTIONS = "set_dnd_timer_actions"
198
+ SET_DUST_COLLECTION_MODE = "set_dust_collection_mode"
199
+ SET_DUST_COLLECTION_SWITCH_STATUS = "set_dust_collection_switch_status"
200
+ SET_FAN_MOTOR_WORK_TIMEOUT = "set_fan_motor_work_timeout"
201
+ SET_FDS_ENDPOINT = "set_fds_endpoint"
202
+ SET_FLOW_LED_STATUS = "set_flow_led_status"
203
+ SET_HOMESEC_PASSWORD = "set_homesec_password"
204
+ SET_IDENTIFY_FURNITURE_STATUS = "set_identify_furniture_status"
205
+ SET_IDENTIFY_GROUND_MATERIAL_STATUS = "set_identify_ground_material_status"
206
+ SET_IGNORE_CARPET_ZONE = "set_ignore_carpet_zone"
207
+ SET_IGNORE_IDENTIFY_AREA = "set_ignore_identify_area"
208
+ SET_LAB_STATUS = "set_lab_status"
209
+ SET_LED_STATUS = "set_led_status"
210
+ SET_MAP_BEAUTIFICATION_STATUS = "set_map_beautification_status"
211
+ SET_MOP_MODE = "set_mop_mode"
212
+ SET_MOP_MOTOR_STATUS = "set_mop_motor_status"
213
+ SET_MOP_TEMPLATE_ID = "set_mop_template_id"
214
+ SET_OFFLINE_MAP_STATUS = "set_offline_map_status"
215
+ SET_SCENES_SEGMENTS = "set_scenes_segments"
216
+ SET_SCENES_ZONES = "set_scenes_zones"
217
+ SET_SEGMENT_GROUND_MATERIAL = "set_segment_ground_material"
218
+ SET_SERVER_TIMER = "set_server_timer"
219
+ SET_SMART_WASH_PARAMS = "set_smart_wash_params"
220
+ SET_SWITCH_MOP_MODE = "set_switch_map_mode"
221
+ SET_TIMER = "set_timer"
222
+ SET_TIMEZONE = "set_timezone"
223
+ SET_VALLEY_ELECTRICITY_TIMER = "set_valley_electricity_timer"
224
+ SET_VOICE_CHAT_VOLUME = "set_voice_chat_volume"
225
+ SET_WASH_DEBUG_PARAMS = "set_wash_debug_params"
226
+ SET_WASH_TOWEL_MODE = "set_wash_towel_mode"
227
+ SET_WASH_TOWEL_PARAMS = "set_wash_towel_params"
228
+ SET_WATER_BOX_CUSTOM_MODE = "set_water_box_custom_mode"
229
+ SET_WATER_BOX_DISTANCE_OFF = "set_water_box_distance_off"
230
+ SORT_MOP_TEMPLATE_PARAMS = "sort_mop_template_params"
231
+ SPLIT_SEGMENT = "split_segment"
232
+ START_CAMERA_PREVIEW = "start_camera_preview"
233
+ START_CLEAN = "start_clean"
234
+ START_EDIT_MAP = "start_edit_map"
235
+ START_VOICE_CHAT = "start_voice_chat"
236
+ START_WASH_THEN_CHARGE = "start_wash_then_charge"
237
+ STOP_CAMERA_PREVIEW = "stop_camera_preview"
238
+ STOP_FAN_MOTOR_WORK = "stop_fan_motor_work"
239
+ STOP_GOTO_TARGET = "stop_goto_target"
240
+ STOP_SEGMENT_CLEAN = "stop_segment_clean"
241
+ STOP_VOICE_CHAT = "stop_voice_chat"
242
+ STOP_ZONED_CLEAN = "stop_zoned_clean"
243
+ SWITCH_VIDEO_QUALITY = "switch_video_quality"
244
+ SWITCH_WATER_MARK = "switch_water_mark"
245
+ TEST_SOUND_VOLUME = "test_sound_volume"
246
+ UPD_SERVER_TIMER = "upd_server_timer"
247
+ UPD_TIMER = "upd_timer"
248
+ UPDATE_DOCK = "update_dock"
249
+ UPDATE_MOP_TEMPLATE_PARAMS = "update_mop_template_params"
250
+ UPLOAD_DATA_FOR_DEBUG_MODE = "upload_data_for_debug_mode"
251
+ UPLOAD_PHOTO = "upload_photo"
252
+ USE_NEW_MAP = "use_new_map"
253
+ USE_OLD_MAP = "use_old_map"
254
+ USER_UPLOAD_LOG = "user_upload_log"
255
+ SET_STRETCH_TAG_STATUS = "set_stretch_tag_status"
256
+ GET_STRETCH_TAG_STATUS = "get_stretch_tag_status"
257
+ SET_RIGHT_BRUSH_STRETCH_STATUS = "set_right_brush_stretch_status"
258
+ GET_RIGHT_BRUSH_STRETCH_STATUS = "get_right_brush_stretch_status"
259
+ SET_DIRTY_OBJECT_DETECT_STATUS = "set_dirty_object_detect_status"
260
+ GET_DIRTY_OBJECT_DETECT_STATUS = "get_dirty_object_detect_status"
261
+ SET_WASH_WATER_TEMPERATURE = "set_wash_water_temperature"
262
+ GET_WASH_WATER_TEMPERATURE = "get_wash_water_temperature"
263
+ APP_EMPTY_RINSE_TANK_WATER = "app_empty_rinse_tank_water"
264
+ SET_PET_SUPPLIES_DEEP_CLEAN_STATUS = "set_pet_supplies_deep_clean_status"
265
+ GET_PET_SUPPLIES_DEEP_CLEAN_STATUS = "get_pet_supplies_deep_clean_status"
266
+ SET_AP_MIC_LED_STATUS = "set_ap_mic_led_status"
267
+ GET_AP_MIC_LED_STATUS = "get_ap_mic_led_status"
268
+ SET_HANDLE_LEAK_WATER_STATUS = "set_handle_leak_water_status"
269
+ GET_HANDLE_LEAK_WATER_STATUS = "get_handle_leak_water_status"
270
+ APP_IGNORE_DIRTY_OBJECTS = "app_ignore_dirty_objects"
271
+ MATTER_GET_STATUS = "matter.get_status"
272
+ MATTER_DNLD_KEY = "matter.dnld_key"
273
+ MATTER_RESET = "matter.reset"
274
+ SET_GAP_DEEP_CLEAN_STATUS = "set_gap_deep_clean_status"
275
+ GET_GAP_DEEP_CLEAN_STATUS = "get_gap_deep_clean_status"
276
+ APP_SET_ROBOT_SETTING = "app_set_robot_setting"
277
+ APP_GET_ROBOT_SETTING = "app_get_robot_setting"
278
+
279
+
280
+ class RoborockB01Q7Methods(StrEnum):
281
+ """Methods used by the Roborock Q7 model."""
282
+
283
+ # NOTE: In the Q7 Hermes dump these appear as suffixes and are also used
284
+ # with an "event." prefix at runtime (see `hermes/.../module_524.js`).
285
+ ADD_CLEAN_FAILED_POST = "add_clean_failed.post"
286
+ EVENT_ADD_CLEAN_FAILED_POST = "event.add_clean_failed.post"
287
+ CLEAN_FINISH_POST = "clean_finish.post"
288
+ EVENT_CLEAN_FINISH_POST = "event.clean_finish.post"
289
+ EVENT_BUILD_MAP_FINISH_POST = "event.BuildMapFinish.post"
290
+ EVENT_MAP_CHANGE_POST = "event.map_change.post"
291
+ EVENT_WORK_APPOINT_CLEAN_FAILED_POST = "event.work_appoint_clean_failed.post"
292
+ START_CLEAN_POST = "startClean.post"
293
+ ADD_ORDER = "service.add_order"
294
+ ADD_SWEEP_CLEAN = "service.add_sweep_clean"
295
+ ARRANGE_ROOM = "service.arrange_room"
296
+ DEL_MAP = "service.del_map"
297
+ DEL_ORDER = "service.del_order"
298
+ DEL_ORDERS = "service.del_orders"
299
+ DELETE_RECORD_BY_URL = "service.delete_record_by_url"
300
+ DOWNLOAD_VOICE_TYPE = "service.download_voice_type"
301
+ ERASE_PREFERENCE = "service.erase_preference"
302
+ FIND_DEVICE = "service.find_device"
303
+ GET_ROOM_ORDER = "service.get_room_order"
304
+ GET_VOICE_DOWNLOAD = "service.get_voice_download"
305
+ HELLO_WIKKA = "service.hello_wikka"
306
+ RENAME_MAP = "service.rename_map"
307
+ RENAME_ROOM = "service.rename_room"
308
+ RENAME_ROOMS = "service.rename_rooms"
309
+ REPLACE_MAP = "service.replace_map"
310
+ RESET_CONSUMABLE = "service.reset_consumable"
311
+ SAVE_CARPET = "service.save_carpet"
312
+ SAVE_RECOMMEND_FB = "service.save_recommend_fb"
313
+ SAVE_SILL = "service.save_sill"
314
+ SET_AREA_START = "service.set_area_start"
315
+ SET_AREAS_START = "service.set_areas_start"
316
+ SET_CUR_MAP = "service.set_cur_map"
317
+ SET_DIRECTION = "service.set_direction"
318
+ SET_GLOBAL_SORT = "service.set_global_sort"
319
+ SET_MAP_HIDE = "service.set_map_hide"
320
+ SET_MULTI_ROOM_MATERIAL = "service.set_multi_room_material"
321
+ SET_POINT_CLEAN = "service.set_point_clean"
322
+ SET_PREFERENCE = "service.set_preference"
323
+ SET_PREFERENCE_TYPE = "service.set_preference_type"
324
+ SET_QUIET_TIME = "service.set_quiet_time"
325
+ SET_ROOM_CLEAN = "service.set_room_clean"
326
+ SET_ROOM_ORDER = "service.set_room_order"
327
+ SET_VIRTUAL_WALL = "service.set_virtual_wall"
328
+ SET_ZONE_CLEAN = "service.set_zone_clean"
329
+ SET_ZONE_POINTS = "service.set_zone_points"
330
+ SPLIT_ROOM = "service.split_room"
331
+ START_EXPLORE = "service.start_explore"
332
+ START_POINT_CLEAN = "service.start_point_clean"
333
+ START_RECHARGE = "service.start_recharge"
334
+ STOP_RECHARGE = "service.stop_recharge"
335
+ UPLOAD_BY_MAPID = "service.upload_by_mapid"
336
+ UPLOAD_RECORD_BY_URL = "service.upload_record_by_url"
337
+ GET_PROP = "prop.get"
338
+ GET_MAP_LIST = "service.get_map_list"
339
+ UPLOAD_BY_MAPTYPE = "service.upload_by_maptype"
340
+ SET_PROP = "prop.set"
341
+ GET_PREFERENCE = "service.get_preference"
342
+ GET_RECORD_LIST = "service.get_record_list"
343
+ GET_ORDER = "service.get_order"
344
+ POST_PROP = "prop.post"
345
+
346
+
347
+ @dataclass
348
+ class DockSummary(RoborockBase):
349
+ dust_collection_mode: DustCollectionMode | None = None
350
+ wash_towel_mode: WashTowelMode | None = None
351
+ smart_wash_params: SmartWashParams | None = None
352
+
353
+
354
+ @dataclass
355
+ class DeviceProp(RoborockBase):
356
+ status: Status = field(default_factory=Status)
357
+ clean_summary: CleanSummary = field(default_factory=CleanSummary)
358
+ consumable: Consumable = field(default_factory=Consumable)
359
+ last_clean_record: CleanRecord | None = None
360
+ dock_summary: DockSummary | None = None
361
+ dust_collection_mode_name: str | None = None
362
+
363
+ def __post_init__(self) -> None:
364
+ if (
365
+ self.dock_summary
366
+ and self.dock_summary.dust_collection_mode is not None
367
+ and self.dock_summary.dust_collection_mode.mode is not None
368
+ ):
369
+ self.dust_collection_mode_name = self.dock_summary.dust_collection_mode.mode.name
370
+
371
+ def update(self, device_prop: DeviceProp) -> None:
372
+ if device_prop.status:
373
+ self.status = device_prop.status
374
+ if device_prop.clean_summary:
375
+ self.clean_summary = device_prop.clean_summary
376
+ if device_prop.consumable:
377
+ self.consumable = device_prop.consumable
378
+ if device_prop.last_clean_record:
379
+ self.last_clean_record = device_prop.last_clean_record
380
+ if device_prop.dock_summary:
381
+ self.dock_summary = device_prop.dock_summary
382
+ self.__post_init__()
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import math
5
+ import time
6
+ from collections.abc import MutableMapping
7
+ from typing import Any, TypeVar
8
+
9
+ from roborock_cli._vendor.roborock.diagnostics import redact_device_uid
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ def unpack_list(value: list[T], size: int) -> list[T | None]:
15
+ return (value + [None] * size)[:size] # type: ignore
16
+
17
+
18
+ class RoborockLoggerAdapter(logging.LoggerAdapter):
19
+ def __init__(
20
+ self,
21
+ duid: str | None = None,
22
+ name: str | None = None,
23
+ logger: logging.Logger | None = None,
24
+ ) -> None:
25
+ super().__init__(logger or logging.getLogger(__name__), {})
26
+ if name is not None:
27
+ self.prefix = name
28
+ elif duid is not None:
29
+ self.prefix = redact_device_uid(duid)
30
+ else:
31
+ raise ValueError("Either duid or name must be provided")
32
+
33
+ def process(self, msg: str, kwargs: MutableMapping[str, Any]) -> tuple[str, MutableMapping[str, Any]]:
34
+ return f"[{self.prefix}] {msg}", kwargs
35
+
36
+
37
+ counter_map: dict[tuple[int, int], int] = {}
38
+
39
+
40
+ def get_next_int(min_val: int, max_val: int) -> int:
41
+ """Gets a random int in the range, precached to help keep it fast."""
42
+ if (min_val, max_val) not in counter_map:
43
+ # If we have never seen this range, or if the cache is getting low, make a bunch of preshuffled values.
44
+ counter_map[(min_val, max_val)] = min_val
45
+ counter_map[(min_val, max_val)] += 1
46
+ return counter_map[(min_val, max_val)] % max_val + min_val
47
+
48
+
49
+ def get_timestamp() -> int:
50
+ """Get the current timestamp in seconds since epoch.
51
+
52
+ This is separated out to allow for easier mocking in tests.
53
+ """
54
+ return math.floor(time.time())