Skip to content

Commit 8ed90f2

Browse files
nanomadedenhaus
andauthored
Add XML command SetCleanSpeed (#911)
Co-authored-by: Robert Resch <robert@resch.dev>
1 parent 3d3a65d commit 8ed90f2

4 files changed

Lines changed: 108 additions & 61 deletions

File tree

deebot_client/commands/xml/__init__.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from .charge import Charge
1111
from .charge_state import GetChargeState
1212
from .clean_logs import GetCleanLogs
13+
from .clean_speed import GetCleanSpeed, SetCleanSpeed
1314
from .error import GetError
14-
from .fan_speed import GetFanSpeed
1515
from .life_span import GetLifeSpan
1616
from .play_sound import PlaySound
1717
from .pos import GetChargerPos, GetPos
@@ -26,24 +26,39 @@
2626
"GetChargeState",
2727
"GetChargerPos",
2828
"GetCleanLogs",
29+
"GetCleanSpeed",
2930
"GetCleanSum",
3031
"GetError",
31-
"GetFanSpeed",
3232
"GetLifeSpan",
3333
"GetPos",
3434
"PlaySound",
35+
"SetCleanSpeed",
3536
]
3637

3738
# fmt: off
3839
# ordered by file asc
3940
_COMMANDS: list[type[XmlCommand]] = [
4041
GetBatteryInfo,
41-
GetChargerPos,
42+
43+
GetChargeState,
44+
45+
Charge,
46+
4247
GetCleanLogs,
48+
49+
GetCleanSpeed,
50+
SetCleanSpeed,
51+
4352
GetError,
53+
4454
GetLifeSpan,
45-
GetPos,
55+
4656
PlaySound,
57+
58+
GetChargerPos,
59+
GetPos,
60+
61+
GetCleanSum
4762
]
4863
# fmt: on
4964

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66

77
from deebot_client.events import FanSpeedEvent, FanSpeedLevel
88
from deebot_client.message import HandlingResult
9+
from deebot_client.util import get_enum
910

10-
from .common import XmlCommandWithMessageHandling
11+
from .common import ExecuteCommand, XmlCommandWithMessageHandling
1112

1213
if TYPE_CHECKING:
1314
from xml.etree.ElementTree import Element
1415

1516
from deebot_client.event_bus import EventBus
1617

1718

18-
class GetFanSpeed(XmlCommandWithMessageHandling):
19-
"""GetFanSpeed command."""
19+
class GetCleanSpeed(XmlCommandWithMessageHandling):
20+
"""GetCleanSpeed command."""
2021

2122
NAME = "GetCleanSpeed"
2223

@@ -29,16 +30,16 @@ def _handle_xml(cls, event_bus: EventBus, xml: Element) -> HandlingResult:
2930
if xml.attrib.get("ret") != "ok" or not (speed := xml.attrib.get("speed")):
3031
return HandlingResult.analyse()
3132

32-
event: FanSpeedEvent | None = None
33+
event_bus.notify(FanSpeedEvent(FanSpeedLevel.from_xml(speed)))
34+
return HandlingResult.success()
3335

34-
match speed.lower():
35-
case "standard":
36-
event = FanSpeedEvent(FanSpeedLevel.NORMAL)
37-
case "strong":
38-
event = FanSpeedEvent(FanSpeedLevel.MAX)
3936

40-
if event:
41-
event_bus.notify(event)
42-
return HandlingResult.success()
37+
class SetCleanSpeed(ExecuteCommand):
38+
"""SetCleanSpeed command."""
4339

44-
return HandlingResult.analyse()
40+
NAME = "SetCleanSpeed"
41+
42+
def __init__(self, speed: FanSpeedLevel | str) -> None:
43+
if isinstance(speed, str):
44+
speed = get_enum(FanSpeedLevel, speed)
45+
super().__init__({"speed": speed.xml_value})
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
5+
import pytest
6+
7+
from deebot_client.command import CommandResult, CommandWithMessageHandling
8+
from deebot_client.commands.xml import GetCleanSpeed, SetCleanSpeed
9+
from deebot_client.events import FanSpeedEvent, FanSpeedLevel
10+
from deebot_client.message import HandlingState
11+
from tests.commands import assert_command
12+
13+
from . import get_request_xml
14+
15+
if TYPE_CHECKING:
16+
from deebot_client.events.base import Event
17+
18+
19+
@pytest.mark.parametrize(
20+
"speed", list(FanSpeedLevel) + [level.name for level in FanSpeedLevel]
21+
)
22+
def test_GetCleanSpeed_should_build_with_string_and_enums(
23+
speed: str | FanSpeedLevel,
24+
) -> None:
25+
"""Test case for the way HA invokes the constructor."""
26+
assert SetCleanSpeed(speed) is not None
27+
28+
29+
@pytest.mark.parametrize(
30+
("speed", "expected_event"),
31+
[
32+
("standard", FanSpeedEvent(FanSpeedLevel.NORMAL)),
33+
("strong", FanSpeedEvent(FanSpeedLevel.MAX)),
34+
],
35+
ids=["standard", "strong"],
36+
)
37+
async def test_get_fan_speed(speed: str, expected_event: Event) -> None:
38+
json = get_request_xml(f"<ctl ret='ok' speed='{speed}'/>")
39+
await assert_command(GetCleanSpeed(), json, expected_event)
40+
41+
42+
@pytest.mark.parametrize(
43+
("xml", "expected_state"),
44+
[
45+
("<ctl ret='error'/>", HandlingState.ANALYSE_LOGGED),
46+
("<ctl ret='ok' />", HandlingState.ANALYSE_LOGGED),
47+
("<ctl ret='ok' speed='invalid'/>", HandlingState.ERROR),
48+
],
49+
ids=["error", "no_state", "invalid_speed"],
50+
)
51+
async def test_get_fan_speed_error(xml: str, expected_state: HandlingState) -> None:
52+
json = get_request_xml(xml)
53+
await assert_command(
54+
GetCleanSpeed(),
55+
json,
56+
None,
57+
command_result=CommandResult(expected_state),
58+
)
59+
60+
61+
@pytest.mark.parametrize(
62+
("command", "xml", "result"),
63+
[
64+
(
65+
SetCleanSpeed(FanSpeedLevel.MAX),
66+
"<ctl ret='ok' />",
67+
HandlingState.SUCCESS,
68+
),
69+
],
70+
)
71+
async def test_set_fan_speed(
72+
command: CommandWithMessageHandling, xml: str, result: HandlingState
73+
) -> None:
74+
json = get_request_xml(xml)
75+
await assert_command(command, json, None, command_result=CommandResult(result))

tests/commands/xml/test_fan_speed.py

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)