-
Notifications
You must be signed in to change notification settings - Fork 75
feat: add stronger mop washing support #765
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
70c1c48
b4fcdca
38076f7
e791aff
f46729d
b9f8ca5
f9c8e6d
f747c4a
b48d9ce
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,8 +1,11 @@ | ||
| """Trait for wash towel mode.""" | ||
|
|
||
| from roborock.data import WashTowelMode | ||
| from functools import cached_property | ||
|
|
||
| from roborock.data import WashTowelMode, WashTowelModes, get_wash_towel_modes | ||
| from roborock.device_features import is_wash_n_fill_dock | ||
| from roborock.devices.traits.v1 import common | ||
| from roborock.devices.traits.v1.device_features import DeviceFeaturesTrait | ||
| from roborock.roborock_typing import RoborockCommand | ||
|
|
||
|
|
||
|
|
@@ -11,3 +14,30 @@ class WashTowelModeTrait(WashTowelMode, common.V1TraitMixin): | |
|
|
||
| command = RoborockCommand.GET_WASH_TOWEL_MODE | ||
| requires_dock_type = is_wash_n_fill_dock | ||
|
|
||
| def __init__( | ||
| self, | ||
| device_feature_trait: DeviceFeaturesTrait | None = None, | ||
|
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. My understanding is this will always be set so it won't ever be None. Is that righT? (Can simplify a check below)
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 thought you were right but I think the actual flow is:
|
||
| wash_mode: WashTowelModes | None = None, | ||
|
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. i think this is not used
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. removed this and reworked some stuff so it's more similar to the status trait. by having it's own parse response we can avoid the |None check on device_feature_trait as well |
||
| ) -> None: | ||
|
Lash-L marked this conversation as resolved.
|
||
| super().__init__() | ||
| self.device_feature_trait = device_feature_trait | ||
| self.wash_mode = wash_mode | ||
|
|
||
| @cached_property | ||
| def wash_towel_mode_options(self) -> list[WashTowelModes]: | ||
| if self.device_feature_trait is None: | ||
| return [] | ||
| return get_wash_towel_modes(self.device_feature_trait) | ||
|
|
||
| async def set_wash_towel_mode(self, mode: WashTowelModes) -> None: | ||
| """Set the wash towel mode.""" | ||
| await self.rpc_channel.send_command(RoborockCommand.SET_WASH_TOWEL_MODE, params={"wash_mode": mode.code}) | ||
|
|
||
| async def start_wash(self) -> None: | ||
| """Start washing the mop.""" | ||
| await self.rpc_channel.send_command(RoborockCommand.APP_START_WASH) | ||
|
|
||
| async def stop_wash(self) -> None: | ||
| """Stop washing the mop.""" | ||
| await self.rpc_channel.send_command(RoborockCommand.APP_STOP_WASH) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,12 +4,15 @@ | |
|
|
||
| import pytest | ||
|
|
||
| from roborock.data import RoborockDockTypeCode, RoborockDockWashTowelModeCode | ||
| from roborock.data import ( | ||
| RoborockDockTypeCode, | ||
| WashTowelModes, | ||
| ) | ||
| from roborock.devices.device import RoborockDevice | ||
| from roborock.devices.traits.v1.wash_towel_mode import WashTowelModeTrait | ||
| from roborock.roborock_typing import RoborockCommand | ||
|
|
||
| WASH_TOWEL_MODE_DATA = [{"wash_mode": RoborockDockWashTowelModeCode.smart}] | ||
| WASH_TOWEL_MODE_DATA = {"wash_mode": WashTowelModes.SMART.code} | ||
|
|
||
|
|
||
| @pytest.fixture(name="wash_towel_mode") | ||
|
|
@@ -50,7 +53,7 @@ async def test_wash_towel_mode_available( | |
| ] | ||
| ) | ||
|
|
||
| assert wash_towel_mode.wash_mode == RoborockDockWashTowelModeCode.smart | ||
| assert wash_towel_mode.wash_mode == WashTowelModes.SMART | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
|
|
@@ -65,3 +68,133 @@ async def test_unsupported_wash_towel_mode( | |
| ) -> None: | ||
| """Test that the trait is not available for unsupported dock types.""" | ||
| assert wash_towel_mode is None | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| ("dock_type_code"), | ||
| [(RoborockDockTypeCode.s8_dock)], | ||
| ) | ||
| @pytest.mark.parametrize( | ||
| ("wash_mode"), | ||
| [ | ||
| (WashTowelModes.SMART), | ||
| (WashTowelModes.LIGHT), | ||
| ], | ||
| ) | ||
| async def test_set_wash_towel_mode( | ||
| wash_towel_mode: WashTowelModeTrait | None, | ||
|
Lash-L marked this conversation as resolved.
Outdated
|
||
| mock_rpc_channel: AsyncMock, | ||
| wash_mode: WashTowelModes, | ||
| dock_type_code: RoborockDockTypeCode, | ||
| ) -> None: | ||
| """Test setting the wash towel mode.""" | ||
| assert wash_towel_mode is not None | ||
|
|
||
| await wash_towel_mode.set_wash_towel_mode(wash_mode) | ||
|
|
||
| mock_rpc_channel.send_command.assert_called_with( | ||
| RoborockCommand.SET_WASH_TOWEL_MODE, params={"wash_mode": wash_mode.code} | ||
| ) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| ("dock_type_code"), | ||
| [(RoborockDockTypeCode.s8_dock)], | ||
| ) | ||
| async def test_start_wash( | ||
| wash_towel_mode: WashTowelModeTrait | None, | ||
| mock_rpc_channel: AsyncMock, | ||
| dock_type_code: RoborockDockTypeCode, | ||
| ) -> None: | ||
| """Test starting the wash.""" | ||
| assert wash_towel_mode is not None | ||
|
|
||
| await wash_towel_mode.start_wash() | ||
|
|
||
| mock_rpc_channel.send_command.assert_called_with(RoborockCommand.APP_START_WASH) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| ("dock_type_code"), | ||
| [(RoborockDockTypeCode.s8_dock)], | ||
| ) | ||
| async def test_stop_wash( | ||
| wash_towel_mode: WashTowelModeTrait | None, | ||
| mock_rpc_channel: AsyncMock, | ||
| dock_type_code: RoborockDockTypeCode, | ||
| ) -> None: | ||
| """Test stopping the wash.""" | ||
| assert wash_towel_mode is not None | ||
|
|
||
| await wash_towel_mode.stop_wash() | ||
|
|
||
| mock_rpc_channel.send_command.assert_called_with(RoborockCommand.APP_STOP_WASH) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| ("dock_type_code"), | ||
| [(RoborockDockTypeCode.s8_dock)], | ||
| ) | ||
| @pytest.mark.parametrize( | ||
| ( | ||
| "is_super_deep_wash_supported", | ||
| "is_dirty_replenish_clean_supported", | ||
| "expected_modes", | ||
| ), | ||
| [ | ||
| ( | ||
| False, | ||
| False, | ||
| [WashTowelModes.LIGHT, WashTowelModes.BALANCED, WashTowelModes.DEEP], | ||
| ), | ||
| ( | ||
| True, | ||
| False, | ||
| [ | ||
| WashTowelModes.LIGHT, | ||
| WashTowelModes.BALANCED, | ||
| WashTowelModes.DEEP, | ||
| WashTowelModes.SUPER_DEEP, | ||
| ], | ||
| ), | ||
| ( | ||
| False, | ||
| True, | ||
| [ | ||
| WashTowelModes.LIGHT, | ||
| WashTowelModes.BALANCED, | ||
| WashTowelModes.DEEP, | ||
| WashTowelModes.SMART, | ||
| ], | ||
| ), | ||
| ( | ||
| True, | ||
| True, | ||
| [ | ||
| WashTowelModes.LIGHT, | ||
| WashTowelModes.BALANCED, | ||
| WashTowelModes.DEEP, | ||
| WashTowelModes.SMART, | ||
| ], | ||
| ), | ||
| ], | ||
| ) | ||
| async def test_wash_towel_mode_options( | ||
| wash_towel_mode: WashTowelModeTrait | None, | ||
| dock_type_code: RoborockDockTypeCode, | ||
| is_super_deep_wash_supported: bool, | ||
| is_dirty_replenish_clean_supported: bool, | ||
| expected_modes: list[WashTowelModes], | ||
| ) -> None: | ||
| """Test what modes are available based on device features.""" | ||
| assert wash_towel_mode is not None | ||
| # We need to clear the cached property to ensure it re-reads the features | ||
|
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. Is this really required? My impression is we're testing with a new instance of |
||
| if "wash_towel_mode_options" in wash_towel_mode.__dict__: | ||
| del wash_towel_mode.__dict__["wash_towel_mode_options"] | ||
|
|
||
| # Mock the device features | ||
| assert wash_towel_mode.device_feature_trait is not None | ||
| wash_towel_mode.device_feature_trait.is_super_deep_wash_supported = is_super_deep_wash_supported | ||
| wash_towel_mode.device_feature_trait.is_dirty_replenish_clean_supported = is_dirty_replenish_clean_supported | ||
|
|
||
| assert wash_towel_mode.wash_towel_mode_options == expected_modes | ||
Uh oh!
There was an error while loading. Please reload this page.