-
Notifications
You must be signed in to change notification settings - Fork 94
feat: add better cleaning mode support #817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
35e7354
c29c38f
8bb33cc
68797de
ed4e3c8
440c316
641a34e
9d69646
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,9 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import typing | ||
| from enum import StrEnum | ||
|
|
||
| from ...exceptions import RoborockUnsupportedFeature | ||
| from ..code_mappings import RoborockModeEnum | ||
|
|
||
| if typing.TYPE_CHECKING: | ||
|
|
@@ -68,6 +70,14 @@ class WashTowelModes(RoborockModeEnum): | |
| SUPER_DEEP = ("super_deep", 8) | ||
|
|
||
|
|
||
| class CleaningModes(StrEnum): | ||
|
Lash-L marked this conversation as resolved.
Outdated
|
||
| VACUUM = "vacuum" | ||
| VAC_AND_MOP = "vac_and_mop" | ||
| MOP = "mop" | ||
| CUSTOM = "custom" | ||
| SMART_MODE = "smart_mode" | ||
|
|
||
|
|
||
| WATER_SLIDE_MODE_MAPPING: dict[int, WaterModes] = { | ||
| 200: WaterModes.OFF, | ||
| 221: WaterModes.PURE_WATER_FLOW_START, | ||
|
|
@@ -174,7 +184,91 @@ def get_water_mode_mapping(features: DeviceFeatures) -> dict[int, str]: | |
| return {mode.code: mode.value for mode in get_water_modes(features)} | ||
|
|
||
|
|
||
| def is_mode_customized(clean_mode: VacuumModes, water_mode: WaterModes, mop_mode: CleanRoutes) -> bool: | ||
| def get_cleaning_mode_options(features: DeviceFeatures) -> list[CleaningModes]: | ||
| """Get the supported high-level cleaning modes for the device.""" | ||
| if not features.is_support_water_mode: | ||
| return [] | ||
|
|
||
| options = [CleaningModes.VACUUM, CleaningModes.VAC_AND_MOP] | ||
| if features.is_pure_clean_mop_supported: | ||
| options.append(CleaningModes.MOP) | ||
| if features.is_customized_clean_supported: | ||
| options.append(CleaningModes.CUSTOM) | ||
| if features.is_smart_clean_mode_set_supported: | ||
| options.append(CleaningModes.SMART_MODE) | ||
| return options | ||
|
|
||
|
|
||
| def get_mop_only_vacuum_mode(features: DeviceFeatures) -> VacuumModes: | ||
|
allenporter marked this conversation as resolved.
|
||
| if not features.is_pure_clean_mop_supported: | ||
| raise RoborockUnsupportedFeature("Mop-only cleaning is not supported") | ||
| if features.is_support_main_brush_up_down_supported: | ||
| return VacuumModes.OFF_RAISE_MAIN_BRUSH | ||
| return VacuumModes.OFF | ||
|
|
||
|
|
||
| _CLEAN_MOTOR_MODE_PARAMS: dict[CleaningModes, tuple[int, int, int]] = { | ||
| CleaningModes.VACUUM: (VacuumModes.BALANCED.code, WaterModes.OFF.code, CleanRoutes.STANDARD.code), | ||
| CleaningModes.VAC_AND_MOP: (VacuumModes.BALANCED.code, WaterModes.STANDARD.code, CleanRoutes.STANDARD.code), | ||
| CleaningModes.CUSTOM: (VacuumModes.CUSTOMIZED.code, WaterModes.CUSTOMIZED.code, CleanRoutes.CUSTOMIZED.code), | ||
| CleaningModes.SMART_MODE: (VacuumModes.SMART_MODE.code, WaterModes.SMART_MODE.code, CleanRoutes.SMART_MODE.code), | ||
| } | ||
|
Lash-L marked this conversation as resolved.
Outdated
|
||
|
|
||
|
|
||
| def get_cleaning_mode_parameters(cleaning_mode: str | CleaningModes, features: DeviceFeatures) -> list[dict[str, int]]: | ||
| """Get the RPC payload for switching the high-level cleaning mode.""" | ||
| try: | ||
| mode = CleaningModes(cleaning_mode) | ||
|
Lash-L marked this conversation as resolved.
Outdated
|
||
| except ValueError as err: | ||
| raise RoborockUnsupportedFeature(f"Cleaning mode {cleaning_mode!r} is not supported") from err | ||
| if mode not in get_cleaning_mode_options(features): | ||
| raise RoborockUnsupportedFeature(f"Cleaning mode {mode.value!r} is not supported") | ||
|
|
||
| if mode == CleaningModes.MOP: | ||
| fan_power = get_mop_only_vacuum_mode(features).code | ||
| water_box_mode = WaterModes.STANDARD.code | ||
| mop_mode = CleanRoutes.STANDARD.code | ||
| else: | ||
| fan_power, water_box_mode, mop_mode = _CLEAN_MOTOR_MODE_PARAMS[mode] | ||
|
|
||
| params: dict[str, int] = {"fan_power": fan_power, "water_box_mode": water_box_mode} | ||
| if features.is_clean_route_setting_supported: | ||
| params["mop_mode"] = mop_mode | ||
| return [params] | ||
|
|
||
|
|
||
| def get_current_cleaning_mode( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thought is that this could be on I think the only advantage could be the names would be shorter, but otherwise its not to different than what is here and can just be a style choice (optional)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have too strong of an opinion on this (so i can easily be convinced), but I think I'll keep it like this for now as it matches the rest of the file. Perhaps it makes sense to make all of these use clash methods instead though. |
||
| clean_mode: int | None, | ||
|
Lash-L marked this conversation as resolved.
Outdated
|
||
| water_mode: int | None, | ||
| mop_mode: int | None, | ||
| features: DeviceFeatures, | ||
| ) -> CleaningModes | None: | ||
| """Classify the current high-level cleaning mode from individual mode codes.""" | ||
| if not features.is_support_water_mode: | ||
| return None | ||
| if clean_mode is None or water_mode is None: | ||
| return None | ||
|
|
||
| if is_smart_mode_set(water_mode, clean_mode, mop_mode): | ||
| return CleaningModes.SMART_MODE | ||
| if is_mode_customized(clean_mode, water_mode, mop_mode): | ||
| return CleaningModes.CUSTOM | ||
| if water_mode != WaterModes.OFF.code: | ||
| try: | ||
| if clean_mode == get_mop_only_vacuum_mode(features).code: | ||
| return CleaningModes.MOP | ||
| except RoborockUnsupportedFeature: | ||
| pass | ||
| if water_mode == WaterModes.OFF.code: | ||
| return CleaningModes.VACUUM | ||
| return CleaningModes.VAC_AND_MOP | ||
|
|
||
|
|
||
| def is_mode_customized( | ||
| clean_mode: int | VacuumModes | None, | ||
| water_mode: int | WaterModes | None, | ||
| mop_mode: int | CleanRoutes | None, | ||
| ) -> bool: | ||
| """Check if any of the cleaning modes are set to a custom value.""" | ||
| return ( | ||
| clean_mode == VacuumModes.CUSTOMIZED | ||
|
|
@@ -183,7 +277,11 @@ def is_mode_customized(clean_mode: VacuumModes, water_mode: WaterModes, mop_mode | |
| ) | ||
|
Lash-L marked this conversation as resolved.
|
||
|
|
||
|
|
||
| def is_smart_mode_set(water_mode: WaterModes, clean_mode: VacuumModes, mop_mode: CleanRoutes) -> bool: | ||
| def is_smart_mode_set( | ||
| water_mode: int | WaterModes | None, | ||
| clean_mode: int | VacuumModes | None, | ||
| mop_mode: int | CleanRoutes | None, | ||
| ) -> bool: | ||
| """Check if the smart mode is set for the given water mode and clean mode""" | ||
| return ( | ||
| water_mode == WaterModes.SMART_MODE | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.