Skip to content

Commit faf6226

Browse files
committed
Add VacuumTrait to q10 devices
1 parent a69286f commit faf6226

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
"""Traits for Q10 B01 devices."""
22

3+
import asyncio
4+
import logging
35
from typing import Any
46

5-
from roborock.devices.rpc.b01_q7_channel import send_decoded_command
7+
from roborock import B01Props
8+
from roborock.data.b01_q10.b01_q10_code_mappings import B01_Q10_DP
69
from roborock.devices.traits import Trait
710
from roborock.devices.transport.mqtt_channel import MqttChannel
811

912
from .command import CommandTrait
13+
from .vacuum import VacuumTrait
14+
15+
_LOGGER = logging.getLogger(__name__)
1016

1117
__all__ = [
1218
"Q10PropertiesApi",
@@ -19,9 +25,15 @@ class Q10PropertiesApi(Trait):
1925
command: CommandTrait
2026
"""Trait for sending commands to Q10 devices."""
2127

28+
vacuum: VacuumTrait
29+
"""Trait for sending Vacuum related commands to Q10 devices"""
30+
2231
def __init__(self, channel: MqttChannel) -> None:
2332
"""Initialize the B01Props API."""
2433
self.command = CommandTrait(channel)
34+
self.vacuum = VacuumTrait(self.command)
35+
self._channel = channel
36+
self._task: asyncio.Task | None = None
2537

2638

2739
def create(channel: MqttChannel) -> Q10PropertiesApi:
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""Traits for Q10 B01 devices."""
2+
3+
import logging
4+
5+
from roborock.data.b01_q10.b01_q10_code_mappings import B01_Q10_DP
6+
7+
from .command import CommandTrait
8+
9+
_LOGGER = logging.getLogger(__name__)
10+
11+
12+
class VacuumTrait:
13+
"""Trait for sending vacuum commands.
14+
15+
This is wrapper around the CommandTrait for sending vacuum related
16+
commands to Q10 devices.
17+
"""
18+
19+
def __init__(self, command: CommandTrait) -> None:
20+
"""Initialize the CommandTrait."""
21+
self._command = command
22+
23+
async def start_clean(self) -> None:
24+
"""Start cleaning."""
25+
await self._command.send(
26+
command=B01_Q10_DP.START_CLEAN,
27+
# TODO: figure out other commands
28+
# 1 = start cleaning
29+
# 2 = "electoral" clean, also has "clean_parameters"
30+
# 4 = fast create map
31+
params={"cmd": 1},
32+
)
33+
34+
async def pause_clean(self) -> None:
35+
"""Pause cleaning."""
36+
await self._command.send(
37+
command=B01_Q10_DP.PAUSE,
38+
params={},
39+
)
40+
41+
async def resume_clean(self) -> None:
42+
"""Resume cleaning."""
43+
await self._command.send(
44+
command=B01_Q10_DP.RESUME,
45+
params={},
46+
)
47+
48+
async def stop_clean(self) -> None:
49+
"""Stop cleaning."""
50+
await self._command.send(
51+
command=B01_Q10_DP.STOP,
52+
params={},
53+
)
54+
55+
async def return_to_dock(self) -> None:
56+
"""Return to dock."""
57+
await self._command.send(
58+
command=B01_Q10_DP.START_DOCK_TASK,
59+
params={},
60+
)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import json
2+
from collections.abc import Awaitable, Callable
3+
from typing import Any
4+
5+
import pytest
6+
7+
from roborock.devices.traits.b01.q10 import Q10PropertiesApi
8+
from roborock.devices.traits.b01.q10.vacuum import VacuumTrait
9+
from tests.fixtures.channel_fixtures import FakeChannel
10+
11+
12+
@pytest.fixture(name="fake_channel")
13+
def fake_channel_fixture() -> FakeChannel:
14+
return FakeChannel()
15+
16+
17+
@pytest.fixture(name="q10_api")
18+
def q10_api_fixture(fake_channel: FakeChannel) -> Q10PropertiesApi:
19+
return Q10PropertiesApi(fake_channel) # type: ignore[arg-type]
20+
21+
22+
@pytest.fixture(name="vacuumm")
23+
def vacuumm_fixture(q10_api: Q10PropertiesApi) -> VacuumTrait:
24+
return q10_api.vacuum
25+
26+
27+
@pytest.mark.parametrize(
28+
("command_fn", "expected_payload"),
29+
[
30+
(lambda x: x.start_clean(), {"201": {"cmd": 1}}),
31+
(lambda x: x.pause_clean(), {"204": {}}),
32+
(lambda x: x.resume_clean(), {"205": {}}),
33+
(lambda x: x.stop_clean(), {"206": {}}),
34+
(lambda x: x.return_to_dock(), {"203": {}}),
35+
],
36+
)
37+
async def test_q7_api_set_fan_speed(
38+
vacuumm: VacuumTrait,
39+
fake_channel: FakeChannel,
40+
command_fn: Callable[[VacuumTrait], Awaitable[None]],
41+
expected_payload: dict[str, Any],
42+
) -> None:
43+
"""Test sending a vacuum start command."""
44+
await command_fn(vacuumm)
45+
46+
assert len(fake_channel.published_messages) == 1
47+
message = fake_channel.published_messages[0]
48+
assert message.payload
49+
payload_data = json.loads(message.payload.decode())
50+
assert payload_data == {"dps": expected_payload}

0 commit comments

Comments
 (0)