Skip to content
Merged
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
23 changes: 23 additions & 0 deletions roborock/devices/traits/b01/q7/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,29 @@ async def set_child_lock(self, enabled: bool) -> None:
"""Enable or disable the child lock."""
await self.set_prop(RoborockB01Props.CHILD_LOCK, int(enabled))

async def set_do_not_disturb(self, enabled: bool, begin_time: int, end_time: int) -> None:
"""Configure do-not-disturb.

The device expects all three values together via ``service.set_quiet_time``
(individual ``prop.set`` calls are ignored). ``begin_time``/``end_time`` are
minutes since midnight and must be in the range 0-1439 (inclusive).

Ranges that cross midnight are supported by passing a ``begin_time`` that is
greater than ``end_time`` (e.g. 22:00-07:00 is ``begin_time=1320``,
``end_time=420``).
"""
for name, value in (("begin_time", begin_time), ("end_time", end_time)):
if not 0 <= value <= 1439:
raise ValueError(f"{name} must be between 0 and 1439 minutes since midnight, got {value}")
await self.send(
RoborockB01Q7Methods.SET_QUIET_TIME,
{
"is_open": int(enabled),
"quiet_begin_time": begin_time,
"quiet_end_time": end_time,
},
)
Comment on lines +119 to +140

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good, but not 100% needed


async def start_clean(self) -> None:
"""Start cleaning."""
await self.send(
Expand Down
39 changes: 39 additions & 0 deletions tests/devices/traits/b01/q7/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,45 @@ async def test_q7_api_set_child_lock(
assert payload_data["dps"]["10000"]["params"] == {RoborockB01Props.CHILD_LOCK: expected_code}


@pytest.mark.parametrize("enabled, expected_is_open", [(True, 1), (False, 0)])
async def test_q7_api_set_do_not_disturb(
enabled: bool,
expected_is_open: int,
q7_api: Q7PropertiesApi,
fake_channel: FakeChannel,
message_builder: B01MessageBuilder,
):
"""Test do-not-disturb is set as a whole via service.set_quiet_time."""
fake_channel.response_queue.append(message_builder.build({"result": "ok"}))
await q7_api.set_do_not_disturb(enabled, 1200, 420)
Comment on lines +195 to +205

message = fake_channel.published_messages[0]
payload_data = json.loads(unpad(message.payload, AES.block_size))
assert payload_data["dps"]["10000"]["method"] == "service.set_quiet_time"
assert payload_data["dps"]["10000"]["params"] == {
"is_open": expected_is_open,
"quiet_begin_time": 1200,
"quiet_end_time": 420,
}


@pytest.mark.parametrize(
("begin_time", "end_time"),
[(-1, 420), (1440, 420), (1200, -1), (1200, 1440)],
)
async def test_q7_api_set_do_not_disturb_invalid_time(
begin_time: int,
end_time: int,
q7_api: Q7PropertiesApi,
fake_channel: FakeChannel,
):
"""Test out-of-range times raise ValueError and nothing is sent."""
with pytest.raises(ValueError, match="minutes since midnight"):
await q7_api.set_do_not_disturb(True, begin_time, end_time)

assert len(fake_channel.published_messages) == 0


@pytest.mark.parametrize(
("mode", "expected_code"),
[
Expand Down
Loading