Skip to content

Commit 831abcf

Browse files
author
NOisi-X
committed
style: apply ruff-format and end-of-file-fixer fixes
1 parent 75890d0 commit 831abcf

3 files changed

Lines changed: 97 additions & 83 deletions

File tree

roborock/data/zeo/zeo_code_mappings.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ class ZeoDetergentExpansionType(RoborockEnum):
210210
class ZeoSoftenerExpansionType(RoborockEnum):
211211
softener = 1
212212
softener_expansion = 2
213-
wool_detergent = 3
213+
wool_detergent = 3
214214

215215

216216
class ZeoDirtDetectionStatus(RoborockEnum):
@@ -318,11 +318,3 @@ class ZeoDryerStartError(RoborockEnum):
318318
# class SmartHostStatus(RoborockEnum):
319319
# smart_host_waiting = 0
320320
# smart_hosting = 1
321-
322-
323-
324-
325-
326-
327-
328-

roborock/devices/traits/a01/__init__.py

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,17 @@
6262
from roborock.device_features import ZeoFeatures
6363
from roborock.devices.rpc.a01_channel import send_decoded_command
6464
from roborock.devices.traits import Trait
65-
from roborock.protocols.a01_protocol import decode_rpc_response
6665
from roborock.devices.traits.a01.device_features import ZeoFeatureTrait
6766
from roborock.devices.transport.mqtt_channel import MqttChannel
6867
from roborock.exceptions import RoborockException
6968
from roborock.mqtt.session import MqttQos
70-
from roborock.roborock_message import RoborockDyadDataProtocol, RoborockMessage, RoborockMessageProtocol, RoborockZeoProtocol
69+
from roborock.protocols.a01_protocol import decode_rpc_response
70+
from roborock.roborock_message import (
71+
RoborockDyadDataProtocol,
72+
RoborockMessage,
73+
RoborockMessageProtocol,
74+
RoborockZeoProtocol,
75+
)
7176

7277
_LOGGER = logging.getLogger(__name__)
7378

@@ -217,8 +222,12 @@ def to_dp_bool(val: Any) -> str:
217222
RoborockZeoProtocol.ION_DEODORIZATION: parse_bool,
218223
RoborockZeoProtocol.UV_LIGHT: parse_bool,
219224
RoborockZeoProtocol.SMART_HOSTING: parse_bool,
220-
RoborockZeoProtocol.SOFTENER_EXPANSION_TYPE: lambda val: _decode_expansion_type(val, ZeoSoftenerExpansionType.softener),
221-
RoborockZeoProtocol.DETERGENT_EXPANSION_TYPE: lambda val: _decode_expansion_type(val, ZeoDetergentExpansionType.concentrated_detergent),
225+
RoborockZeoProtocol.SOFTENER_EXPANSION_TYPE: lambda val: _decode_expansion_type(
226+
val, ZeoSoftenerExpansionType.softener
227+
),
228+
RoborockZeoProtocol.DETERGENT_EXPANSION_TYPE: lambda val: _decode_expansion_type(
229+
val, ZeoDetergentExpansionType.concentrated_detergent
230+
),
222231
RoborockZeoProtocol.SMILE_LIGHT_STATUS: parse_bool,
223232
RoborockZeoProtocol.POWER_LIGHT: parse_bool,
224233
RoborockZeoProtocol.PANEL_PROGRAM_PARAMS_SET: lambda val: int(val),
@@ -336,6 +345,7 @@ class ZeoStartParams:
336345
# 32-bit integer at DP 222. This mirrors WasherDpsCache.customMode in
337346
# module 725 of the React Native plugin bundle.
338347

348+
339349
@dataclass
340350
class ZeoCustomMode:
341351
"""Decoded custom programme parameters from DP 222 (LoadCloudProgram).
@@ -610,9 +620,7 @@ def _start_params(self) -> tuple[RoborockZeoProtocol, ...]:
610620
(RoborockZeoProtocol.ION_DEODORIZATION, "ion_deodorization"),
611621
)
612622

613-
async def _build_feature_gated_dps(
614-
self, features: ZeoFeatures | None, dps: dict[RoborockZeoProtocol, Any]
615-
) -> None:
623+
async def _build_feature_gated_dps(self, features: ZeoFeatures | None, dps: dict[RoborockZeoProtocol, Any]) -> None:
616624
"""Add feature-gated DPs to *dps* in-place, batch-querying uncached ones.
617625
618626
Only includes DPs whose corresponding FeatureBit is set in *features*.
@@ -822,12 +830,8 @@ async def _build_save_payload(self) -> dict[RoborockZeoProtocol, Any]:
822830
"""Bundle Mode + Program + cached optionals for a save command."""
823831
await self._ensure_subscribed()
824832
payload: dict[RoborockZeoProtocol, Any] = {
825-
RoborockZeoProtocol.MODE: self._dps_cache.get(
826-
int(RoborockZeoProtocol.MODE), 1
827-
),
828-
RoborockZeoProtocol.PROGRAM: self._dps_cache.get(
829-
int(RoborockZeoProtocol.PROGRAM), 1
830-
),
833+
RoborockZeoProtocol.MODE: self._dps_cache.get(int(RoborockZeoProtocol.MODE), 1),
834+
RoborockZeoProtocol.PROGRAM: self._dps_cache.get(int(RoborockZeoProtocol.PROGRAM), 1),
831835
}
832836
for dp in self._save_params:
833837
val = self._dps_cache.get(int(dp))
@@ -994,15 +998,15 @@ async def get_auto_detergent(self) -> bool:
994998
self._channel,
995999
{
9961000
RoborockZeoProtocol.ID_QUERY: [
997-
RoborockZeoProtocol.DETERGENT_TYPE if self.is_addition_type_control
1001+
RoborockZeoProtocol.DETERGENT_TYPE
1002+
if self.is_addition_type_control
9981003
else RoborockZeoProtocol.DETERGENT_SET,
9991004
],
10001005
},
10011006
value_encoder=json.dumps,
10021007
)
10031008
raw = result.get(
1004-
RoborockZeoProtocol.DETERGENT_TYPE if self.is_addition_type_control
1005-
else RoborockZeoProtocol.DETERGENT_SET
1009+
RoborockZeoProtocol.DETERGENT_TYPE if self.is_addition_type_control else RoborockZeoProtocol.DETERGENT_SET
10061010
)
10071011
return parse_bool(raw) if not self.is_addition_type_control else bool(raw and int(raw) > 0)
10081012

@@ -1012,15 +1016,15 @@ async def get_auto_softener(self) -> bool:
10121016
self._channel,
10131017
{
10141018
RoborockZeoProtocol.ID_QUERY: [
1015-
RoborockZeoProtocol.SOFTENER_TYPE if self.is_addition_type_control
1019+
RoborockZeoProtocol.SOFTENER_TYPE
1020+
if self.is_addition_type_control
10161021
else RoborockZeoProtocol.SOFTENER_SET,
10171022
],
10181023
},
10191024
value_encoder=json.dumps,
10201025
)
10211026
raw = result.get(
1022-
RoborockZeoProtocol.SOFTENER_TYPE if self.is_addition_type_control
1023-
else RoborockZeoProtocol.SOFTENER_SET
1027+
RoborockZeoProtocol.SOFTENER_TYPE if self.is_addition_type_control else RoborockZeoProtocol.SOFTENER_SET
10241028
)
10251029
return parse_bool(raw) if not self.is_addition_type_control else bool(raw and int(raw) > 0)
10261030

@@ -1223,12 +1227,15 @@ async def load_general_info(self) -> dict[RoborockZeoProtocol, Any]:
12231227
async def upload_log(self) -> dict[RoborockZeoProtocol, Any]:
12241228
"""Request the device to upload diagnostic logs (RPC call)."""
12251229
import random as _random
1230+
12261231
return await send_decoded_command(
12271232
self._channel,
1228-
{RoborockZeoProtocol.RPC_REQUEST: {
1229-
"id": _random.randint(0, 999999),
1230-
"method": "user_upload_log",
1231-
}},
1233+
{
1234+
RoborockZeoProtocol.RPC_REQUEST: {
1235+
"id": _random.randint(0, 999999),
1236+
"method": "user_upload_log",
1237+
}
1238+
},
12321239
value_encoder=lambda x: x,
12331240
)
12341241

@@ -1355,26 +1362,45 @@ async def set_value(self, protocol: RoborockZeoProtocol, value: Any) -> dict[Rob
13551362
# auto‑enable logic and for force‑load DP selection. These frozensets
13561363
# mirror the ``isHyperionSeries / isHaliaSeries / isHeraSeries`` and
13571364
# ``isM1Series / isMuseSeries / isMetisSeries`` guards.
1358-
_HYPERION_HALIA_HERA_PRODUCT_IDS: frozenset[str] = frozenset({
1359-
# Hyperion series
1360-
"roborock.wm.a141", "roborock.wm.a149", "roborock.wm.a207", "roborock.wm.a230",
1361-
# Halia series
1362-
"roborock.wm.a240", "roborock.wm.a241",
1363-
# Hera series
1364-
"roborock.wm.a227", "roborock.wm.a261", "roborock.wm.a273",
1365-
"roborock.wm.a268", "roborock.wm.a269",
1366-
})
1367-
1368-
_M1_MUSE_METIS_PRODUCT_IDS: frozenset[str] = frozenset({
1369-
# M1 series
1370-
"roborock.wm.a92", "roborock.wm.a93", "roborock.wm.a133", "roborock.wm.a277",
1371-
"roborock.wm.a162", "roborock.wm.a233", "roborock.wm.a276", "roborock.wm.a234",
1372-
"roborock.wm.a218",
1373-
# Muse series
1374-
"roborock.wm.a142", "roborock.wm.a215",
1375-
# Metis series
1376-
"roborock.wm.a154", "roborock.wm.a214",
1377-
})
1365+
_HYPERION_HALIA_HERA_PRODUCT_IDS: frozenset[str] = frozenset(
1366+
{
1367+
# Hyperion series
1368+
"roborock.wm.a141",
1369+
"roborock.wm.a149",
1370+
"roborock.wm.a207",
1371+
"roborock.wm.a230",
1372+
# Halia series
1373+
"roborock.wm.a240",
1374+
"roborock.wm.a241",
1375+
# Hera series
1376+
"roborock.wm.a227",
1377+
"roborock.wm.a261",
1378+
"roborock.wm.a273",
1379+
"roborock.wm.a268",
1380+
"roborock.wm.a269",
1381+
}
1382+
)
1383+
1384+
_M1_MUSE_METIS_PRODUCT_IDS: frozenset[str] = frozenset(
1385+
{
1386+
# M1 series
1387+
"roborock.wm.a92",
1388+
"roborock.wm.a93",
1389+
"roborock.wm.a133",
1390+
"roborock.wm.a277",
1391+
"roborock.wm.a162",
1392+
"roborock.wm.a233",
1393+
"roborock.wm.a276",
1394+
"roborock.wm.a234",
1395+
"roborock.wm.a218",
1396+
# Muse series
1397+
"roborock.wm.a142",
1398+
"roborock.wm.a215",
1399+
# Metis series
1400+
"roborock.wm.a154",
1401+
"roborock.wm.a214",
1402+
}
1403+
)
13781404

13791405

13801406
def _is_dryer(product: HomeDataProduct) -> bool:

tests/devices/test_a01_code_review.py

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,7 @@ def test_zeo_feature_bits_match_bundle_positions():
126126
ZeoFeatureBits.ion_deodorization: 23,
127127
}
128128
for member, expected_pos in expected.items():
129-
assert int(member) == expected_pos, (
130-
f"{member.name} is at bit {int(member)}, expected {expected_pos}"
131-
)
129+
assert int(member) == expected_pos, f"{member.name} is at bit {int(member)}, expected {expected_pos}"
132130

133131

134132
def test_zeo_features_fields_map_to_feature_bits():
@@ -138,9 +136,7 @@ def test_zeo_features_fields_map_to_feature_bits():
138136
ZeoFeatures.from_feature_bits() to raise AttributeError.
139137
"""
140138
for f in fields(ZeoFeatures):
141-
assert hasattr(ZeoFeatureBits, f.name), (
142-
f"ZeoFeatures.{f.name} has no matching ZeoFeatureBits member"
143-
)
139+
assert hasattr(ZeoFeatureBits, f.name), f"ZeoFeatures.{f.name} has no matching ZeoFeatureBits member"
144140

145141

146142
def test_zeo_features_from_feature_bits_decodes_correct_bits():
@@ -226,22 +222,19 @@ async def _side_effect(channel, params, **kwargs):
226222
}
227223
return {}
228224

229-
with patch(
230-
"roborock.devices.traits.a01.send_decoded_command", new_callable=AsyncMock, side_effect=_side_effect
231-
), patch(
232-
"roborock.devices.traits.a01.device_features.send_decoded_command",
233-
new_callable=AsyncMock,
234-
side_effect=_side_effect,
225+
with (
226+
patch("roborock.devices.traits.a01.send_decoded_command", new_callable=AsyncMock, side_effect=_side_effect),
227+
patch(
228+
"roborock.devices.traits.a01.device_features.send_decoded_command",
229+
new_callable=AsyncMock,
230+
side_effect=_side_effect,
231+
),
235232
):
236233
api = ZeoApi(mock_channel)
237234
await api.start()
238235

239236
# The SET (non-query) command is the one that carries START.
240-
set_calls = [
241-
params
242-
for params, _ in captured
243-
if _ID_QUERY_INT not in {int(k) for k in params}
244-
]
237+
set_calls = [params for params, _ in captured if _ID_QUERY_INT not in {int(k) for k in params}]
245238
assert set_calls, "start() should issue a SET command"
246239
start_params = set_calls[-1]
247240
assert start_params[RoborockZeoProtocol.START] == "True"
@@ -275,24 +268,27 @@ async def _side_effect(channel, params, **kwargs):
275268

276269
# Pre-populate cache with START params so _get_start_params() doesn't
277270
# issue an extra query that would distort the count.
278-
with patch(
279-
"roborock.devices.traits.a01.send_decoded_command", new_callable=AsyncMock, side_effect=_side_effect
280-
), patch(
281-
"roborock.devices.traits.a01.device_features.send_decoded_command",
282-
new_callable=AsyncMock,
283-
side_effect=_side_effect,
271+
with (
272+
patch("roborock.devices.traits.a01.send_decoded_command", new_callable=AsyncMock, side_effect=_side_effect),
273+
patch(
274+
"roborock.devices.traits.a01.device_features.send_decoded_command",
275+
new_callable=AsyncMock,
276+
side_effect=_side_effect,
277+
),
284278
):
285279
api = ZeoApi(mock_channel)
286280
# Seed the DPS cache with required START params so only FEATURE_BITS
287281
# and feature-gated queries are counted.
288-
api._dps_cache.update({
289-
int(RoborockZeoProtocol.MODE): 1,
290-
int(RoborockZeoProtocol.PROGRAM): 1,
291-
int(RoborockZeoProtocol.TEMP): 30,
292-
int(RoborockZeoProtocol.RINSE_TIMES): 2,
293-
int(RoborockZeoProtocol.SPIN_LEVEL): 800,
294-
int(RoborockZeoProtocol.DRYING_MODE): 1,
295-
})
282+
api._dps_cache.update(
283+
{
284+
int(RoborockZeoProtocol.MODE): 1,
285+
int(RoborockZeoProtocol.PROGRAM): 1,
286+
int(RoborockZeoProtocol.TEMP): 30,
287+
int(RoborockZeoProtocol.RINSE_TIMES): 2,
288+
int(RoborockZeoProtocol.SPIN_LEVEL): 800,
289+
int(RoborockZeoProtocol.DRYING_MODE): 1,
290+
}
291+
)
296292
await api.start()
297293

298294
# FEATURE_BITS query (1) + batch gated-DP query (1) + SET (1) = 3 total calls.

0 commit comments

Comments
 (0)