Skip to content

Commit 24e906b

Browse files
committed
Implement ResetLifeSpan
1 parent dd46cd3 commit 24e906b

3 files changed

Lines changed: 96 additions & 11 deletions

File tree

deebot_client/commands/xml/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from .clean_logs import GetCleanLogs
1313
from .error import GetError
1414
from .fan_speed import GetFanSpeed
15-
from .life_span import GetLifeSpan
15+
from .life_span import GetLifeSpan, ResetLifeSpan
1616
from .play_sound import PlaySound
1717
from .pos import GetPos
1818
from .stats import GetCleanSum
@@ -31,6 +31,7 @@
3131
"GetLifeSpan",
3232
"GetPos",
3333
"PlaySound",
34+
"ResetLifeSpan",
3435
]
3536

3637
# fmt: off
@@ -46,6 +47,7 @@
4647
GetLifeSpan,
4748
GetPos,
4849
PlaySound,
50+
ResetLifeSpan,
4951
]
5052
# fmt: on
5153

deebot_client/commands/xml/life_span.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING
5+
from types import MappingProxyType
6+
from typing import TYPE_CHECKING, Any
67

8+
from deebot_client.command import InitParam
79
from deebot_client.events import LifeSpan, LifeSpanEvent
8-
from deebot_client.message import HandlingResult
10+
from deebot_client.message import HandlingResult, HandlingState
911

10-
from .common import XmlCommandWithMessageHandling
12+
from .common import ExecuteCommand, XmlCommandMqttP2P, XmlCommandWithMessageHandling
1113

1214
if TYPE_CHECKING:
1315
from xml.etree.ElementTree import Element
@@ -20,8 +22,11 @@ class GetLifeSpan(XmlCommandWithMessageHandling):
2022

2123
NAME = "GetLifeSpan"
2224

23-
def __init__(self, life_span: LifeSpan) -> None:
24-
super().__init__({"type": life_span.xml_value})
25+
def __init__(self, life_span: LifeSpan | str) -> None:
26+
xml_value = (
27+
life_span.xml_value if isinstance(life_span, LifeSpan) else life_span
28+
)
29+
super().__init__({"type": xml_value})
2530

2631
@classmethod
2732
def _handle_xml(cls, event_bus: EventBus, xml: Element) -> HandlingResult:
@@ -47,3 +52,24 @@ def _handle_xml(cls, event_bus: EventBus, xml: Element) -> HandlingResult:
4752
LifeSpanEvent(LifeSpan.from_xml(component_type), percent, left)
4853
)
4954
return HandlingResult.success()
55+
56+
57+
class ResetLifeSpan(ExecuteCommand, XmlCommandMqttP2P):
58+
"""ResetLifeSpan command."""
59+
60+
NAME = "ResetLifeSpan"
61+
_mqtt_params = MappingProxyType({"type": InitParam(LifeSpan, "life_span")})
62+
63+
def __init__(self, life_span: LifeSpan | str) -> None:
64+
xml_value = (
65+
life_span.xml_value if isinstance(life_span, LifeSpan) else life_span
66+
)
67+
super().__init__({"type": xml_value})
68+
69+
def _handle_mqtt_p2p(
70+
self, event_bus: EventBus, response: dict[str, Any] | str
71+
) -> None:
72+
"""Handle response received over the mqtt channel "p2p"."""
73+
result = self.handle(event_bus, response)
74+
if result.state == HandlingState.SUCCESS:
75+
event_bus.request_refresh(LifeSpanEvent)

tests/commands/xml/test_life_span.py

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
11
from __future__ import annotations
22

3+
from typing import TYPE_CHECKING
4+
from unittest.mock import patch
5+
36
import pytest
47

58
from deebot_client.command import CommandResult
6-
from deebot_client.commands.xml import GetLifeSpan
9+
from deebot_client.commands.xml import GetLifeSpan, ResetLifeSpan
710
from deebot_client.events import LifeSpan, LifeSpanEvent
811
from deebot_client.message import HandlingState
912
from tests.commands import assert_command
1013

11-
from . import get_request_xml
14+
from . import (
15+
assert_execute_command,
16+
get_failure_body,
17+
get_request_xml,
18+
get_success_body,
19+
)
20+
21+
if TYPE_CHECKING:
22+
from deebot_client.event_bus import EventBus
1223

1324

1425
@pytest.mark.parametrize(
1526
("component_type", "lifespan_type", "left", "total", "expected_event"),
1627
[
1728
("Brush", LifeSpan.BRUSH, 50, 100, LifeSpanEvent(LifeSpan.BRUSH, 50, 50)),
29+
(
30+
"Brush",
31+
LifeSpan.BRUSH.xml_value,
32+
50,
33+
100,
34+
LifeSpanEvent(LifeSpan.BRUSH, 50, 50),
35+
),
1836
(
1937
"DustCaseHeap",
2038
LifeSpan.DUST_CASE_HEAP,
@@ -33,15 +51,15 @@
3351
)
3452
async def test_get_life_span(
3553
component_type: str,
36-
lifespan_type: LifeSpan,
54+
lifespan_type: LifeSpan | str,
3755
left: int,
3856
total: int,
3957
expected_event: LifeSpanEvent,
4058
) -> None:
41-
json = get_request_xml(
59+
xml = get_request_xml(
4260
f"<ctl ret='ok' type='{component_type}' left='{left}' total='{total}'/>"
4361
)
44-
await assert_command(GetLifeSpan(lifespan_type), json, expected_event)
62+
await assert_command(GetLifeSpan(lifespan_type), xml, expected_event)
4563

4664

4765
@pytest.mark.parametrize(
@@ -57,3 +75,42 @@ async def test_get_life_span_error(xml: str) -> None:
5775
None,
5876
command_result=CommandResult(HandlingState.ANALYSE_LOGGED),
5977
)
78+
79+
80+
@pytest.mark.parametrize(
81+
("command", "args"),
82+
[
83+
(ResetLifeSpan(LifeSpan.FILTER), {"type": LifeSpan.FILTER.xml_value}),
84+
(ResetLifeSpan(LifeSpan.FILTER.xml_value), {"type": LifeSpan.FILTER.xml_value}),
85+
(
86+
ResetLifeSpan.create_from_mqtt(b'<ctl type="Brush" />'),
87+
{"type": LifeSpan.BRUSH.xml_value},
88+
),
89+
],
90+
)
91+
async def test_ResetLifeSpan(command: ResetLifeSpan, args: dict[str, str]) -> None:
92+
await assert_execute_command(command, args)
93+
94+
95+
def test_ResetLifeSpan_invokes_refresh(event_bus: EventBus) -> None:
96+
command = ResetLifeSpan(LifeSpan.FILTER)
97+
success_response = get_success_body()
98+
99+
with patch.object(
100+
event_bus, "request_refresh", return_value=None
101+
) as mock_request_refresh:
102+
command.handle_mqtt_p2p(event_bus, success_response)
103+
104+
mock_request_refresh.assert_called_with(LifeSpanEvent)
105+
106+
107+
def test_ResetLifeSpan_not_invokes_refresh(event_bus: EventBus) -> None:
108+
command = ResetLifeSpan(LifeSpan.FILTER)
109+
failure_response = get_failure_body()
110+
111+
with patch.object(
112+
event_bus, "request_refresh", return_value=None
113+
) as mock_request_refresh:
114+
command.handle_mqtt_p2p(event_bus, failure_response)
115+
116+
mock_request_refresh.assert_not_called()

0 commit comments

Comments
 (0)