Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions roborock/devices/traits/a01/device_feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@
}
)

# Devices known to lack DEFAULT_SETTING (DP 225).
_UNSUPPORTED_DEFAULT_SETTING: frozenset[str] = frozenset(
{
"roborock.wm.a63", # H1
}
)

# Series that support UV light (DP 228).
_UV_LIGHT_SERIES: frozenset[str] = (
_H1_LITE_SERIES # a90, a91, a237
Expand Down Expand Up @@ -242,6 +249,13 @@ def supports_feature_bits(model: str | None) -> bool:
return model not in _UNSUPPORTED_FEATURE_BITS


def supports_default_setting(model: str | None) -> bool:
"""H1 (a63) does not support DP 225 even though it has a softener compartment."""
if model is None:
return True # conservative: assume yes
return model not in _UNSUPPORTED_DEFAULT_SETTING


def supports_remote_control(model: str | None) -> bool:
"""Remote control (DP 232) is supported on all overseas models."""
if model is None:
Expand Down Expand Up @@ -309,6 +323,10 @@ def build_force_load_dp_list(model: str | None) -> list[RoborockZeoProtocol]:
if not supports_feature_bits(model):
base = [dp for dp in base if dp != RoborockZeoProtocol.FEATURE_BITS]

# ── Strip unsupported DEFAULT_SETTING ──
if not supports_default_setting(model):
base = [dp for dp in base if dp != RoborockZeoProtocol.DEFAULT_SETTING]

return base


Expand Down
41 changes: 41 additions & 0 deletions tests/devices/traits/a01/test_device_feature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Tests for A01 (Zeo) per-model feature gating."""

import pytest

from roborock.devices.traits.a01.device_feature import build_force_load_dp_list, supports_default_setting
from roborock.roborock_message import RoborockZeoProtocol


@pytest.mark.parametrize(
("model", "expected"),
[
("roborock.wm.a63", False), # H1
("roborock.wm.a102", True), # H1 Overseas
("roborock.wm.a90", True), # H1 Lite
(None, True), # unknown model: assume supported
],
)
def test_supports_default_setting(model: str | None, expected: bool) -> None:
"""DP 225 is unsupported on H1 (a63) only."""
assert supports_default_setting(model) is expected


def test_force_load_omits_default_setting_for_h1() -> None:
"""H1 (a63) has a softener compartment but must not be queried for DP 225."""
dp_list = build_force_load_dp_list("roborock.wm.a63")

assert RoborockZeoProtocol.DEFAULT_SETTING not in dp_list
# The remaining softener DPs are still queried.
assert RoborockZeoProtocol.SOFTENER_SET in dp_list
assert RoborockZeoProtocol.SOFTENER_TYPE in dp_list
assert RoborockZeoProtocol.SOFTENER_EMPTY in dp_list


def test_force_load_keeps_default_setting_for_other_softener_models() -> None:
"""Other softener-equipped models still query DP 225."""
assert RoborockZeoProtocol.DEFAULT_SETTING in build_force_load_dp_list("roborock.wm.a102")


def test_force_load_omits_default_setting_without_softener() -> None:
"""Models without a softener compartment never query DP 225."""
assert RoborockZeoProtocol.DEFAULT_SETTING not in build_force_load_dp_list("roborock.wm.a92")
Loading