Skip to content

Commit

Permalink
Add XML command "SetFanSpeed"
Browse files Browse the repository at this point in the history
  • Loading branch information
flubshi authored and pentesttkr committed Aug 29, 2024
1 parent 5da23d7 commit 136fb4d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 5 deletions.
3 changes: 2 additions & 1 deletion deebot_client/commands/xml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from .charge_state import GetChargeState
from .error import GetError
from .fan_speed import GetFanSpeed
from .fan_speed import GetFanSpeed, SetFanSpeed
from .pos import GetPos

if TYPE_CHECKING:
Expand All @@ -18,6 +18,7 @@
"GetChargeState",
"GetError",
"GetFanSpeed",
"SetFanSpeed",
"GetPos",
]

Expand Down
29 changes: 26 additions & 3 deletions deebot_client/commands/xml/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

from defusedxml import ElementTree # type: ignore[import-untyped]

from deebot_client.command import Command, CommandWithMessageHandling
from deebot_client.command import Command, CommandWithMessageHandling, SetCommand
from deebot_client.const import DataType
from deebot_client.logging_filter import get_logger
from deebot_client.message import HandlingResult, MessageStr
from deebot_client.message import HandlingResult, MessageStr, HandlingState

if TYPE_CHECKING:
from deebot_client.event_bus import EventBus
Expand All @@ -25,7 +25,6 @@ class XmlCommand(Command):
data_type: DataType = DataType.XML

@property # type: ignore[misc]
@classmethod
def has_sub_element(cls) -> bool:
"""Return True if command has inner element."""
return False
Expand Down Expand Up @@ -65,3 +64,27 @@ def _handle_str(cls, event_bus: EventBus, message: str) -> HandlingResult:
"""
xml = ElementTree.fromstring(message)
return cls._handle_xml(event_bus, xml)


class ExecuteCommand(XmlCommandWithMessageHandling, ABC):
"""Command, which is executing something (ex. Charge)."""

@classmethod
def _handle_xml(cls, event_bus: EventBus, xml: Element) -> HandlingResult:
"""Handle message->xml and notify the correct event subscribers.
:return: A message response
"""
# Success event looks like <ctl ret='ok'/>
if xml.attrib.get("ret") == "ok":
return HandlingResult.success()

_LOGGER.warning('Command "%s" was not successful. XML response: %s', cls.name, xml)
return HandlingResult(HandlingState.FAILED)


class XmlSetCommand(ExecuteCommand, SetCommand, ABC):
"""Xml base set command.
Command needs to be linked to the "get" command, for handling (updating) the sensors.
"""
18 changes: 17 additions & 1 deletion deebot_client/commands/xml/fan_speed.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

from __future__ import annotations

from types import MappingProxyType
from typing import TYPE_CHECKING

from deebot_client.command import InitParam
from deebot_client.events import FanSpeedEvent, FanSpeedLevel
from deebot_client.message import HandlingResult

from .common import XmlCommandWithMessageHandling
from .common import XmlCommandWithMessageHandling, XmlSetCommand

if TYPE_CHECKING:
from xml.etree.ElementTree import Element
Expand Down Expand Up @@ -42,3 +44,17 @@ def _handle_xml(cls, event_bus: EventBus, xml: Element) -> HandlingResult:
return HandlingResult.success()

return HandlingResult.analyse()


class SetFanSpeed(XmlSetCommand):
"""Set fan speed command."""

name = "SetCleanSpeed"
get_command = GetFanSpeed
_mqtt_params = MappingProxyType({"speed": InitParam(FanSpeedLevel)})

def __init__(self, speed: FanSpeedLevel | str) -> None:
if isinstance(speed, int):
speed = "strong" if speed in [1, 2] else "normal"
super().__init__({"speed": speed})

12 changes: 12 additions & 0 deletions tests/commands/xml/test_fan_speed.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

from deebot_client.command import CommandResult
from deebot_client.commands.xml import GetFanSpeed
from deebot_client.commands.xml.fan_speed import SetFanSpeed
from deebot_client.events import FanSpeedEvent, FanSpeedLevel
from deebot_client.message import HandlingState
from tests.commands import assert_command

from . import get_request_xml
from ..json import assert_set_command

if TYPE_CHECKING:
from deebot_client.events.base import Event
Expand Down Expand Up @@ -42,3 +44,13 @@ async def test_get_fan_speed_error(xml: str) -> None:
None,
command_result=CommandResult(HandlingState.ANALYSE_LOGGED),
)

async def test_set_fan_speed() -> None:
command = SetFanSpeed(FanSpeedLevel.MAX)
json = get_request_xml("<ctl ret='ok' />")
await assert_command(command, json, None, command_result=CommandResult(HandlingState.SUCCESS))

async def test_set_fan_speed_error() -> None:
command = SetFanSpeed("invalid")
json = get_request_xml("<ctl ret='error' />")
await assert_command(command, json, None, command_result=CommandResult(HandlingState.FAILED))

0 comments on commit 136fb4d

Please sign in to comment.