Skip to content

Commit 083929f

Browse files
committed
fix: Support unknown q10 DPS enum codes
1 parent 51495ce commit 083929f

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

roborock/data/code_mappings.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class RoborockModeEnum(StrEnum):
5555
"""A custom StrEnum that also stores an integer code for each member."""
5656

5757
code: int
58+
"""The integer code associated with the enum member."""
5859

5960
def __new__(cls, value: str, code: int) -> RoborockModeEnum:
6061
"""Creates a new enum member."""
@@ -68,7 +69,18 @@ def from_code(cls, code: int) -> RoborockModeEnum:
6869
for member in cls:
6970
if member.code == code:
7071
return member
71-
raise ValueError(f"{code} is not a valid code for {cls.__name__}")
72+
message = f"{code} is not a valid code for {cls.__name__}"
73+
if message not in completed_warnings:
74+
completed_warnings.add(message)
75+
_LOGGER.warning(message)
76+
raise ValueError(message)
77+
78+
@classmethod
79+
def from_code_optional(cls, code: int) -> RoborockModeEnum | None:
80+
try:
81+
return cls.from_code(code)
82+
except ValueError:
83+
return None
7284

7385
@classmethod
7486
def from_value(cls, value: str) -> RoborockModeEnum:

roborock/protocols/b01_q10_protocol.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,9 @@ def _convert_datapoints(datapoints: dict[str, Any], message: RoborockMessage) ->
4444
code = int(key)
4545
except ValueError as e:
4646
raise ValueError(f"dps key is not a valid integer: {e} for {message.payload!r}") from e
47-
try:
48-
dps = B01_Q10_DP.from_code(code)
49-
except ValueError as e:
50-
raise ValueError(f"dps key is not a valid B01_Q10_DP: {e} for {message.payload!r}") from e
51-
# Update from_code to use `Self` on newer python version to remove this type ignore
52-
result[dps] = value # type: ignore[index]
47+
if (dps := B01_Q10_DP.from_code_optional(code)) is not None:
48+
# Update from_code to use `Self` on newer python version to remove this type ignore
49+
result[dps] = value # type: ignore[index]
5350
return result
5451

5552

tests/data/test_code_mappings.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ def test_invalid_from_code() -> None:
2020
B01_Q10_DP.from_code(999999)
2121

2222

23+
def test_invalid_from_code_optional() -> None:
24+
"""Test invalid from_code_optional method."""
25+
assert B01_Q10_DP.from_code_optional(999999) is None
26+
27+
2328
def test_from_name() -> None:
2429
"""Test from_name method."""
2530
assert B01_Q10_DP.START_CLEAN == B01_Q10_DP.from_name("START_CLEAN")

tests/protocols/test_b01_q10_protocol.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ def test_decode_rpc_payload(filename: str, snapshot: SnapshotAssertion) -> None:
5858
(b'{"dps": {"not_a_number": 123}}', "dps key is not a valid integer"),
5959
(b'{"dps": {"101": 123}}', "Invalid dpCommon format: expected dict"),
6060
(b'{"dps": {"101": {"not_a_number": 123}}}', "Invalid dpCommon format: dps key is not a valid intege"),
61-
(b'{"dps": {"909090": 123}}', "dps key is not a valid B01_Q10_DP"),
6261
],
6362
)
6463
def test_decode_invalid_rpc_payload(payload: bytes, expected_error_message: str) -> None:
@@ -75,6 +74,23 @@ def test_decode_invalid_rpc_payload(payload: bytes, expected_error_message: str)
7574
decode_rpc_response(message)
7675

7776

77+
def test_decode_unknown_dps_code() -> None:
78+
"""Test decoding a B01 RPC response protocol message."""
79+
message = RoborockMessage(
80+
protocol=RoborockMessageProtocol.RPC_RESPONSE,
81+
payload=b'{"dps": {"909090": 123, "122":100}}',
82+
seq=12750,
83+
version=b"B01",
84+
random=97431,
85+
timestamp=1652547161,
86+
)
87+
88+
decoded_message = decode_rpc_response(message)
89+
assert decoded_message == {
90+
B01_Q10_DP.BATTERY: 100,
91+
}
92+
93+
7894
@pytest.mark.parametrize(
7995
("command", "params"),
8096
[

0 commit comments

Comments
 (0)