roborock.data.v1.v1_clean_modes
1from __future__ import annotations 2 3import typing 4from enum import StrEnum 5from typing import TypeVar 6 7from ...exceptions import RoborockUnsupportedFeature 8from ..code_mappings import RoborockModeEnum 9 10if typing.TYPE_CHECKING: 11 from roborock.device_features import DeviceFeatures 12 13 14class VacuumModes(RoborockModeEnum): 15 GENTLE = ("gentle", 105) 16 OFF = ("off", 105) 17 QUIET = ("quiet", 101) 18 BALANCED = ("balanced", 102) 19 TURBO = ("turbo", 103) 20 MAX = ("max", 104) 21 MAX_PLUS = ("max_plus", 108) 22 OFF_RAISE_MAIN_BRUSH = ("off_raise_main_brush", 109) 23 CUSTOMIZED = ("custom", 106) 24 SMART_MODE = ("smart_mode", 110) 25 26 27class CleanRoutes(RoborockModeEnum): 28 STANDARD = ("standard", 300) 29 DEEP = ("deep", 301) 30 DEEP_PLUS = ("deep_plus", 303) 31 FAST = ("fast", 304) 32 DEEP_PLUS_CN = ("deep_plus", 305) 33 SMART_MODE = ("smart_mode", 306) 34 CUSTOMIZED = ("custom", 302) 35 36 37class VacuumModesOld(RoborockModeEnum): 38 QUIET = ("quiet", 38) 39 BALANCED = ("balanced", 60) 40 TURBO = ("turbo", 75) 41 MAX = ("max", 100) 42 43 44class WaterModes(RoborockModeEnum): 45 OFF = ("off", 200) 46 LOW = ("low", 201) 47 MILD = ("mild", 201) 48 MEDIUM = ("medium", 202) 49 STANDARD = ("standard", 202) 50 HIGH = ("high", 203) 51 INTENSE = ("intense", 203) 52 MIN = ("min", 205) 53 MAX = ("max", 206) 54 CUSTOMIZED = ("custom", 204) 55 CUSTOM = ("custom_water_flow", 207) 56 EXTREME = ("extreme", 208) 57 SMART_MODE = ("smart_mode", 209) 58 PURE_WATER_FLOW_START = ("slight", 221) 59 PURE_WATER_FLOW_SMALL = ("low", 225) 60 PURE_WATER_FLOW_MIDDLE = ("medium", 235) 61 PURE_WATER_FLOW_LARGE = ("moderate", 245) 62 PURE_WATER_SUPER_BEGIN = ("high", 248) 63 PURE_WATER_FLOW_END = ("extreme", 250) 64 65 66class WashTowelModes(RoborockModeEnum): 67 SMART = ("smart", 10) 68 LIGHT = ("light", 0) 69 BALANCED = ("balanced", 1) 70 DEEP = ("deep", 2) 71 SUPER_DEEP = ("super_deep", 8) 72 73 74class CleaningMode(StrEnum): 75 """High-level cleaning intent derived from the lower-level motor settings. 76 77 Prefer this abstraction when you want to present or switch between the 78 user-facing cleaning behaviors exposed by the app. The lower-level 79 `VacuumModes`, `WaterModes`, and `CleanRoutes` enums are still useful for 80 fine-grained selection. 81 """ 82 83 VACUUM = "vacuum" 84 VAC_AND_MOP = "vac_and_mop" 85 MOP = "mop" 86 CUSTOM = "custom" 87 SMART_MODE = "smart_mode" 88 89 90WATER_SLIDE_MODE_MAPPING: dict[int, WaterModes] = { 91 200: WaterModes.OFF, 92 221: WaterModes.PURE_WATER_FLOW_START, 93 225: WaterModes.PURE_WATER_FLOW_SMALL, 94 235: WaterModes.PURE_WATER_FLOW_MIDDLE, 95 245: WaterModes.PURE_WATER_FLOW_LARGE, 96 248: WaterModes.PURE_WATER_SUPER_BEGIN, 97 250: WaterModes.PURE_WATER_FLOW_END, 98} 99 100ModeEnumT = TypeVar("ModeEnumT", bound=RoborockModeEnum) 101 102 103def get_wash_towel_modes(features: DeviceFeatures) -> list[WashTowelModes]: 104 """Get the valid wash towel modes for the device""" 105 modes = [WashTowelModes.LIGHT, WashTowelModes.BALANCED, WashTowelModes.DEEP] 106 if features.is_super_deep_wash_supported and not features.is_dirty_replenish_clean_supported: 107 modes.append(WashTowelModes.SUPER_DEEP) 108 elif features.is_dirty_replenish_clean_supported: 109 modes.append(WashTowelModes.SMART) 110 return modes 111 112 113def get_clean_modes(features: DeviceFeatures) -> list[VacuumModes]: 114 """Get the valid clean modes for the device - also known as 'fan power' or 'suction mode'""" 115 modes = [VacuumModes.QUIET, VacuumModes.BALANCED, VacuumModes.TURBO, VacuumModes.MAX] 116 if features.is_max_plus_mode_supported or features.is_none_pure_clean_mop_with_max_plus: 117 # If the vacuum has max plus mode supported 118 modes.append(VacuumModes.MAX_PLUS) 119 if features.is_pure_clean_mop_supported: 120 # If the vacuum is capable of 'pure mop clean' aka no vacuum 121 if features.is_support_main_brush_up_down_supported: 122 modes.append(VacuumModes.OFF_RAISE_MAIN_BRUSH) 123 else: 124 modes.append(VacuumModes.OFF) 125 else: 126 # If not, we can add gentle 127 modes.append(VacuumModes.GENTLE) 128 if features.is_smart_clean_mode_set_supported: 129 modes.append(VacuumModes.SMART_MODE) 130 if features.is_customized_clean_supported: 131 modes.append(VacuumModes.CUSTOMIZED) 132 return modes 133 134 135def get_clean_routes(features: DeviceFeatures, region: str) -> list[CleanRoutes]: 136 """The routes that the vacuum will take while mopping""" 137 if features.is_none_pure_clean_mop_with_max_plus: 138 return [CleanRoutes.FAST, CleanRoutes.STANDARD] 139 supported = [CleanRoutes.STANDARD, CleanRoutes.DEEP] 140 if features.is_careful_slow_mop_supported: 141 if not ( 142 features.is_corner_clean_mode_supported 143 and features.is_clean_route_deep_slow_plus_supported 144 and region == "cn" 145 ): 146 # for some reason there is a china specific deep plus mode 147 supported.append(CleanRoutes.DEEP_PLUS_CN) 148 else: 149 supported.append(CleanRoutes.DEEP_PLUS) 150 151 if features.is_clean_route_fast_mode_supported: 152 supported.append(CleanRoutes.FAST) 153 if features.is_smart_clean_mode_set_supported: 154 supported.append(CleanRoutes.SMART_MODE) 155 if features.is_customized_clean_supported: 156 supported.append(CleanRoutes.CUSTOMIZED) 157 158 return supported 159 160 161def get_water_modes(features: DeviceFeatures) -> list[WaterModes]: 162 """Get the valid water modes for the device - also known as 'water flow' or 'water level'""" 163 # Water slide mode supports a separate set of water flow codes. 164 if features.is_water_slide_mode_supported: 165 return list(WATER_SLIDE_MODE_MAPPING.values()) 166 167 supported_modes = [WaterModes.OFF] 168 if features.is_mop_shake_module_supported: 169 # For mops that have the vibrating mop pad, they do mild standard intense 170 supported_modes.extend([WaterModes.MILD, WaterModes.STANDARD, WaterModes.INTENSE]) 171 else: 172 supported_modes.extend([WaterModes.LOW, WaterModes.MEDIUM, WaterModes.HIGH]) 173 if features.is_custom_water_box_distance_supported: 174 # This is for devices that allow you to set a custom water flow from 0-100 175 supported_modes.append(WaterModes.CUSTOM) 176 if features.is_mop_shake_module_supported and features.is_mop_shake_water_max_supported: 177 supported_modes.append(WaterModes.EXTREME) 178 if features.is_smart_clean_mode_set_supported: 179 supported_modes.append(WaterModes.SMART_MODE) 180 if features.is_customized_clean_supported: 181 supported_modes.append(WaterModes.CUSTOMIZED) 182 183 return supported_modes 184 185 186def get_water_mode_mapping(features: DeviceFeatures) -> dict[int, str]: 187 """Get water mode mapping by supported feature set. 188 189 WaterModes contains aliases for multiple codes that share the same value 190 string (e.g. low can be 201 or 225). For water slide mode devices we need 191 explicit code mapping to preserve those slide-specific codes. 192 """ 193 if features.is_water_slide_mode_supported: 194 return {code: mode.value for code, mode in WATER_SLIDE_MODE_MAPPING.items()} 195 return {mode.code: mode.value for mode in get_water_modes(features)} 196 197 198def get_cleaning_mode_options(features: DeviceFeatures) -> list[CleaningMode]: 199 """Return the supported high-level cleaning modes for the device. 200 201 These options are the preferred user-facing choices because they bundle the 202 correct fan, water, and mop-route settings together for the device. Callers 203 should generally present these instead of mixing lower-level mode enums 204 unless they explicitly need fine-grained control. 205 """ 206 if not features.is_support_water_mode: 207 return [] 208 209 supported_water_modes = get_water_modes(features) 210 options = [CleaningMode.VACUUM, CleaningMode.VAC_AND_MOP] 211 if features.is_pure_clean_mop_supported: 212 options.append(CleaningMode.MOP) 213 if features.is_customized_clean_supported and WaterModes.CUSTOMIZED in supported_water_modes: 214 options.append(CleaningMode.CUSTOM) 215 if features.is_smart_clean_mode_set_supported and WaterModes.SMART_MODE in supported_water_modes: 216 options.append(CleaningMode.SMART_MODE) 217 return options 218 219 220def get_mop_only_vacuum_mode(features: DeviceFeatures) -> VacuumModes: 221 """Determine the vacuum mode to use when you just want to mop. 222 223 There are three cases that must be handled: 224 1. The device does not support only mopping. 225 2. The device supports raising the vacuum brush while mopping 226 3. All other cases. 227 """ 228 if not features.is_pure_clean_mop_supported: 229 raise RoborockUnsupportedFeature("Mop-only cleaning is not supported") 230 if features.is_support_main_brush_up_down_supported: 231 return VacuumModes.OFF_RAISE_MAIN_BRUSH 232 return VacuumModes.OFF 233 234 235def _get_default_mopping_water_mode(features: DeviceFeatures) -> WaterModes: 236 """Pick a sensible default water mode when mopping for the device.""" 237 # Water-slide devices use a disjoint set of water codes; pick a mid-flow 238 # slide code instead of the standard 202, which they don't accept. 239 if features.is_water_slide_mode_supported: 240 return WaterModes.PURE_WATER_FLOW_MIDDLE 241 return WaterModes.STANDARD 242 243 244def _get_clean_motor_mode_params( 245 mode: CleaningMode, 246 features: DeviceFeatures, 247) -> tuple[VacuumModes, WaterModes, CleanRoutes]: 248 """Return (fan_power, water_box_mode, mop_mode) enums for the high-level mode.""" 249 if mode == CleaningMode.VACUUM: 250 return (VacuumModes.BALANCED, WaterModes.OFF, CleanRoutes.STANDARD) 251 if mode == CleaningMode.VAC_AND_MOP: 252 return (VacuumModes.BALANCED, _get_default_mopping_water_mode(features), CleanRoutes.STANDARD) 253 if mode == CleaningMode.MOP: 254 return ( 255 get_mop_only_vacuum_mode(features), 256 _get_default_mopping_water_mode(features), 257 CleanRoutes.STANDARD, 258 ) 259 if mode == CleaningMode.CUSTOM: 260 return (VacuumModes.CUSTOMIZED, WaterModes.CUSTOMIZED, CleanRoutes.CUSTOMIZED) 261 if mode == CleaningMode.SMART_MODE: 262 return (VacuumModes.SMART_MODE, WaterModes.SMART_MODE, CleanRoutes.SMART_MODE) 263 raise RoborockUnsupportedFeature(f"Cleaning mode {mode.value!r} is not supported") 264 265 266def resolve_cleaning_mode(cleaning_mode: str | CleaningMode) -> CleaningMode: 267 """Resolve a string or enum into a CleaningMode value.""" 268 if isinstance(cleaning_mode, CleaningMode): 269 return cleaning_mode 270 try: 271 return CleaningMode(cleaning_mode) 272 except ValueError as err: 273 raise RoborockUnsupportedFeature(f"Cleaning mode {cleaning_mode!r} is not supported") from err 274 275 276def get_cleaning_mode_parameters(cleaning_mode: CleaningMode, features: DeviceFeatures) -> list[dict[str, int]]: 277 """Get the RPC payload for switching the high-level cleaning mode.""" 278 if cleaning_mode not in get_cleaning_mode_options(features): 279 raise RoborockUnsupportedFeature(f"Cleaning mode {cleaning_mode.value!r} is not supported") 280 281 fan_power, water_box_mode, mop_mode = _get_clean_motor_mode_params(cleaning_mode, features) 282 params: dict[str, int] = {"fan_power": fan_power.code, "water_box_mode": water_box_mode.code} 283 if features.is_clean_route_setting_supported: 284 params["mop_mode"] = mop_mode.code 285 return [params] 286 287 288def _resolve_mode_code(value: int | ModeEnumT | None, mode_cls: type[ModeEnumT]) -> ModeEnumT | None: 289 """Resolve a raw code or enum into a RoborockModeEnum.""" 290 if value is None: 291 return None 292 if isinstance(value, mode_cls): 293 return value 294 return mode_cls.from_code_optional(int(value)) 295 296 297def _resolve_clean_mode(value: int | VacuumModes | None, features: DeviceFeatures) -> VacuumModes | None: 298 """Resolve a vacuum mode code, accounting for feature-specific code aliases.""" 299 if value is None or isinstance(value, VacuumModes): 300 return value 301 if value == VacuumModes.OFF.code: 302 if features.is_pure_clean_mop_supported: 303 return get_mop_only_vacuum_mode(features) 304 return VacuumModes.GENTLE 305 return VacuumModes.from_code_optional(value) 306 307 308def get_current_cleaning_mode( 309 clean_mode: int | VacuumModes | None, 310 water_mode: int | WaterModes | None, 311 mop_mode: int | CleanRoutes | None, 312 features: DeviceFeatures, 313) -> CleaningMode | None: 314 """Classify the current high-level cleaning mode from individual mode codes.""" 315 if not features.is_support_water_mode: 316 return None 317 clean_mode_enum = _resolve_clean_mode(clean_mode, features) 318 water_mode_enum = _resolve_mode_code(water_mode, WaterModes) 319 mop_mode_enum = _resolve_mode_code(mop_mode, CleanRoutes) 320 if clean_mode_enum is None or water_mode_enum is None: 321 return None 322 323 if is_smart_mode_set(water_mode_enum, clean_mode_enum, mop_mode_enum): 324 return CleaningMode.SMART_MODE 325 if is_mode_customized(clean_mode_enum, water_mode_enum, mop_mode_enum): 326 return CleaningMode.CUSTOM 327 if water_mode_enum != WaterModes.OFF: 328 try: 329 if clean_mode_enum == get_mop_only_vacuum_mode(features): 330 return CleaningMode.MOP 331 except RoborockUnsupportedFeature: 332 pass 333 if water_mode_enum == WaterModes.OFF: 334 return CleaningMode.VACUUM 335 return CleaningMode.VAC_AND_MOP 336 337 338def is_mode_customized( 339 clean_mode: VacuumModes | None, 340 water_mode: WaterModes | None, 341 mop_mode: CleanRoutes | None, 342) -> bool: 343 """Check if any of the cleaning modes are set to a custom value.""" 344 return ( 345 clean_mode == VacuumModes.CUSTOMIZED 346 or water_mode == WaterModes.CUSTOMIZED 347 or mop_mode == CleanRoutes.CUSTOMIZED 348 ) 349 350 351def is_smart_mode_set( 352 water_mode: WaterModes | None, 353 clean_mode: VacuumModes | None, 354 mop_mode: CleanRoutes | None, 355) -> bool: 356 """Check if the smart mode is set for the given water mode and clean mode""" 357 return ( 358 water_mode == WaterModes.SMART_MODE 359 or clean_mode == VacuumModes.SMART_MODE 360 or mop_mode == CleanRoutes.SMART_MODE 361 )
15class VacuumModes(RoborockModeEnum): 16 GENTLE = ("gentle", 105) 17 OFF = ("off", 105) 18 QUIET = ("quiet", 101) 19 BALANCED = ("balanced", 102) 20 TURBO = ("turbo", 103) 21 MAX = ("max", 104) 22 MAX_PLUS = ("max_plus", 108) 23 OFF_RAISE_MAIN_BRUSH = ("off_raise_main_brush", 109) 24 CUSTOMIZED = ("custom", 106) 25 SMART_MODE = ("smart_mode", 110)
A custom StrEnum that also stores an integer code for each member.
28class CleanRoutes(RoborockModeEnum): 29 STANDARD = ("standard", 300) 30 DEEP = ("deep", 301) 31 DEEP_PLUS = ("deep_plus", 303) 32 FAST = ("fast", 304) 33 DEEP_PLUS_CN = ("deep_plus", 305) 34 SMART_MODE = ("smart_mode", 306) 35 CUSTOMIZED = ("custom", 302)
A custom StrEnum that also stores an integer code for each member.
38class VacuumModesOld(RoborockModeEnum): 39 QUIET = ("quiet", 38) 40 BALANCED = ("balanced", 60) 41 TURBO = ("turbo", 75) 42 MAX = ("max", 100)
A custom StrEnum that also stores an integer code for each member.
45class WaterModes(RoborockModeEnum): 46 OFF = ("off", 200) 47 LOW = ("low", 201) 48 MILD = ("mild", 201) 49 MEDIUM = ("medium", 202) 50 STANDARD = ("standard", 202) 51 HIGH = ("high", 203) 52 INTENSE = ("intense", 203) 53 MIN = ("min", 205) 54 MAX = ("max", 206) 55 CUSTOMIZED = ("custom", 204) 56 CUSTOM = ("custom_water_flow", 207) 57 EXTREME = ("extreme", 208) 58 SMART_MODE = ("smart_mode", 209) 59 PURE_WATER_FLOW_START = ("slight", 221) 60 PURE_WATER_FLOW_SMALL = ("low", 225) 61 PURE_WATER_FLOW_MIDDLE = ("medium", 235) 62 PURE_WATER_FLOW_LARGE = ("moderate", 245) 63 PURE_WATER_SUPER_BEGIN = ("high", 248) 64 PURE_WATER_FLOW_END = ("extreme", 250)
A custom StrEnum that also stores an integer code for each member.
67class WashTowelModes(RoborockModeEnum): 68 SMART = ("smart", 10) 69 LIGHT = ("light", 0) 70 BALANCED = ("balanced", 1) 71 DEEP = ("deep", 2) 72 SUPER_DEEP = ("super_deep", 8)
A custom StrEnum that also stores an integer code for each member.
75class CleaningMode(StrEnum): 76 """High-level cleaning intent derived from the lower-level motor settings. 77 78 Prefer this abstraction when you want to present or switch between the 79 user-facing cleaning behaviors exposed by the app. The lower-level 80 `VacuumModes`, `WaterModes`, and `CleanRoutes` enums are still useful for 81 fine-grained selection. 82 """ 83 84 VACUUM = "vacuum" 85 VAC_AND_MOP = "vac_and_mop" 86 MOP = "mop" 87 CUSTOM = "custom" 88 SMART_MODE = "smart_mode"
High-level cleaning intent derived from the lower-level motor settings.
Prefer this abstraction when you want to present or switch between the
user-facing cleaning behaviors exposed by the app. The lower-level
VacuumModes, WaterModes, and CleanRoutes enums are still useful for
fine-grained selection.
104def get_wash_towel_modes(features: DeviceFeatures) -> list[WashTowelModes]: 105 """Get the valid wash towel modes for the device""" 106 modes = [WashTowelModes.LIGHT, WashTowelModes.BALANCED, WashTowelModes.DEEP] 107 if features.is_super_deep_wash_supported and not features.is_dirty_replenish_clean_supported: 108 modes.append(WashTowelModes.SUPER_DEEP) 109 elif features.is_dirty_replenish_clean_supported: 110 modes.append(WashTowelModes.SMART) 111 return modes
Get the valid wash towel modes for the device
114def get_clean_modes(features: DeviceFeatures) -> list[VacuumModes]: 115 """Get the valid clean modes for the device - also known as 'fan power' or 'suction mode'""" 116 modes = [VacuumModes.QUIET, VacuumModes.BALANCED, VacuumModes.TURBO, VacuumModes.MAX] 117 if features.is_max_plus_mode_supported or features.is_none_pure_clean_mop_with_max_plus: 118 # If the vacuum has max plus mode supported 119 modes.append(VacuumModes.MAX_PLUS) 120 if features.is_pure_clean_mop_supported: 121 # If the vacuum is capable of 'pure mop clean' aka no vacuum 122 if features.is_support_main_brush_up_down_supported: 123 modes.append(VacuumModes.OFF_RAISE_MAIN_BRUSH) 124 else: 125 modes.append(VacuumModes.OFF) 126 else: 127 # If not, we can add gentle 128 modes.append(VacuumModes.GENTLE) 129 if features.is_smart_clean_mode_set_supported: 130 modes.append(VacuumModes.SMART_MODE) 131 if features.is_customized_clean_supported: 132 modes.append(VacuumModes.CUSTOMIZED) 133 return modes
Get the valid clean modes for the device - also known as 'fan power' or 'suction mode'
136def get_clean_routes(features: DeviceFeatures, region: str) -> list[CleanRoutes]: 137 """The routes that the vacuum will take while mopping""" 138 if features.is_none_pure_clean_mop_with_max_plus: 139 return [CleanRoutes.FAST, CleanRoutes.STANDARD] 140 supported = [CleanRoutes.STANDARD, CleanRoutes.DEEP] 141 if features.is_careful_slow_mop_supported: 142 if not ( 143 features.is_corner_clean_mode_supported 144 and features.is_clean_route_deep_slow_plus_supported 145 and region == "cn" 146 ): 147 # for some reason there is a china specific deep plus mode 148 supported.append(CleanRoutes.DEEP_PLUS_CN) 149 else: 150 supported.append(CleanRoutes.DEEP_PLUS) 151 152 if features.is_clean_route_fast_mode_supported: 153 supported.append(CleanRoutes.FAST) 154 if features.is_smart_clean_mode_set_supported: 155 supported.append(CleanRoutes.SMART_MODE) 156 if features.is_customized_clean_supported: 157 supported.append(CleanRoutes.CUSTOMIZED) 158 159 return supported
The routes that the vacuum will take while mopping
162def get_water_modes(features: DeviceFeatures) -> list[WaterModes]: 163 """Get the valid water modes for the device - also known as 'water flow' or 'water level'""" 164 # Water slide mode supports a separate set of water flow codes. 165 if features.is_water_slide_mode_supported: 166 return list(WATER_SLIDE_MODE_MAPPING.values()) 167 168 supported_modes = [WaterModes.OFF] 169 if features.is_mop_shake_module_supported: 170 # For mops that have the vibrating mop pad, they do mild standard intense 171 supported_modes.extend([WaterModes.MILD, WaterModes.STANDARD, WaterModes.INTENSE]) 172 else: 173 supported_modes.extend([WaterModes.LOW, WaterModes.MEDIUM, WaterModes.HIGH]) 174 if features.is_custom_water_box_distance_supported: 175 # This is for devices that allow you to set a custom water flow from 0-100 176 supported_modes.append(WaterModes.CUSTOM) 177 if features.is_mop_shake_module_supported and features.is_mop_shake_water_max_supported: 178 supported_modes.append(WaterModes.EXTREME) 179 if features.is_smart_clean_mode_set_supported: 180 supported_modes.append(WaterModes.SMART_MODE) 181 if features.is_customized_clean_supported: 182 supported_modes.append(WaterModes.CUSTOMIZED) 183 184 return supported_modes
Get the valid water modes for the device - also known as 'water flow' or 'water level'
187def get_water_mode_mapping(features: DeviceFeatures) -> dict[int, str]: 188 """Get water mode mapping by supported feature set. 189 190 WaterModes contains aliases for multiple codes that share the same value 191 string (e.g. low can be 201 or 225). For water slide mode devices we need 192 explicit code mapping to preserve those slide-specific codes. 193 """ 194 if features.is_water_slide_mode_supported: 195 return {code: mode.value for code, mode in WATER_SLIDE_MODE_MAPPING.items()} 196 return {mode.code: mode.value for mode in get_water_modes(features)}
Get water mode mapping by supported feature set.
WaterModes contains aliases for multiple codes that share the same value string (e.g. low can be 201 or 225). For water slide mode devices we need explicit code mapping to preserve those slide-specific codes.
199def get_cleaning_mode_options(features: DeviceFeatures) -> list[CleaningMode]: 200 """Return the supported high-level cleaning modes for the device. 201 202 These options are the preferred user-facing choices because they bundle the 203 correct fan, water, and mop-route settings together for the device. Callers 204 should generally present these instead of mixing lower-level mode enums 205 unless they explicitly need fine-grained control. 206 """ 207 if not features.is_support_water_mode: 208 return [] 209 210 supported_water_modes = get_water_modes(features) 211 options = [CleaningMode.VACUUM, CleaningMode.VAC_AND_MOP] 212 if features.is_pure_clean_mop_supported: 213 options.append(CleaningMode.MOP) 214 if features.is_customized_clean_supported and WaterModes.CUSTOMIZED in supported_water_modes: 215 options.append(CleaningMode.CUSTOM) 216 if features.is_smart_clean_mode_set_supported and WaterModes.SMART_MODE in supported_water_modes: 217 options.append(CleaningMode.SMART_MODE) 218 return options
Return the supported high-level cleaning modes for the device.
These options are the preferred user-facing choices because they bundle the correct fan, water, and mop-route settings together for the device. Callers should generally present these instead of mixing lower-level mode enums unless they explicitly need fine-grained control.
221def get_mop_only_vacuum_mode(features: DeviceFeatures) -> VacuumModes: 222 """Determine the vacuum mode to use when you just want to mop. 223 224 There are three cases that must be handled: 225 1. The device does not support only mopping. 226 2. The device supports raising the vacuum brush while mopping 227 3. All other cases. 228 """ 229 if not features.is_pure_clean_mop_supported: 230 raise RoborockUnsupportedFeature("Mop-only cleaning is not supported") 231 if features.is_support_main_brush_up_down_supported: 232 return VacuumModes.OFF_RAISE_MAIN_BRUSH 233 return VacuumModes.OFF
Determine the vacuum mode to use when you just want to mop.
There are three cases that must be handled:
- The device does not support only mopping.
- The device supports raising the vacuum brush while mopping
- All other cases.
267def resolve_cleaning_mode(cleaning_mode: str | CleaningMode) -> CleaningMode: 268 """Resolve a string or enum into a CleaningMode value.""" 269 if isinstance(cleaning_mode, CleaningMode): 270 return cleaning_mode 271 try: 272 return CleaningMode(cleaning_mode) 273 except ValueError as err: 274 raise RoborockUnsupportedFeature(f"Cleaning mode {cleaning_mode!r} is not supported") from err
Resolve a string or enum into a CleaningMode value.
277def get_cleaning_mode_parameters(cleaning_mode: CleaningMode, features: DeviceFeatures) -> list[dict[str, int]]: 278 """Get the RPC payload for switching the high-level cleaning mode.""" 279 if cleaning_mode not in get_cleaning_mode_options(features): 280 raise RoborockUnsupportedFeature(f"Cleaning mode {cleaning_mode.value!r} is not supported") 281 282 fan_power, water_box_mode, mop_mode = _get_clean_motor_mode_params(cleaning_mode, features) 283 params: dict[str, int] = {"fan_power": fan_power.code, "water_box_mode": water_box_mode.code} 284 if features.is_clean_route_setting_supported: 285 params["mop_mode"] = mop_mode.code 286 return [params]
Get the RPC payload for switching the high-level cleaning mode.
309def get_current_cleaning_mode( 310 clean_mode: int | VacuumModes | None, 311 water_mode: int | WaterModes | None, 312 mop_mode: int | CleanRoutes | None, 313 features: DeviceFeatures, 314) -> CleaningMode | None: 315 """Classify the current high-level cleaning mode from individual mode codes.""" 316 if not features.is_support_water_mode: 317 return None 318 clean_mode_enum = _resolve_clean_mode(clean_mode, features) 319 water_mode_enum = _resolve_mode_code(water_mode, WaterModes) 320 mop_mode_enum = _resolve_mode_code(mop_mode, CleanRoutes) 321 if clean_mode_enum is None or water_mode_enum is None: 322 return None 323 324 if is_smart_mode_set(water_mode_enum, clean_mode_enum, mop_mode_enum): 325 return CleaningMode.SMART_MODE 326 if is_mode_customized(clean_mode_enum, water_mode_enum, mop_mode_enum): 327 return CleaningMode.CUSTOM 328 if water_mode_enum != WaterModes.OFF: 329 try: 330 if clean_mode_enum == get_mop_only_vacuum_mode(features): 331 return CleaningMode.MOP 332 except RoborockUnsupportedFeature: 333 pass 334 if water_mode_enum == WaterModes.OFF: 335 return CleaningMode.VACUUM 336 return CleaningMode.VAC_AND_MOP
Classify the current high-level cleaning mode from individual mode codes.
339def is_mode_customized( 340 clean_mode: VacuumModes | None, 341 water_mode: WaterModes | None, 342 mop_mode: CleanRoutes | None, 343) -> bool: 344 """Check if any of the cleaning modes are set to a custom value.""" 345 return ( 346 clean_mode == VacuumModes.CUSTOMIZED 347 or water_mode == WaterModes.CUSTOMIZED 348 or mop_mode == CleanRoutes.CUSTOMIZED 349 )
Check if any of the cleaning modes are set to a custom value.
352def is_smart_mode_set( 353 water_mode: WaterModes | None, 354 clean_mode: VacuumModes | None, 355 mop_mode: CleanRoutes | None, 356) -> bool: 357 """Check if the smart mode is set for the given water mode and clean mode""" 358 return ( 359 water_mode == WaterModes.SMART_MODE 360 or clean_mode == VacuumModes.SMART_MODE 361 or mop_mode == CleanRoutes.SMART_MODE 362 )
Check if the smart mode is set for the given water mode and clean mode