Skip to content

Commit 908b8b0

Browse files
committed
fix: Remove DockSummary and make dust collection mode optional based on dock type
1 parent 1809b5a commit 908b8b0

File tree

12 files changed

+261
-218
lines changed

12 files changed

+261
-218
lines changed

roborock/device_features.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,3 +642,13 @@ def get_supported_features(self) -> list[str]:
642642
RoborockDockTypeCode.saros_r10_dock,
643643
RoborockDockTypeCode.qrevo_curv_dock,
644644
]
645+
646+
647+
def is_wash_n_fill_dock(dock_type: RoborockDockTypeCode) -> bool:
648+
"""Check if the dock type is a wash and fill dock."""
649+
return dock_type in WASH_N_FILL_DOCK_TYPES
650+
651+
652+
def is_valid_dock(dock_type: RoborockDockTypeCode) -> bool:
653+
"""Check if device supports a dock."""
654+
return dock_type != RoborockDockTypeCode.no_dock

roborock/devices/traits/v1/__init__.py

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@
2626
- `requires_feature` - The string name of the device feature that must be supported
2727
for this trait to be enabled. See `DeviceFeaturesTrait` for a list of
2828
available features.
29-
- `requires_dock_type` - If set, this trait requires the
30-
device to have any of the specified dock types to be enabled. See
31-
`RoborockDockTypeCode` for a list of available dock types.
29+
- `requires_dock_type` - If set, this is a function that accepts a `RoborockDockTypeCode`
30+
and returns a boolean indicating whether the trait is supported for that dock type.
3231
"""
3332

3433
import logging
@@ -50,7 +49,6 @@
5049
from .consumeable import ConsumableTrait
5150
from .device_features import DeviceFeaturesTrait
5251
from .do_not_disturb import DoNotDisturbTrait
53-
from .dock_summary import DockSummaryTrait
5452
from .dust_collection_mode import DustCollectionModeTrait
5553
from .flow_led_status import FlowLedStatusTrait
5654
from .home import HomeTrait
@@ -84,7 +82,6 @@
8482
"FlowLedStatusTrait",
8583
"LedStatusTrait",
8684
"ValleyElectricityTimerTrait",
87-
"DockSummaryTrait",
8885
"DustCollectionModeTrait",
8986
"WashTowelModeTrait",
9087
"SmartWashParamsTrait",
@@ -111,16 +108,15 @@ class PropertiesApi(Trait):
111108
consumables: ConsumableTrait
112109
home: HomeTrait
113110
device_features: DeviceFeaturesTrait
114-
dust_collection_mode: DustCollectionModeTrait
115111

116112
# Optional features that may not be supported on all devices
117113
child_lock: ChildLockTrait | None = None
118114
led_status: LedStatusTrait | None = None
119115
flow_led_status: FlowLedStatusTrait | None = None
120116
valley_electricity_timer: ValleyElectricityTimerTrait | None = None
117+
dust_collection_mode: DustCollectionModeTrait | None = None
121118
wash_towel_mode: WashTowelModeTrait | None = None
122119
smart_wash_params: SmartWashParamsTrait | None = None
123-
dock_summary: DockSummaryTrait | None = None
124120

125121
def __init__(
126122
self,
@@ -191,35 +187,21 @@ async def discover_features(self) -> None:
191187

192188
# Union args may not be in declared order
193189
item_type = union_args[0] if union_args[1] is type(None) else union_args[1]
194-
if item_type is DockSummaryTrait:
195-
# DockSummaryTrait is created manually below
196-
continue
197-
trait = item_type()
198-
if not self._is_supported(trait, item.name, dock_type):
190+
if not self._is_supported(item_type, item.name, dock_type):
199191
_LOGGER.debug("Trait '%s' not supported, skipping", item.name)
200192
continue
201-
202193
_LOGGER.debug("Trait '%s' is supported, initializing", item.name)
194+
trait = item_type()
203195
setattr(self, item.name, trait)
204196
trait._rpc_channel = self._get_rpc_channel(trait)
205197

206-
if dock_type is None or dock_type == RoborockDockTypeCode.no_dock:
207-
_LOGGER.debug("Trait 'dock_summary' not supported, skipping")
208-
else:
209-
_LOGGER.debug("Trait 'dock_summary' is supported, initializing")
210-
self.dock_summary = DockSummaryTrait(
211-
self.dust_collection_mode,
212-
self.wash_towel_mode,
213-
self.smart_wash_params,
214-
)
215-
216-
def _is_supported(self, trait: V1TraitMixin, name: str, dock_type: RoborockDockTypeCode) -> bool:
198+
def _is_supported(self, trait_type: type[V1TraitMixin], name: str, dock_type: RoborockDockTypeCode) -> bool:
217199
"""Check if a trait is supported by the device."""
218200

219-
if (requires_dock_type := getattr(trait, "requires_dock_type", None)) is not None:
220-
return dock_type in requires_dock_type
201+
if (requires_dock_type := getattr(trait_type, "requires_dock_type", None)) is not None:
202+
return requires_dock_type(dock_type)
221203

222-
if (feature_name := getattr(trait, "requires_feature", None)) is None:
204+
if (feature_name := getattr(trait_type, "requires_feature", None)) is None:
223205
_LOGGER.debug("Optional trait missing 'requires_feature' attribute %s, skipping", name)
224206
return False
225207
if (is_supported := getattr(self.device_features, feature_name)) is None:

roborock/devices/traits/v1/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ async def refresh(self) -> Self:
8282
new_data = self._parse_response(response)
8383
if not isinstance(new_data, RoborockBase):
8484
raise ValueError(f"Internal error, unexpected response type: {new_data!r}")
85+
_LOGGER.debug("Refreshed %s: %s", self.__class__.__name__, new_data)
8586
self._update_trait_values(new_data)
8687
return self
8788

roborock/devices/traits/v1/dock_summary.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

roborock/devices/traits/v1/dust_collection_mode.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Trait for dust collection mode."""
22

33
from roborock.containers import DustCollectionMode
4+
from roborock.device_features import is_valid_dock
45
from roborock.devices.traits.v1 import common
56
from roborock.roborock_typing import RoborockCommand
67

@@ -9,3 +10,4 @@ class DustCollectionModeTrait(DustCollectionMode, common.V1TraitMixin):
910
"""Trait for dust collection mode."""
1011

1112
command = RoborockCommand.GET_DUST_COLLECTION_MODE
13+
requires_dock_type = is_valid_dock
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Trait for smart wash parameters."""
22

33
from roborock.containers import SmartWashParams
4-
from roborock.device_features import WASH_N_FILL_DOCK_TYPES
4+
from roborock.device_features import is_wash_n_fill_dock
55
from roborock.devices.traits.v1 import common
66
from roborock.roborock_typing import RoborockCommand
77

@@ -10,4 +10,4 @@ class SmartWashParamsTrait(SmartWashParams, common.V1TraitMixin):
1010
"""Trait for smart wash parameters."""
1111

1212
command = RoborockCommand.GET_SMART_WASH_PARAMS
13-
requires_dock_type = WASH_N_FILL_DOCK_TYPES
13+
requires_dock_type = is_wash_n_fill_dock
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Trait for wash towel mode."""
22

33
from roborock.containers import WashTowelMode
4-
from roborock.device_features import WASH_N_FILL_DOCK_TYPES
4+
from roborock.device_features import is_wash_n_fill_dock
55
from roborock.devices.traits.v1 import common
66
from roborock.roborock_typing import RoborockCommand
77

@@ -10,4 +10,4 @@ class WashTowelModeTrait(WashTowelMode, common.V1TraitMixin):
1010
"""Trait for wash towel mode."""
1111

1212
command = RoborockCommand.GET_WASH_TOWEL_MODE
13-
requires_dock_type = WASH_N_FILL_DOCK_TYPES
13+
requires_dock_type = is_wash_n_fill_dock

tests/devices/traits/v1/fixtures.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import pytest
66

7+
from roborock.code_mappings import RoborockDockTypeCode
78
from roborock.containers import HomeData, S7MaxVStatus, UserData
89
from roborock.devices.cache import Cache, InMemoryCache
910
from roborock.devices.device import RoborockDevice
@@ -68,3 +69,33 @@ def device_fixture(
6869
roborock_cache,
6970
),
7071
)
72+
73+
74+
@pytest.fixture(name="dock_type_code", autouse=True)
75+
def dock_type_code_fixture(request: pytest.FixtureRequest) -> RoborockDockTypeCode | None:
76+
"""Fixture to provide the dock type code for parameterized tests."""
77+
return RoborockDockTypeCode.s7_max_ultra_dock
78+
79+
80+
@pytest.fixture(autouse=True)
81+
async def discover_features_fixture(
82+
device: RoborockDevice,
83+
mock_rpc_channel: AsyncMock,
84+
dock_type_code: RoborockDockTypeCode | None,
85+
) -> None:
86+
"""Fixture to set up the clean summary for tests.
87+
88+
The CleanRecordTrait depends on the CleanSummaryTrait, so we need to
89+
prepare that first.
90+
"""
91+
assert device.v1_properties
92+
mock_rpc_channel.send_command.side_effect = [
93+
[mock_data.APP_GET_INIT_STATUS],
94+
{
95+
**mock_data.STATUS,
96+
"dock_type": dock_type_code,
97+
},
98+
]
99+
await device.v1_properties.discover_features()
100+
assert device.v1_properties.status.dock_type == dock_type_code
101+
mock_rpc_channel.send_command.reset_mock()

tests/devices/traits/v1/test_dock_summary.py

Lines changed: 0 additions & 144 deletions
This file was deleted.

0 commit comments

Comments
 (0)