diff --git a/deebot_client/commands/xml/__init__.py b/deebot_client/commands/xml/__init__.py
index 9561f6581..c61cfeca1 100644
--- a/deebot_client/commands/xml/__init__.py
+++ b/deebot_client/commands/xml/__init__.py
@@ -10,8 +10,8 @@
from .charge import Charge
from .charge_state import GetChargeState
from .clean_logs import GetCleanLogs
+from .clean_speed import GetCleanSpeed, SetCleanSpeed
from .error import GetError
-from .fan_speed import GetFanSpeed
from .life_span import GetLifeSpan
from .play_sound import PlaySound
from .pos import GetChargerPos, GetPos
@@ -26,24 +26,39 @@
"GetChargeState",
"GetChargerPos",
"GetCleanLogs",
+ "GetCleanSpeed",
"GetCleanSum",
"GetError",
- "GetFanSpeed",
"GetLifeSpan",
"GetPos",
"PlaySound",
+ "SetCleanSpeed",
]
# fmt: off
# ordered by file asc
_COMMANDS: list[type[XmlCommand]] = [
GetBatteryInfo,
- GetChargerPos,
+
+ GetChargeState,
+
+ Charge,
+
GetCleanLogs,
+
+ GetCleanSpeed,
+ SetCleanSpeed,
+
GetError,
+
GetLifeSpan,
- GetPos,
+
PlaySound,
+
+ GetChargerPos,
+ GetPos,
+
+ GetCleanSum
]
# fmt: on
diff --git a/deebot_client/commands/xml/fan_speed.py b/deebot_client/commands/xml/clean_speed.py
similarity index 54%
rename from deebot_client/commands/xml/fan_speed.py
rename to deebot_client/commands/xml/clean_speed.py
index 2a834554c..7041b1c0d 100644
--- a/deebot_client/commands/xml/fan_speed.py
+++ b/deebot_client/commands/xml/clean_speed.py
@@ -6,8 +6,9 @@
from deebot_client.events import FanSpeedEvent, FanSpeedLevel
from deebot_client.message import HandlingResult
+from deebot_client.util import get_enum
-from .common import XmlCommandWithMessageHandling
+from .common import ExecuteCommand, XmlCommandWithMessageHandling
if TYPE_CHECKING:
from xml.etree.ElementTree import Element
@@ -15,8 +16,8 @@
from deebot_client.event_bus import EventBus
-class GetFanSpeed(XmlCommandWithMessageHandling):
- """GetFanSpeed command."""
+class GetCleanSpeed(XmlCommandWithMessageHandling):
+ """GetCleanSpeed command."""
NAME = "GetCleanSpeed"
@@ -29,16 +30,16 @@ def _handle_xml(cls, event_bus: EventBus, xml: Element) -> HandlingResult:
if xml.attrib.get("ret") != "ok" or not (speed := xml.attrib.get("speed")):
return HandlingResult.analyse()
- event: FanSpeedEvent | None = None
+ event_bus.notify(FanSpeedEvent(FanSpeedLevel.from_xml(speed)))
+ return HandlingResult.success()
- match speed.lower():
- case "standard":
- event = FanSpeedEvent(FanSpeedLevel.NORMAL)
- case "strong":
- event = FanSpeedEvent(FanSpeedLevel.MAX)
- if event:
- event_bus.notify(event)
- return HandlingResult.success()
+class SetCleanSpeed(ExecuteCommand):
+ """SetCleanSpeed command."""
- return HandlingResult.analyse()
+ NAME = "SetCleanSpeed"
+
+ def __init__(self, speed: FanSpeedLevel | str) -> None:
+ if isinstance(speed, str):
+ speed = get_enum(FanSpeedLevel, speed)
+ super().__init__({"speed": speed.xml_value})
diff --git a/tests/commands/xml/test_clean_speed.py b/tests/commands/xml/test_clean_speed.py
new file mode 100644
index 000000000..bd42e41b4
--- /dev/null
+++ b/tests/commands/xml/test_clean_speed.py
@@ -0,0 +1,75 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import pytest
+
+from deebot_client.command import CommandResult, CommandWithMessageHandling
+from deebot_client.commands.xml import GetCleanSpeed, SetCleanSpeed
+from deebot_client.events import FanSpeedEvent, FanSpeedLevel
+from deebot_client.message import HandlingState
+from tests.commands import assert_command
+
+from . import get_request_xml
+
+if TYPE_CHECKING:
+ from deebot_client.events.base import Event
+
+
+@pytest.mark.parametrize(
+ "speed", list(FanSpeedLevel) + [level.name for level in FanSpeedLevel]
+)
+def test_GetCleanSpeed_should_build_with_string_and_enums(
+ speed: str | FanSpeedLevel,
+) -> None:
+ """Test case for the way HA invokes the constructor."""
+ assert SetCleanSpeed(speed) is not None
+
+
+@pytest.mark.parametrize(
+ ("speed", "expected_event"),
+ [
+ ("standard", FanSpeedEvent(FanSpeedLevel.NORMAL)),
+ ("strong", FanSpeedEvent(FanSpeedLevel.MAX)),
+ ],
+ ids=["standard", "strong"],
+)
+async def test_get_fan_speed(speed: str, expected_event: Event) -> None:
+ json = get_request_xml(f"")
+ await assert_command(GetCleanSpeed(), json, expected_event)
+
+
+@pytest.mark.parametrize(
+ ("xml", "expected_state"),
+ [
+ ("", HandlingState.ANALYSE_LOGGED),
+ ("", HandlingState.ANALYSE_LOGGED),
+ ("", HandlingState.ERROR),
+ ],
+ ids=["error", "no_state", "invalid_speed"],
+)
+async def test_get_fan_speed_error(xml: str, expected_state: HandlingState) -> None:
+ json = get_request_xml(xml)
+ await assert_command(
+ GetCleanSpeed(),
+ json,
+ None,
+ command_result=CommandResult(expected_state),
+ )
+
+
+@pytest.mark.parametrize(
+ ("command", "xml", "result"),
+ [
+ (
+ SetCleanSpeed(FanSpeedLevel.MAX),
+ "",
+ HandlingState.SUCCESS,
+ ),
+ ],
+)
+async def test_set_fan_speed(
+ command: CommandWithMessageHandling, xml: str, result: HandlingState
+) -> None:
+ json = get_request_xml(xml)
+ await assert_command(command, json, None, command_result=CommandResult(result))
diff --git a/tests/commands/xml/test_fan_speed.py b/tests/commands/xml/test_fan_speed.py
deleted file mode 100644
index bf728ecfc..000000000
--- a/tests/commands/xml/test_fan_speed.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from __future__ import annotations
-
-from typing import TYPE_CHECKING
-
-import pytest
-
-from deebot_client.command import CommandResult
-from deebot_client.commands.xml import GetFanSpeed
-from deebot_client.events import FanSpeedEvent, FanSpeedLevel
-from deebot_client.message import HandlingState
-from tests.commands import assert_command
-
-from . import get_request_xml
-
-if TYPE_CHECKING:
- from deebot_client.events.base import Event
-
-
-@pytest.mark.parametrize(
- ("speed", "expected_event"),
- [
- ("standard", FanSpeedEvent(FanSpeedLevel.NORMAL)),
- ("strong", FanSpeedEvent(FanSpeedLevel.MAX)),
- ],
- ids=["standard", "strong"],
-)
-async def test_get_fan_speed(speed: str, expected_event: Event) -> None:
- json = get_request_xml(f"")
- await assert_command(GetFanSpeed(), json, expected_event)
-
-
-@pytest.mark.parametrize(
- "xml",
- ["", ""],
- ids=["error", "no_state"],
-)
-async def test_get_fan_speed_error(xml: str) -> None:
- json = get_request_xml(xml)
- await assert_command(
- GetFanSpeed(),
- json,
- None,
- command_result=CommandResult(HandlingState.ANALYSE_LOGGED),
- )