From 80f3bf59570fa378ee77b433d8ce5fe4d05428b9 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Thu, 24 Apr 2025 18:12:18 +0200 Subject: [PATCH 01/13] move to correct device --- deebot_client/hardware/deebot/659yh8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deebot_client/hardware/deebot/659yh8.py b/deebot_client/hardware/deebot/659yh8.py index ade0eb9b3..8e9a72f9a 120000 --- a/deebot_client/hardware/deebot/659yh8.py +++ b/deebot_client/hardware/deebot/659yh8.py @@ -1 +1 @@ -x5d34r.py \ No newline at end of file +8kwdb4.py \ No newline at end of file From 39298c9ea3eacd1996bd284c3fc0dcaaeb634191 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Thu, 24 Apr 2025 18:14:42 +0200 Subject: [PATCH 02/13] manage mqtt message onStats --- deebot_client/commands/json/stats.py | 12 ++++++++++++ deebot_client/hardware/deebot/8kwdb4.py | 4 ++-- deebot_client/messages/json/__init__.py | 5 ++++- deebot_client/messages/json/stats.py | 23 ++++++++++++++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/deebot_client/commands/json/stats.py b/deebot_client/commands/json/stats.py index 70a9cb3e2..98203a75d 100644 --- a/deebot_client/commands/json/stats.py +++ b/deebot_client/commands/json/stats.py @@ -6,6 +6,7 @@ from deebot_client.events import StatsEvent, TotalStatsEvent from deebot_client.message import HandlingResult, MessageBodyDataDict +from deebot_client.messages.json import OnStats from .common import JsonCommandWithMessageHandling @@ -51,3 +52,14 @@ def _handle_body_data_dict( stats_event = TotalStatsEvent(data["area"], data["time"], data["count"]) event_bus.notify(stats_event) return HandlingResult.success() + + +class GetOnStats(OnStats, JsonCommandWithMessageHandling): + """Get onStats command.""" + + NAME = "getOnStats" + + def __init__(self, *, is_available_check: bool = False) -> None: + super().__init__() + self._is_available_check = is_available_check + diff --git a/deebot_client/hardware/deebot/8kwdb4.py b/deebot_client/hardware/deebot/8kwdb4.py index c2ecdb414..513c41d8b 100644 --- a/deebot_client/hardware/deebot/8kwdb4.py +++ b/deebot_client/hardware/deebot/8kwdb4.py @@ -50,7 +50,7 @@ from deebot_client.commands.json.play_sound import PlaySound from deebot_client.commands.json.pos import GetPos from deebot_client.commands.json.relocation import SetRelocationState -from deebot_client.commands.json.stats import GetStats, GetTotalStats +from deebot_client.commands.json.stats import GetOnStats, GetTotalStats from deebot_client.commands.json.true_detect import GetTrueDetect, SetTrueDetect from deebot_client.commands.json.volume import GetVolume, SetVolume from deebot_client.commands.json.water_info import GetWaterInfo, SetWaterInfo @@ -179,7 +179,7 @@ ), state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfo()]), stats=CapabilityStats( - clean=CapabilityEvent(StatsEvent, [GetStats()]), + clean=CapabilityEvent(StatsEvent, [GetOnStats()]), report=CapabilityEvent(ReportStatsEvent, []), total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), ), diff --git a/deebot_client/messages/json/__init__.py b/deebot_client/messages/json/__init__.py index 6a916460f..24dc4174e 100644 --- a/deebot_client/messages/json/__init__.py +++ b/deebot_client/messages/json/__init__.py @@ -8,7 +8,7 @@ from .battery import OnBattery from .map import OnMapSetV2 from .station_state import OnStationState -from .stats import ReportStats +from .stats import ReportStats, OnStats if TYPE_CHECKING: from deebot_client.message import Message @@ -17,6 +17,7 @@ "OnBattery", "OnMapSetV2", "ReportStats", + "OnStats", ] # fmt: off @@ -30,6 +31,8 @@ OnStationState, + OnStats, + ReportStats, ] # fmt: on diff --git a/deebot_client/messages/json/stats.py b/deebot_client/messages/json/stats.py index a0c5e9829..23d7d5143 100644 --- a/deebot_client/messages/json/stats.py +++ b/deebot_client/messages/json/stats.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Any -from deebot_client.events import CleanJobStatus, ReportStatsEvent +from deebot_client.events import CleanJobStatus, ReportStatsEvent, StatsEvent from deebot_client.message import HandlingResult, MessageBodyDataDict if TYPE_CHECKING: @@ -40,3 +40,24 @@ def _handle_body_data_dict( ) event_bus.notify(stats_event) return HandlingResult.success() + + +class OnStats(MessageBodyDataDict): + """Get stats command.""" + + NAME = "onStats" + + @classmethod + def _handle_body_data_dict( + cls, event_bus: EventBus, data: dict[str, Any] + ) -> HandlingResult: + """Handle message->body->data and notify the correct event subscribers. + + :return: A message response + """ + event_bus.notify(StatsEvent( + area=data["area"], + time=data["time"], + type=data["type"] + )) + return HandlingResult.success() From c9db78cfe4878446c90a99169099bc61bca7afd0 Mon Sep 17 00:00:00 2001 From: Gabriele Pongelli Date: Sun, 27 Apr 2025 08:44:44 +0200 Subject: [PATCH 03/13] Suggested change deebot_client/messages/json/__init__.py Co-authored-by: Robert Resch --- deebot_client/messages/json/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/deebot_client/messages/json/__init__.py b/deebot_client/messages/json/__init__.py index 24dc4174e..41a11aa0a 100644 --- a/deebot_client/messages/json/__init__.py +++ b/deebot_client/messages/json/__init__.py @@ -32,7 +32,6 @@ OnStationState, OnStats, - ReportStats, ] # fmt: on From 0bd000ffa93452f918d8c7a64560a2ee812c87d8 Mon Sep 17 00:00:00 2001 From: Gabriele Pongelli Date: Sun, 27 Apr 2025 08:49:37 +0200 Subject: [PATCH 04/13] Commit suggestion on deebot_client/commands/json/stats.py Co-authored-by: Robert Resch --- deebot_client/commands/json/stats.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/deebot_client/commands/json/stats.py b/deebot_client/commands/json/stats.py index 98203a75d..421d38e79 100644 --- a/deebot_client/commands/json/stats.py +++ b/deebot_client/commands/json/stats.py @@ -59,7 +59,4 @@ class GetOnStats(OnStats, JsonCommandWithMessageHandling): NAME = "getOnStats" - def __init__(self, *, is_available_check: bool = False) -> None: - super().__init__() - self._is_available_check = is_available_check From 1db068ffa6c6ca4c70b94019fe3ef576db286488 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Mon, 28 Apr 2025 14:24:54 +0200 Subject: [PATCH 05/13] sort list --- deebot_client/messages/json/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deebot_client/messages/json/__init__.py b/deebot_client/messages/json/__init__.py index 41a11aa0a..f265ba88e 100644 --- a/deebot_client/messages/json/__init__.py +++ b/deebot_client/messages/json/__init__.py @@ -16,8 +16,8 @@ __all__ = [ "OnBattery", "OnMapSetV2", - "ReportStats", "OnStats", + "ReportStats", ] # fmt: off From 10463b694d969abf6d574bb948d3f1c33d9bd22d Mon Sep 17 00:00:00 2001 From: gpongelli Date: Mon, 28 Apr 2025 14:27:53 +0200 Subject: [PATCH 06/13] remove GetOnStats, statistics are managed via mqtt --- deebot_client/commands/json/stats.py | 9 --------- deebot_client/hardware/deebot/8kwdb4.py | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/deebot_client/commands/json/stats.py b/deebot_client/commands/json/stats.py index 421d38e79..70a9cb3e2 100644 --- a/deebot_client/commands/json/stats.py +++ b/deebot_client/commands/json/stats.py @@ -6,7 +6,6 @@ from deebot_client.events import StatsEvent, TotalStatsEvent from deebot_client.message import HandlingResult, MessageBodyDataDict -from deebot_client.messages.json import OnStats from .common import JsonCommandWithMessageHandling @@ -52,11 +51,3 @@ def _handle_body_data_dict( stats_event = TotalStatsEvent(data["area"], data["time"], data["count"]) event_bus.notify(stats_event) return HandlingResult.success() - - -class GetOnStats(OnStats, JsonCommandWithMessageHandling): - """Get onStats command.""" - - NAME = "getOnStats" - - diff --git a/deebot_client/hardware/deebot/8kwdb4.py b/deebot_client/hardware/deebot/8kwdb4.py index 513c41d8b..33ba962e2 100644 --- a/deebot_client/hardware/deebot/8kwdb4.py +++ b/deebot_client/hardware/deebot/8kwdb4.py @@ -50,7 +50,7 @@ from deebot_client.commands.json.play_sound import PlaySound from deebot_client.commands.json.pos import GetPos from deebot_client.commands.json.relocation import SetRelocationState -from deebot_client.commands.json.stats import GetOnStats, GetTotalStats +from deebot_client.commands.json.stats import GetTotalStats from deebot_client.commands.json.true_detect import GetTrueDetect, SetTrueDetect from deebot_client.commands.json.volume import GetVolume, SetVolume from deebot_client.commands.json.water_info import GetWaterInfo, SetWaterInfo @@ -179,7 +179,7 @@ ), state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfo()]), stats=CapabilityStats( - clean=CapabilityEvent(StatsEvent, [GetOnStats()]), + clean=CapabilityEvent(StatsEvent, []), report=CapabilityEvent(ReportStatsEvent, []), total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), ), From 4b5962a0e2a5961c87f623508b1fd2c28f691c46 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Mon, 28 Apr 2025 15:13:32 +0200 Subject: [PATCH 07/13] test for OnStats --- tests/messages/test_get_messages.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/messages/test_get_messages.py b/tests/messages/test_get_messages.py index 5db55670a..2fdf95a7a 100644 --- a/tests/messages/test_get_messages.py +++ b/tests/messages/test_get_messages.py @@ -8,6 +8,7 @@ from deebot_client.const import DataType from deebot_client.messages import get_message from deebot_client.messages.json.battery import OnBattery +from deebot_client.messages.json.stats import OnStats if TYPE_CHECKING: from deebot_client.message import Message @@ -19,6 +20,7 @@ ("onBattery", DataType.JSON, OnBattery), ("onBattery_V2", DataType.JSON, OnBattery), ("onError", DataType.JSON, GetError), + ("onStats", DataType.JSON, OnStats), ("GetCleanLogs", DataType.JSON, None), ("unknown", DataType.JSON, None), ("unknown", DataType.XML, None), From 2f8f34e0732cd00ead12aa52ebb6318775077a08 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Mon, 28 Apr 2025 15:36:25 +0200 Subject: [PATCH 08/13] add test_onStats test data comes from logs on gh issue; other fields are filtered out for now to not change StatsEvent dataclass. --- tests/messages/json/test_stats.py | 64 ++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/tests/messages/json/test_stats.py b/tests/messages/json/test_stats.py index e5b49b92b..5b776efb8 100644 --- a/tests/messages/json/test_stats.py +++ b/tests/messages/json/test_stats.py @@ -4,8 +4,8 @@ import pytest -from deebot_client.events import CleanJobStatus, ReportStatsEvent -from deebot_client.messages.json import ReportStats +from deebot_client.events import CleanJobStatus, ReportStatsEvent, StatsEvent +from deebot_client.messages.json import OnStats, ReportStats from tests.messages import assert_message @@ -61,3 +61,63 @@ def test_ReportStats(data: dict[str, Any], expected: ReportStatsEvent) -> None: } assert_message(ReportStats, data, expected) + + +@pytest.mark.parametrize( + ("data", "expected"), + [ + ( + { + "area":2, + "time":89, + "cid":"2002066096", + "start":"1744009746", + "type":"auto", + "enablePowerMop":1, + "powerMopType":2, + "aiopen":1, + "aitypes":[9], + "avoidCount":1 + }, + StatsEvent( + area=2, + time=89, + type="auto", + ), + ), + ( + { + "area": 50, + "time": 56289, + "cid": "2002066096", + "start": "1744009746", + "type": "auto", + "enablePowerMop": 1, + "powerMopType": 2, + "aiopen": 1, + "aitypes": [9], + "avoidCount": 1 + }, + + StatsEvent( + area=50, + time=56289, + type="auto", + ), + ), + ], +) +def test_onStats(data: dict[str, Any], expected: StatsEvent) -> None: + data = { + "header": { + "pri": 1, + "tzm": 480, + "ts": "1662017348913", + "ver": "0.0.1", + "fwVer": "1.8.2", + "hwVer": "0.1.1", + }, + "body": {"data": data}, + } + + assert_message(OnStats, data, expected) From 9cb19c417a914740f53f11d4164c9311c2864f37 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Mon, 28 Apr 2025 15:45:28 +0200 Subject: [PATCH 09/13] revert change --- deebot_client/hardware/deebot/8kwdb4.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deebot_client/hardware/deebot/8kwdb4.py b/deebot_client/hardware/deebot/8kwdb4.py index 33ba962e2..c2ecdb414 100644 --- a/deebot_client/hardware/deebot/8kwdb4.py +++ b/deebot_client/hardware/deebot/8kwdb4.py @@ -50,7 +50,7 @@ from deebot_client.commands.json.play_sound import PlaySound from deebot_client.commands.json.pos import GetPos from deebot_client.commands.json.relocation import SetRelocationState -from deebot_client.commands.json.stats import GetTotalStats +from deebot_client.commands.json.stats import GetStats, GetTotalStats from deebot_client.commands.json.true_detect import GetTrueDetect, SetTrueDetect from deebot_client.commands.json.volume import GetVolume, SetVolume from deebot_client.commands.json.water_info import GetWaterInfo, SetWaterInfo @@ -179,7 +179,7 @@ ), state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfo()]), stats=CapabilityStats( - clean=CapabilityEvent(StatsEvent, []), + clean=CapabilityEvent(StatsEvent, [GetStats()]), report=CapabilityEvent(ReportStatsEvent, []), total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), ), From dd31de58582706acaf21cd1009e35e9c9b7b58da Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:23:11 +0000 Subject: [PATCH 10/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- deebot_client/messages/json/__init__.py | 2 +- deebot_client/messages/json/stats.py | 8 +++----- tests/messages/json/test_stats.py | 23 +++++++++++------------ 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/deebot_client/messages/json/__init__.py b/deebot_client/messages/json/__init__.py index f265ba88e..a7e321b83 100644 --- a/deebot_client/messages/json/__init__.py +++ b/deebot_client/messages/json/__init__.py @@ -8,7 +8,7 @@ from .battery import OnBattery from .map import OnMapSetV2 from .station_state import OnStationState -from .stats import ReportStats, OnStats +from .stats import OnStats, ReportStats if TYPE_CHECKING: from deebot_client.message import Message diff --git a/deebot_client/messages/json/stats.py b/deebot_client/messages/json/stats.py index 23d7d5143..e3566f683 100644 --- a/deebot_client/messages/json/stats.py +++ b/deebot_client/messages/json/stats.py @@ -55,9 +55,7 @@ def _handle_body_data_dict( :return: A message response """ - event_bus.notify(StatsEvent( - area=data["area"], - time=data["time"], - type=data["type"] - )) + event_bus.notify( + StatsEvent(area=data["area"], time=data["time"], type=data["type"]) + ) return HandlingResult.success() diff --git a/tests/messages/json/test_stats.py b/tests/messages/json/test_stats.py index 5b776efb8..16fc7cc72 100644 --- a/tests/messages/json/test_stats.py +++ b/tests/messages/json/test_stats.py @@ -68,16 +68,16 @@ def test_ReportStats(data: dict[str, Any], expected: ReportStatsEvent) -> None: [ ( { - "area":2, - "time":89, - "cid":"2002066096", - "start":"1744009746", - "type":"auto", - "enablePowerMop":1, - "powerMopType":2, - "aiopen":1, - "aitypes":[9], - "avoidCount":1 + "area": 2, + "time": 89, + "cid": "2002066096", + "start": "1744009746", + "type": "auto", + "enablePowerMop": 1, + "powerMopType": 2, + "aiopen": 1, + "aitypes": [9], + "avoidCount": 1, }, StatsEvent( area=2, @@ -96,9 +96,8 @@ def test_ReportStats(data: dict[str, Any], expected: ReportStatsEvent) -> None: "powerMopType": 2, "aiopen": 1, "aitypes": [9], - "avoidCount": 1 + "avoidCount": 1, }, - StatsEvent( area=50, time=56289, From afc7a3dff56f3d039acde8cec39ce8d88643761c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 06:41:58 +0000 Subject: [PATCH 11/13] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/messages/json/test_stats.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/messages/json/test_stats.py b/tests/messages/json/test_stats.py index 42b6d23e3..6c7f88fe2 100644 --- a/tests/messages/json/test_stats.py +++ b/tests/messages/json/test_stats.py @@ -4,7 +4,12 @@ import pytest -from deebot_client.events import CleanJobStatus, FirmwareEvent, ReportStatsEvent, StatsEvent +from deebot_client.events import ( + CleanJobStatus, + FirmwareEvent, + ReportStatsEvent, + StatsEvent, +) from deebot_client.messages.json import OnStats, ReportStats from tests.messages import assert_message From 843188dbf36986906aa1c198e8db157e90a26a93 Mon Sep 17 00:00:00 2001 From: Robert Resch Date: Sat, 3 May 2025 17:30:09 +0000 Subject: [PATCH 12/13] Revert capabilities change --- deebot_client/hardware/deebot/659yh8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deebot_client/hardware/deebot/659yh8.py b/deebot_client/hardware/deebot/659yh8.py index 8e9a72f9a..ade0eb9b3 120000 --- a/deebot_client/hardware/deebot/659yh8.py +++ b/deebot_client/hardware/deebot/659yh8.py @@ -1 +1 @@ -8kwdb4.py \ No newline at end of file +x5d34r.py \ No newline at end of file From 0e882ca877c997e5d3f3eabac80e3b8488d7df7d Mon Sep 17 00:00:00 2001 From: Robert Resch Date: Sat, 3 May 2025 17:31:29 +0000 Subject: [PATCH 13/13] Fix test --- tests/messages/json/test_stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/messages/json/test_stats.py b/tests/messages/json/test_stats.py index 6c7f88fe2..95609fdae 100644 --- a/tests/messages/json/test_stats.py +++ b/tests/messages/json/test_stats.py @@ -124,4 +124,4 @@ def test_onStats(data: dict[str, Any], expected: StatsEvent) -> None: "body": {"data": data}, } - assert_message(OnStats, data, expected) + assert_message(OnStats, data, (FirmwareEvent("1.8.2"), expected))