Skip to content

Commit b8b2409

Browse files
authored
feat: add dust collection settings to the B01 Q7 api (#919)
Adds set_dust_collection (auto-empty on/off) and set_dust_collection_frequency (cleans per emptying) to Q7PropertiesApi, using prop.set like the other Q7 setters. Both verified against a real Q7 M5+ (roborock.vacuum.sc05, fw 03.01.80): dust_auto_state and dust_frequency round-trip correctly. Note that writing dust_action (empty now) is rejected by the device with code 1, so a manual-empty trigger is intentionally not included; it likely requires the dock-task DPS (203 start_dock_task) instead.
1 parent 6f5c8ec commit b8b2409

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

roborock/devices/traits/b01/q7/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ async def set_child_lock(self, enabled: bool) -> None:
131131
"""Enable or disable the child lock."""
132132
await self.set_prop(RoborockB01Props.CHILD_LOCK, int(enabled))
133133

134+
async def set_dust_collection(self, enabled: bool) -> None:
135+
"""Enable or disable automatic dust collection at the dock."""
136+
await self.set_prop(RoborockB01Props.DUST_AUTO_STATE, int(enabled))
137+
138+
async def set_dust_collection_frequency(self, frequency: int) -> None:
139+
"""Set how often the dock auto-empties, in cleans per emptying (1 = every clean)."""
140+
if frequency < 1:
141+
raise ValueError(f"frequency must be a positive number of cleans, got {frequency}")
142+
await self.set_prop(RoborockB01Props.DUST_FREQUENCY, frequency)
143+
134144
async def set_do_not_disturb(self, enabled: bool, begin_time: int, end_time: int) -> None:
135145
"""Configure do-not-disturb.
136146

tests/devices/traits/b01/q7/test_init.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,56 @@ async def test_q7_api_set_child_lock(
133133
assert params == {RoborockB01Props.CHILD_LOCK: expected_code}
134134

135135

136+
@pytest.mark.parametrize(
137+
("enabled", "expected_code"),
138+
[(True, 1), (False, 0)],
139+
)
140+
async def test_q7_api_set_dust_collection(
141+
enabled: bool,
142+
expected_code: int,
143+
q7_api: Q7PropertiesApi,
144+
fake_channel: FakeQ7Channel,
145+
):
146+
"""Test toggling automatic dust collection."""
147+
fake_channel.response_queue.append({"result": "ok"})
148+
await q7_api.set_dust_collection(enabled)
149+
150+
assert len(fake_channel.published_commands) == 1
151+
command, params = fake_channel.published_commands[0]
152+
assert command == RoborockB01Q7Methods.SET_PROP
153+
assert params == {RoborockB01Props.DUST_AUTO_STATE: expected_code}
154+
155+
156+
@pytest.mark.parametrize("frequency", [1, 2, 3])
157+
async def test_q7_api_set_dust_collection_frequency(
158+
frequency: int,
159+
q7_api: Q7PropertiesApi,
160+
fake_channel: FakeQ7Channel,
161+
):
162+
"""Test setting the automatic dust-collection frequency."""
163+
fake_channel.response_queue.append({"result": "ok"})
164+
await q7_api.set_dust_collection_frequency(frequency)
165+
166+
assert len(fake_channel.published_commands) == 1
167+
command, params = fake_channel.published_commands[0]
168+
assert command == RoborockB01Q7Methods.SET_PROP
169+
assert params == {RoborockB01Props.DUST_FREQUENCY: frequency}
170+
171+
172+
@pytest.mark.parametrize("frequency", [0, -1])
173+
async def test_q7_api_set_dust_collection_frequency_invalid(
174+
frequency: int,
175+
q7_api: Q7PropertiesApi,
176+
fake_channel: FakeQ7Channel,
177+
):
178+
"""Test invalid dust-collection frequencies raise without publishing."""
179+
fake_channel.response_queue.append({"result": "ok"})
180+
with pytest.raises(ValueError, match="positive number of cleans"):
181+
await q7_api.set_dust_collection_frequency(frequency)
182+
183+
assert len(fake_channel.published_commands) == 0
184+
185+
136186
@pytest.mark.parametrize("enabled, expected_is_open", [(True, 1), (False, 0)])
137187
async def test_q7_api_set_do_not_disturb(
138188
enabled: bool,

0 commit comments

Comments
 (0)