roborock.data.v1.v1_clean_modes

  1from __future__ import annotations
  2
  3import typing
  4
  5from ..code_mappings import RoborockModeEnum
  6
  7if typing.TYPE_CHECKING:
  8    from roborock.device_features import DeviceFeatures
  9
 10
 11class VacuumModes(RoborockModeEnum):
 12    GENTLE = ("gentle", 105)
 13    OFF = ("off", 105)
 14    QUIET = ("quiet", 101)
 15    BALANCED = ("balanced", 102)
 16    TURBO = ("turbo", 103)
 17    MAX = ("max", 104)
 18    MAX_PLUS = ("max_plus", 108)
 19    OFF_RAISE_MAIN_BRUSH = ("off_raise_main_brush", 109)
 20    CUSTOMIZED = ("custom", 106)
 21    SMART_MODE = ("smart_mode", 110)
 22
 23
 24class CleanRoutes(RoborockModeEnum):
 25    STANDARD = ("standard", 300)
 26    DEEP = ("deep", 301)
 27    DEEP_PLUS = ("deep_plus", 303)
 28    FAST = ("fast", 304)
 29    DEEP_PLUS_CN = ("deep_plus", 305)
 30    SMART_MODE = ("smart_mode", 306)
 31    CUSTOMIZED = ("custom", 302)
 32
 33
 34class VacuumModesOld(RoborockModeEnum):
 35    QUIET = ("quiet", 38)
 36    BALANCED = ("balanced", 60)
 37    TURBO = ("turbo", 75)
 38    MAX = ("max", 100)
 39
 40
 41class WaterModes(RoborockModeEnum):
 42    OFF = ("off", 200)
 43    LOW = ("low", 201)
 44    MILD = ("mild", 201)
 45    MEDIUM = ("medium", 202)
 46    STANDARD = ("standard", 202)
 47    HIGH = ("high", 203)
 48    INTENSE = ("intense", 203)
 49    MIN = ("min", 205)
 50    MAX = ("max", 206)
 51    CUSTOMIZED = ("custom", 204)
 52    CUSTOM = ("custom_water_flow", 207)
 53    EXTREME = ("extreme", 208)
 54    SMART_MODE = ("smart_mode", 209)
 55    PURE_WATER_FLOW_START = ("slight", 221)
 56    PURE_WATER_FLOW_SMALL = ("low", 225)
 57    PURE_WATER_FLOW_MIDDLE = ("medium", 235)
 58    PURE_WATER_FLOW_LARGE = ("moderate", 245)
 59    PURE_WATER_SUPER_BEGIN = ("high", 248)
 60    PURE_WATER_FLOW_END = ("extreme", 250)
 61
 62
 63class WashTowelModes(RoborockModeEnum):
 64    SMART = ("smart", 10)
 65    LIGHT = ("light", 0)
 66    BALANCED = ("balanced", 1)
 67    DEEP = ("deep", 2)
 68    SUPER_DEEP = ("super_deep", 8)
 69
 70
 71WATER_SLIDE_MODE_MAPPING: dict[int, WaterModes] = {
 72    200: WaterModes.OFF,
 73    221: WaterModes.PURE_WATER_FLOW_START,
 74    225: WaterModes.PURE_WATER_FLOW_SMALL,
 75    235: WaterModes.PURE_WATER_FLOW_MIDDLE,
 76    245: WaterModes.PURE_WATER_FLOW_LARGE,
 77    248: WaterModes.PURE_WATER_SUPER_BEGIN,
 78    250: WaterModes.PURE_WATER_FLOW_END,
 79}
 80
 81
 82def get_wash_towel_modes(features: DeviceFeatures) -> list[WashTowelModes]:
 83    """Get the valid wash towel modes for the device"""
 84    modes = [WashTowelModes.LIGHT, WashTowelModes.BALANCED, WashTowelModes.DEEP]
 85    if features.is_super_deep_wash_supported and not features.is_dirty_replenish_clean_supported:
 86        modes.append(WashTowelModes.SUPER_DEEP)
 87    elif features.is_dirty_replenish_clean_supported:
 88        modes.append(WashTowelModes.SMART)
 89    return modes
 90
 91
 92def get_clean_modes(features: DeviceFeatures) -> list[VacuumModes]:
 93    """Get the valid clean modes for the device - also known as 'fan power' or 'suction mode'"""
 94    modes = [VacuumModes.QUIET, VacuumModes.BALANCED, VacuumModes.TURBO, VacuumModes.MAX]
 95    if features.is_max_plus_mode_supported or features.is_none_pure_clean_mop_with_max_plus:
 96        # If the vacuum has max plus mode supported
 97        modes.append(VacuumModes.MAX_PLUS)
 98    if features.is_pure_clean_mop_supported:
 99        # If the vacuum is capable of 'pure mop clean' aka no vacuum
100        if features.is_support_main_brush_up_down_supported:
101            modes.append(VacuumModes.OFF_RAISE_MAIN_BRUSH)
102        else:
103            modes.append(VacuumModes.OFF)
104    else:
105        # If not, we can add gentle
106        modes.append(VacuumModes.GENTLE)
107    if features.is_smart_clean_mode_set_supported:
108        modes.append(VacuumModes.SMART_MODE)
109    if features.is_customized_clean_supported:
110        modes.append(VacuumModes.CUSTOMIZED)
111    return modes
112
113
114def get_clean_routes(features: DeviceFeatures, region: str) -> list[CleanRoutes]:
115    """The routes that the vacuum will take while mopping"""
116    if features.is_none_pure_clean_mop_with_max_plus:
117        return [CleanRoutes.FAST, CleanRoutes.STANDARD]
118    supported = [CleanRoutes.STANDARD, CleanRoutes.DEEP]
119    if features.is_careful_slow_mop_supported:
120        if not (
121            features.is_corner_clean_mode_supported
122            and features.is_clean_route_deep_slow_plus_supported
123            and region == "cn"
124        ):
125            # for some reason there is a china specific deep plus mode
126            supported.append(CleanRoutes.DEEP_PLUS_CN)
127        else:
128            supported.append(CleanRoutes.DEEP_PLUS)
129
130    if features.is_clean_route_fast_mode_supported:
131        supported.append(CleanRoutes.FAST)
132    if features.is_smart_clean_mode_set_supported:
133        supported.append(CleanRoutes.SMART_MODE)
134    if features.is_customized_clean_supported:
135        supported.append(CleanRoutes.CUSTOMIZED)
136
137    return supported
138
139
140def get_water_modes(features: DeviceFeatures) -> list[WaterModes]:
141    """Get the valid water modes for the device - also known as 'water flow' or 'water level'"""
142    # Water slide mode supports a separate set of water flow codes.
143    if features.is_water_slide_mode_supported:
144        return list(WATER_SLIDE_MODE_MAPPING.values())
145
146    supported_modes = [WaterModes.OFF]
147    if features.is_mop_shake_module_supported:
148        # For mops that have the vibrating mop pad, they do mild standard intense
149        supported_modes.extend([WaterModes.MILD, WaterModes.STANDARD, WaterModes.INTENSE])
150    else:
151        supported_modes.extend([WaterModes.LOW, WaterModes.MEDIUM, WaterModes.HIGH])
152    if features.is_custom_water_box_distance_supported:
153        # This is for devices that allow you to set a custom water flow from 0-100
154        supported_modes.append(WaterModes.CUSTOM)
155    if features.is_mop_shake_module_supported and features.is_mop_shake_water_max_supported:
156        supported_modes.append(WaterModes.EXTREME)
157    if features.is_smart_clean_mode_set_supported:
158        supported_modes.append(WaterModes.SMART_MODE)
159    if features.is_customized_clean_supported:
160        supported_modes.append(WaterModes.CUSTOMIZED)
161
162    return supported_modes
163
164
165def get_water_mode_mapping(features: DeviceFeatures) -> dict[int, str]:
166    """Get water mode mapping by supported feature set.
167
168    WaterModes contains aliases for multiple codes that share the same value
169    string (e.g. low can be 201 or 225). For water slide mode devices we need
170    explicit code mapping to preserve those slide-specific codes.
171    """
172    if features.is_water_slide_mode_supported:
173        return {code: mode.value for code, mode in WATER_SLIDE_MODE_MAPPING.items()}
174    return {mode.code: mode.value for mode in get_water_modes(features)}
175
176
177def is_mode_customized(clean_mode: VacuumModes, water_mode: WaterModes, mop_mode: CleanRoutes) -> bool:
178    """Check if any of the cleaning modes are set to a custom value."""
179    return (
180        clean_mode == VacuumModes.CUSTOMIZED
181        or water_mode == WaterModes.CUSTOMIZED
182        or mop_mode == CleanRoutes.CUSTOMIZED
183    )
184
185
186def is_smart_mode_set(water_mode: WaterModes, clean_mode: VacuumModes, mop_mode: CleanRoutes) -> bool:
187    """Check if the smart mode is set for the given water mode and clean mode"""
188    return (
189        water_mode == WaterModes.SMART_MODE
190        or clean_mode == VacuumModes.SMART_MODE
191        or mop_mode == CleanRoutes.SMART_MODE
192    )
class VacuumModes(roborock.data.code_mappings.RoborockModeEnum):
12class VacuumModes(RoborockModeEnum):
13    GENTLE = ("gentle", 105)
14    OFF = ("off", 105)
15    QUIET = ("quiet", 101)
16    BALANCED = ("balanced", 102)
17    TURBO = ("turbo", 103)
18    MAX = ("max", 104)
19    MAX_PLUS = ("max_plus", 108)
20    OFF_RAISE_MAIN_BRUSH = ("off_raise_main_brush", 109)
21    CUSTOMIZED = ("custom", 106)
22    SMART_MODE = ("smart_mode", 110)

A custom StrEnum that also stores an integer code for each member.

GENTLE = <VacuumModes.GENTLE: 'gentle'>
OFF = <VacuumModes.OFF: 'off'>
QUIET = <VacuumModes.QUIET: 'quiet'>
BALANCED = <VacuumModes.BALANCED: 'balanced'>
TURBO = <VacuumModes.TURBO: 'turbo'>
MAX = <VacuumModes.MAX: 'max'>
MAX_PLUS = <VacuumModes.MAX_PLUS: 'max_plus'>
OFF_RAISE_MAIN_BRUSH = <VacuumModes.OFF_RAISE_MAIN_BRUSH: 'off_raise_main_brush'>
CUSTOMIZED = <VacuumModes.CUSTOMIZED: 'custom'>
SMART_MODE = <VacuumModes.SMART_MODE: 'smart_mode'>
class CleanRoutes(roborock.data.code_mappings.RoborockModeEnum):
25class CleanRoutes(RoborockModeEnum):
26    STANDARD = ("standard", 300)
27    DEEP = ("deep", 301)
28    DEEP_PLUS = ("deep_plus", 303)
29    FAST = ("fast", 304)
30    DEEP_PLUS_CN = ("deep_plus", 305)
31    SMART_MODE = ("smart_mode", 306)
32    CUSTOMIZED = ("custom", 302)

A custom StrEnum that also stores an integer code for each member.

STANDARD = <CleanRoutes.STANDARD: 'standard'>
DEEP = <CleanRoutes.DEEP: 'deep'>
DEEP_PLUS = <CleanRoutes.DEEP_PLUS: 'deep_plus'>
FAST = <CleanRoutes.FAST: 'fast'>
DEEP_PLUS_CN = <CleanRoutes.DEEP_PLUS: 'deep_plus'>
SMART_MODE = <CleanRoutes.SMART_MODE: 'smart_mode'>
CUSTOMIZED = <CleanRoutes.CUSTOMIZED: 'custom'>
class VacuumModesOld(roborock.data.code_mappings.RoborockModeEnum):
35class VacuumModesOld(RoborockModeEnum):
36    QUIET = ("quiet", 38)
37    BALANCED = ("balanced", 60)
38    TURBO = ("turbo", 75)
39    MAX = ("max", 100)

A custom StrEnum that also stores an integer code for each member.

QUIET = <VacuumModesOld.QUIET: 'quiet'>
BALANCED = <VacuumModesOld.BALANCED: 'balanced'>
TURBO = <VacuumModesOld.TURBO: 'turbo'>
MAX = <VacuumModesOld.MAX: 'max'>
class WaterModes(roborock.data.code_mappings.RoborockModeEnum):
42class WaterModes(RoborockModeEnum):
43    OFF = ("off", 200)
44    LOW = ("low", 201)
45    MILD = ("mild", 201)
46    MEDIUM = ("medium", 202)
47    STANDARD = ("standard", 202)
48    HIGH = ("high", 203)
49    INTENSE = ("intense", 203)
50    MIN = ("min", 205)
51    MAX = ("max", 206)
52    CUSTOMIZED = ("custom", 204)
53    CUSTOM = ("custom_water_flow", 207)
54    EXTREME = ("extreme", 208)
55    SMART_MODE = ("smart_mode", 209)
56    PURE_WATER_FLOW_START = ("slight", 221)
57    PURE_WATER_FLOW_SMALL = ("low", 225)
58    PURE_WATER_FLOW_MIDDLE = ("medium", 235)
59    PURE_WATER_FLOW_LARGE = ("moderate", 245)
60    PURE_WATER_SUPER_BEGIN = ("high", 248)
61    PURE_WATER_FLOW_END = ("extreme", 250)

A custom StrEnum that also stores an integer code for each member.

OFF = <WaterModes.OFF: 'off'>
LOW = <WaterModes.LOW: 'low'>
MILD = <WaterModes.MILD: 'mild'>
MEDIUM = <WaterModes.MEDIUM: 'medium'>
STANDARD = <WaterModes.STANDARD: 'standard'>
HIGH = <WaterModes.HIGH: 'high'>
INTENSE = <WaterModes.INTENSE: 'intense'>
MIN = <WaterModes.MIN: 'min'>
MAX = <WaterModes.MAX: 'max'>
CUSTOMIZED = <WaterModes.CUSTOMIZED: 'custom'>
CUSTOM = <WaterModes.CUSTOM: 'custom_water_flow'>
EXTREME = <WaterModes.EXTREME: 'extreme'>
SMART_MODE = <WaterModes.SMART_MODE: 'smart_mode'>
PURE_WATER_FLOW_START = <WaterModes.PURE_WATER_FLOW_START: 'slight'>
PURE_WATER_FLOW_SMALL = <WaterModes.LOW: 'low'>
PURE_WATER_FLOW_MIDDLE = <WaterModes.MEDIUM: 'medium'>
PURE_WATER_FLOW_LARGE = <WaterModes.PURE_WATER_FLOW_LARGE: 'moderate'>
PURE_WATER_SUPER_BEGIN = <WaterModes.HIGH: 'high'>
PURE_WATER_FLOW_END = <WaterModes.EXTREME: 'extreme'>
class WashTowelModes(roborock.data.code_mappings.RoborockModeEnum):
64class WashTowelModes(RoborockModeEnum):
65    SMART = ("smart", 10)
66    LIGHT = ("light", 0)
67    BALANCED = ("balanced", 1)
68    DEEP = ("deep", 2)
69    SUPER_DEEP = ("super_deep", 8)

A custom StrEnum that also stores an integer code for each member.

SMART = <WashTowelModes.SMART: 'smart'>
LIGHT = <WashTowelModes.LIGHT: 'light'>
BALANCED = <WashTowelModes.BALANCED: 'balanced'>
DEEP = <WashTowelModes.DEEP: 'deep'>
SUPER_DEEP = <WashTowelModes.SUPER_DEEP: 'super_deep'>
WATER_SLIDE_MODE_MAPPING: dict[int, WaterModes] = {200: <WaterModes.OFF: 'off'>, 221: <WaterModes.PURE_WATER_FLOW_START: 'slight'>, 225: <WaterModes.LOW: 'low'>, 235: <WaterModes.MEDIUM: 'medium'>, 245: <WaterModes.PURE_WATER_FLOW_LARGE: 'moderate'>, 248: <WaterModes.HIGH: 'high'>, 250: <WaterModes.EXTREME: 'extreme'>}
def get_wash_towel_modes( features: roborock.device_features.DeviceFeatures) -> list[WashTowelModes]:
83def get_wash_towel_modes(features: DeviceFeatures) -> list[WashTowelModes]:
84    """Get the valid wash towel modes for the device"""
85    modes = [WashTowelModes.LIGHT, WashTowelModes.BALANCED, WashTowelModes.DEEP]
86    if features.is_super_deep_wash_supported and not features.is_dirty_replenish_clean_supported:
87        modes.append(WashTowelModes.SUPER_DEEP)
88    elif features.is_dirty_replenish_clean_supported:
89        modes.append(WashTowelModes.SMART)
90    return modes

Get the valid wash towel modes for the device

def get_clean_modes( features: roborock.device_features.DeviceFeatures) -> list[VacuumModes]:
 93def get_clean_modes(features: DeviceFeatures) -> list[VacuumModes]:
 94    """Get the valid clean modes for the device - also known as 'fan power' or 'suction mode'"""
 95    modes = [VacuumModes.QUIET, VacuumModes.BALANCED, VacuumModes.TURBO, VacuumModes.MAX]
 96    if features.is_max_plus_mode_supported or features.is_none_pure_clean_mop_with_max_plus:
 97        # If the vacuum has max plus mode supported
 98        modes.append(VacuumModes.MAX_PLUS)
 99    if features.is_pure_clean_mop_supported:
100        # If the vacuum is capable of 'pure mop clean' aka no vacuum
101        if features.is_support_main_brush_up_down_supported:
102            modes.append(VacuumModes.OFF_RAISE_MAIN_BRUSH)
103        else:
104            modes.append(VacuumModes.OFF)
105    else:
106        # If not, we can add gentle
107        modes.append(VacuumModes.GENTLE)
108    if features.is_smart_clean_mode_set_supported:
109        modes.append(VacuumModes.SMART_MODE)
110    if features.is_customized_clean_supported:
111        modes.append(VacuumModes.CUSTOMIZED)
112    return modes

Get the valid clean modes for the device - also known as 'fan power' or 'suction mode'

def get_clean_routes( features: roborock.device_features.DeviceFeatures, region: str) -> list[CleanRoutes]:
115def get_clean_routes(features: DeviceFeatures, region: str) -> list[CleanRoutes]:
116    """The routes that the vacuum will take while mopping"""
117    if features.is_none_pure_clean_mop_with_max_plus:
118        return [CleanRoutes.FAST, CleanRoutes.STANDARD]
119    supported = [CleanRoutes.STANDARD, CleanRoutes.DEEP]
120    if features.is_careful_slow_mop_supported:
121        if not (
122            features.is_corner_clean_mode_supported
123            and features.is_clean_route_deep_slow_plus_supported
124            and region == "cn"
125        ):
126            # for some reason there is a china specific deep plus mode
127            supported.append(CleanRoutes.DEEP_PLUS_CN)
128        else:
129            supported.append(CleanRoutes.DEEP_PLUS)
130
131    if features.is_clean_route_fast_mode_supported:
132        supported.append(CleanRoutes.FAST)
133    if features.is_smart_clean_mode_set_supported:
134        supported.append(CleanRoutes.SMART_MODE)
135    if features.is_customized_clean_supported:
136        supported.append(CleanRoutes.CUSTOMIZED)
137
138    return supported

The routes that the vacuum will take while mopping

def get_water_modes( features: roborock.device_features.DeviceFeatures) -> list[WaterModes]:
141def get_water_modes(features: DeviceFeatures) -> list[WaterModes]:
142    """Get the valid water modes for the device - also known as 'water flow' or 'water level'"""
143    # Water slide mode supports a separate set of water flow codes.
144    if features.is_water_slide_mode_supported:
145        return list(WATER_SLIDE_MODE_MAPPING.values())
146
147    supported_modes = [WaterModes.OFF]
148    if features.is_mop_shake_module_supported:
149        # For mops that have the vibrating mop pad, they do mild standard intense
150        supported_modes.extend([WaterModes.MILD, WaterModes.STANDARD, WaterModes.INTENSE])
151    else:
152        supported_modes.extend([WaterModes.LOW, WaterModes.MEDIUM, WaterModes.HIGH])
153    if features.is_custom_water_box_distance_supported:
154        # This is for devices that allow you to set a custom water flow from 0-100
155        supported_modes.append(WaterModes.CUSTOM)
156    if features.is_mop_shake_module_supported and features.is_mop_shake_water_max_supported:
157        supported_modes.append(WaterModes.EXTREME)
158    if features.is_smart_clean_mode_set_supported:
159        supported_modes.append(WaterModes.SMART_MODE)
160    if features.is_customized_clean_supported:
161        supported_modes.append(WaterModes.CUSTOMIZED)
162
163    return supported_modes

Get the valid water modes for the device - also known as 'water flow' or 'water level'

def get_water_mode_mapping(features: roborock.device_features.DeviceFeatures) -> dict[int, str]:
166def get_water_mode_mapping(features: DeviceFeatures) -> dict[int, str]:
167    """Get water mode mapping by supported feature set.
168
169    WaterModes contains aliases for multiple codes that share the same value
170    string (e.g. low can be 201 or 225). For water slide mode devices we need
171    explicit code mapping to preserve those slide-specific codes.
172    """
173    if features.is_water_slide_mode_supported:
174        return {code: mode.value for code, mode in WATER_SLIDE_MODE_MAPPING.items()}
175    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.

def is_mode_customized( clean_mode: VacuumModes, water_mode: WaterModes, mop_mode: CleanRoutes) -> bool:
178def is_mode_customized(clean_mode: VacuumModes, water_mode: WaterModes, mop_mode: CleanRoutes) -> bool:
179    """Check if any of the cleaning modes are set to a custom value."""
180    return (
181        clean_mode == VacuumModes.CUSTOMIZED
182        or water_mode == WaterModes.CUSTOMIZED
183        or mop_mode == CleanRoutes.CUSTOMIZED
184    )

Check if any of the cleaning modes are set to a custom value.

def is_smart_mode_set( water_mode: WaterModes, clean_mode: VacuumModes, mop_mode: CleanRoutes) -> bool:
187def is_smart_mode_set(water_mode: WaterModes, clean_mode: VacuumModes, mop_mode: CleanRoutes) -> bool:
188    """Check if the smart mode is set for the given water mode and clean mode"""
189    return (
190        water_mode == WaterModes.SMART_MODE
191        or clean_mode == VacuumModes.SMART_MODE
192        or mop_mode == CleanRoutes.SMART_MODE
193    )

Check if the smart mode is set for the given water mode and clean mode