From 64c4b7809d63e551b5e5f0bcab8b9862c8b297ee Mon Sep 17 00:00:00 2001 From: Joerg Zimmermann Date: Tue, 6 May 2025 18:18:35 +0200 Subject: [PATCH 1/3] Add initial support for Goat A1600 RTK (#852) --- deebot_client/commands/json/__init__.py | 12 ++ .../commands/json/auto_cut_direction.py | 21 +++ deebot_client/commands/json/rain_delay.py | 45 ++++++ deebot_client/events/__init__.py | 15 ++ deebot_client/hardware/deebot/xmp9ds.py | 145 ++++++++++++++++++ 5 files changed, 238 insertions(+) create mode 100644 deebot_client/commands/json/auto_cut_direction.py create mode 100644 deebot_client/commands/json/rain_delay.py create mode 100644 deebot_client/hardware/deebot/xmp9ds.py diff --git a/deebot_client/commands/json/__init__.py b/deebot_client/commands/json/__init__.py index 6f1db25f1..4bddf663a 100644 --- a/deebot_client/commands/json/__init__.py +++ b/deebot_client/commands/json/__init__.py @@ -6,6 +6,7 @@ from . import auto_empty, station_action, station_state from .advanced_mode import GetAdvancedMode, SetAdvancedMode +from .auto_cut_direction import GetAutoCutDirection, SetAutoCutDirection from .battery import GetBattery from .border_switch import GetBorderSwitch, SetBorderSwitch from .carpet import GetCarpetAutoFanBoost, SetCarpetAutoFanBoost @@ -39,6 +40,7 @@ from .ota import GetOta, SetOta from .play_sound import PlaySound from .pos import GetPos +from .rain_delay import GetRainDelay, SetRainDelay from .relocation import SetRelocationState from .safe_protect import GetSafeProtect, SetSafeProtect from .stats import GetStats, GetTotalStats @@ -61,6 +63,7 @@ "CleanV2", "ClearMap", "GetAdvancedMode", + "GetAutoCutDirection", "GetBattery", "GetBorderSwitch", "GetCachedMapInfo", @@ -91,6 +94,7 @@ "GetNetInfoLegacy", "GetOta", "GetPos", + "GetRainDelay", "GetSafeProtect", "GetStats", "GetSweepMode", @@ -103,6 +107,7 @@ "PlaySound", "ResetLifeSpan", "SetAdvancedMode", + "SetAutoCutDirection", "SetBorderSwitch", "SetCarpetAutoFanBoost", "SetChildLock", @@ -116,6 +121,7 @@ "SetMoveUpWarning", "SetMultimapState", "SetOta", + "SetRainDelay", "SetRelocationState", "SetSafeProtect", "SetSweepMode", @@ -132,6 +138,9 @@ GetAdvancedMode, SetAdvancedMode, + GetAutoCutDirection, + SetAutoCutDirection, + auto_empty.GetAutoEmpty, auto_empty.SetAutoEmpty, @@ -208,6 +217,9 @@ GetPos, + GetRainDelay, + SetRainDelay, + SetRelocationState, GetSafeProtect, diff --git a/deebot_client/commands/json/auto_cut_direction.py b/deebot_client/commands/json/auto_cut_direction.py new file mode 100644 index 000000000..c4e01d9bc --- /dev/null +++ b/deebot_client/commands/json/auto_cut_direction.py @@ -0,0 +1,21 @@ +"""Auto cut direction command module.""" + +from __future__ import annotations + +from deebot_client.events import AutoCutDirectionEvent + +from .common import GetEnableCommand, SetEnableCommand + + +class GetAutoCutDirection(GetEnableCommand): + """Get auto cut direction command.""" + + NAME = "getAutoCutDirection" + EVENT_TYPE = AutoCutDirectionEvent + + +class SetAutoCutDirection(SetEnableCommand): + """Set auto cut direction command.""" + + NAME = "setAutoCutDirection" + get_command = GetAutoCutDirection diff --git a/deebot_client/commands/json/rain_delay.py b/deebot_client/commands/json/rain_delay.py new file mode 100644 index 000000000..e17d947c7 --- /dev/null +++ b/deebot_client/commands/json/rain_delay.py @@ -0,0 +1,45 @@ +"""Rain delay module.""" + +from __future__ import annotations + +from types import MappingProxyType +from typing import TYPE_CHECKING, Any + +from deebot_client.command import InitParam +from deebot_client.events import RainDelayEvent +from deebot_client.message import HandlingResult + +from .common import JsonGetCommand, JsonSetCommand + +if TYPE_CHECKING: + from deebot_client.event_bus import EventBus + + +class GetRainDelay(JsonGetCommand): + """Get cut direction command.""" + + NAME = "getRainDelay" + + @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(RainDelayEvent(enable=data["enable"], delay=data["delay"])) + return HandlingResult.success() + + +class SetRainDelay(JsonSetCommand): + """Set rain delay command.""" + + NAME = "setRainDelay" + get_command = GetRainDelay + _mqtt_params = MappingProxyType( + {"enable": InitParam(bool), "delay": InitParam(int)} + ) + + def __init__(self, enable: bool, delay: int) -> None: + super().__init__({"enable": enable, "delay": delay}) diff --git a/deebot_client/events/__init__.py b/deebot_client/events/__init__.py index a1b44e363..51680bfbc 100644 --- a/deebot_client/events/__init__.py +++ b/deebot_client/events/__init__.py @@ -34,6 +34,7 @@ __all__ = [ "AutoEmptyEvent", + "AutoCutDirectionEvent", "BatteryEvent", "CachedMapInfoEvent", "CleanJobStatus", @@ -54,6 +55,7 @@ "NetworkInfoEvent", "Position", "PositionsEvent", + "RainDelayEvent", "StationEvent", "SweepModeEvent", "WorkMode", @@ -236,6 +238,11 @@ class AdvancedModeEvent(EnableEvent): """Advanced mode event.""" +@dataclass(frozen=True) +class AutoCutDirectionEvent(EnableEvent): + """Auto cut direction event.""" + + @dataclass(frozen=True) class ContinuousCleaningEvent(EnableEvent): """Continuous cleaning event.""" @@ -308,3 +315,11 @@ class FirmwareEvent(Event): """Firmware event.""" version: str + + +@dataclass(frozen=True) +class RainDelayEvent(Event): + """Rain delay event representation.""" + + enable: bool + delay: int diff --git a/deebot_client/hardware/deebot/xmp9ds.py b/deebot_client/hardware/deebot/xmp9ds.py new file mode 100644 index 000000000..d0087e71b --- /dev/null +++ b/deebot_client/hardware/deebot/xmp9ds.py @@ -0,0 +1,145 @@ +"""DEEBOT GOAT A1600 RTK Capabilities.""" + +from __future__ import annotations + +from deebot_client.capabilities import ( + Capabilities, + CapabilityClean, + CapabilityCleanAction, + CapabilityCustomCommand, + CapabilityEvent, + CapabilityExecute, + CapabilityLifeSpan, + CapabilitySet, + CapabilitySetEnable, + CapabilitySettings, + CapabilityStats, + DeviceType, +) +from deebot_client.commands.json import ( + GetBorderSwitch, + GetChildLock, + GetCrossMapBorderWarning, + GetCutDirection, + GetMoveUpWarning, + GetSafeProtect, + SetBorderSwitch, + SetChildLock, + SetCrossMapBorderWarning, + SetCutDirection, + SetMoveUpWarning, + SetSafeProtect, +) +from deebot_client.commands.json.advanced_mode import GetAdvancedMode, SetAdvancedMode +from deebot_client.commands.json.auto_cut_direction import ( + GetAutoCutDirection, + SetAutoCutDirection, +) +from deebot_client.commands.json.battery import GetBattery +from deebot_client.commands.json.charge import Charge +from deebot_client.commands.json.charge_state import GetChargeState +from deebot_client.commands.json.clean import CleanV2, GetCleanInfoV2 +from deebot_client.commands.json.custom import CustomCommand +from deebot_client.commands.json.error import GetError +from deebot_client.commands.json.life_span import GetLifeSpan, ResetLifeSpan +from deebot_client.commands.json.network import GetNetInfo +from deebot_client.commands.json.play_sound import PlaySound +from deebot_client.commands.json.rain_delay import GetRainDelay, SetRainDelay +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.const import DataType +from deebot_client.events import ( + AdvancedModeEvent, + AutoCutDirectionEvent, + AvailabilityEvent, + BatteryEvent, + BorderSwitchEvent, + ChildLockEvent, + CrossMapBorderWarningEvent, + CustomCommandEvent, + CutDirectionEvent, + ErrorEvent, + LifeSpan, + LifeSpanEvent, + MoveUpWarningEvent, + NetworkInfoEvent, + RainDelayEvent, + ReportStatsEvent, + SafeProtectEvent, + StateEvent, + StatsEvent, + TotalStatsEvent, + TrueDetectEvent, + VolumeEvent, +) +from deebot_client.models import StaticDeviceInfo +from deebot_client.util import short_name + +from . import DEVICES + +DEVICES[short_name(__name__)] = StaticDeviceInfo( + DataType.JSON, + Capabilities( + device_type=DeviceType.MOWER, + availability=CapabilityEvent( + AvailabilityEvent, [GetBattery(is_available_check=True)] + ), + battery=CapabilityEvent(BatteryEvent, [GetBattery()]), + charge=CapabilityExecute(Charge), + clean=CapabilityClean( + action=CapabilityCleanAction(command=CleanV2), + ), + custom=CapabilityCustomCommand( + event=CustomCommandEvent, get=[], set=CustomCommand + ), + error=CapabilityEvent(ErrorEvent, [GetError()]), + life_span=CapabilityLifeSpan( + types=(LifeSpan.BLADE), + event=LifeSpanEvent, + get=[GetLifeSpan([LifeSpan.BLADE])], + reset=ResetLifeSpan, + ), + network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]), + play_sound=CapabilityExecute(PlaySound), + settings=CapabilitySettings( + advanced_mode=CapabilitySetEnable( + AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode + ), + auto_cut_direction=CapabilitySetEnable( + AutoCutDirectionEvent, [GetAutoCutDirection()], SetAutoCutDirection + ), + border_switch=CapabilitySetEnable( + BorderSwitchEvent, [GetBorderSwitch()], SetBorderSwitch + ), + cut_direction=CapabilitySet( + CutDirectionEvent, [GetCutDirection()], SetCutDirection + ), + child_lock=CapabilitySetEnable( + ChildLockEvent, [GetChildLock()], SetChildLock + ), + moveup_warning=CapabilitySetEnable( + MoveUpWarningEvent, [GetMoveUpWarning()], SetMoveUpWarning + ), + cross_map_border_warning=CapabilitySetEnable( + CrossMapBorderWarningEvent, + [GetCrossMapBorderWarning()], + SetCrossMapBorderWarning, + ), + rain_delay=CapabilitySet(RainDelayEvent, [GetRainDelay()], SetRainDelay), + safe_protect=CapabilitySetEnable( + SafeProtectEvent, [GetSafeProtect()], SetSafeProtect + ), + true_detect=CapabilitySetEnable( + TrueDetectEvent, [GetTrueDetect()], SetTrueDetect + ), + volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume), + ), + state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfoV2()]), + stats=CapabilityStats( + clean=CapabilityEvent(StatsEvent, [GetStats()]), + report=CapabilityEvent(ReportStatsEvent, []), + total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), + ), + ), +) From bfbf286bf398b40f858e84d5d1431376d47c9820 Mon Sep 17 00:00:00 2001 From: Joerg Zimmermann Date: Sun, 11 May 2025 20:12:17 +0200 Subject: [PATCH 2/3] Revert "Add initial support for Goat A1600 RTK (#852)" This reverts commit 64c4b7809d63e551b5e5f0bcab8b9862c8b297ee. --- deebot_client/commands/json/__init__.py | 12 -- .../commands/json/auto_cut_direction.py | 21 --- deebot_client/commands/json/rain_delay.py | 45 ------ deebot_client/events/__init__.py | 15 -- deebot_client/hardware/deebot/xmp9ds.py | 145 ------------------ 5 files changed, 238 deletions(-) delete mode 100644 deebot_client/commands/json/auto_cut_direction.py delete mode 100644 deebot_client/commands/json/rain_delay.py delete mode 100644 deebot_client/hardware/deebot/xmp9ds.py diff --git a/deebot_client/commands/json/__init__.py b/deebot_client/commands/json/__init__.py index 4bddf663a..6f1db25f1 100644 --- a/deebot_client/commands/json/__init__.py +++ b/deebot_client/commands/json/__init__.py @@ -6,7 +6,6 @@ from . import auto_empty, station_action, station_state from .advanced_mode import GetAdvancedMode, SetAdvancedMode -from .auto_cut_direction import GetAutoCutDirection, SetAutoCutDirection from .battery import GetBattery from .border_switch import GetBorderSwitch, SetBorderSwitch from .carpet import GetCarpetAutoFanBoost, SetCarpetAutoFanBoost @@ -40,7 +39,6 @@ from .ota import GetOta, SetOta from .play_sound import PlaySound from .pos import GetPos -from .rain_delay import GetRainDelay, SetRainDelay from .relocation import SetRelocationState from .safe_protect import GetSafeProtect, SetSafeProtect from .stats import GetStats, GetTotalStats @@ -63,7 +61,6 @@ "CleanV2", "ClearMap", "GetAdvancedMode", - "GetAutoCutDirection", "GetBattery", "GetBorderSwitch", "GetCachedMapInfo", @@ -94,7 +91,6 @@ "GetNetInfoLegacy", "GetOta", "GetPos", - "GetRainDelay", "GetSafeProtect", "GetStats", "GetSweepMode", @@ -107,7 +103,6 @@ "PlaySound", "ResetLifeSpan", "SetAdvancedMode", - "SetAutoCutDirection", "SetBorderSwitch", "SetCarpetAutoFanBoost", "SetChildLock", @@ -121,7 +116,6 @@ "SetMoveUpWarning", "SetMultimapState", "SetOta", - "SetRainDelay", "SetRelocationState", "SetSafeProtect", "SetSweepMode", @@ -138,9 +132,6 @@ GetAdvancedMode, SetAdvancedMode, - GetAutoCutDirection, - SetAutoCutDirection, - auto_empty.GetAutoEmpty, auto_empty.SetAutoEmpty, @@ -217,9 +208,6 @@ GetPos, - GetRainDelay, - SetRainDelay, - SetRelocationState, GetSafeProtect, diff --git a/deebot_client/commands/json/auto_cut_direction.py b/deebot_client/commands/json/auto_cut_direction.py deleted file mode 100644 index c4e01d9bc..000000000 --- a/deebot_client/commands/json/auto_cut_direction.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Auto cut direction command module.""" - -from __future__ import annotations - -from deebot_client.events import AutoCutDirectionEvent - -from .common import GetEnableCommand, SetEnableCommand - - -class GetAutoCutDirection(GetEnableCommand): - """Get auto cut direction command.""" - - NAME = "getAutoCutDirection" - EVENT_TYPE = AutoCutDirectionEvent - - -class SetAutoCutDirection(SetEnableCommand): - """Set auto cut direction command.""" - - NAME = "setAutoCutDirection" - get_command = GetAutoCutDirection diff --git a/deebot_client/commands/json/rain_delay.py b/deebot_client/commands/json/rain_delay.py deleted file mode 100644 index e17d947c7..000000000 --- a/deebot_client/commands/json/rain_delay.py +++ /dev/null @@ -1,45 +0,0 @@ -"""Rain delay module.""" - -from __future__ import annotations - -from types import MappingProxyType -from typing import TYPE_CHECKING, Any - -from deebot_client.command import InitParam -from deebot_client.events import RainDelayEvent -from deebot_client.message import HandlingResult - -from .common import JsonGetCommand, JsonSetCommand - -if TYPE_CHECKING: - from deebot_client.event_bus import EventBus - - -class GetRainDelay(JsonGetCommand): - """Get cut direction command.""" - - NAME = "getRainDelay" - - @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(RainDelayEvent(enable=data["enable"], delay=data["delay"])) - return HandlingResult.success() - - -class SetRainDelay(JsonSetCommand): - """Set rain delay command.""" - - NAME = "setRainDelay" - get_command = GetRainDelay - _mqtt_params = MappingProxyType( - {"enable": InitParam(bool), "delay": InitParam(int)} - ) - - def __init__(self, enable: bool, delay: int) -> None: - super().__init__({"enable": enable, "delay": delay}) diff --git a/deebot_client/events/__init__.py b/deebot_client/events/__init__.py index 51680bfbc..a1b44e363 100644 --- a/deebot_client/events/__init__.py +++ b/deebot_client/events/__init__.py @@ -34,7 +34,6 @@ __all__ = [ "AutoEmptyEvent", - "AutoCutDirectionEvent", "BatteryEvent", "CachedMapInfoEvent", "CleanJobStatus", @@ -55,7 +54,6 @@ "NetworkInfoEvent", "Position", "PositionsEvent", - "RainDelayEvent", "StationEvent", "SweepModeEvent", "WorkMode", @@ -238,11 +236,6 @@ class AdvancedModeEvent(EnableEvent): """Advanced mode event.""" -@dataclass(frozen=True) -class AutoCutDirectionEvent(EnableEvent): - """Auto cut direction event.""" - - @dataclass(frozen=True) class ContinuousCleaningEvent(EnableEvent): """Continuous cleaning event.""" @@ -315,11 +308,3 @@ class FirmwareEvent(Event): """Firmware event.""" version: str - - -@dataclass(frozen=True) -class RainDelayEvent(Event): - """Rain delay event representation.""" - - enable: bool - delay: int diff --git a/deebot_client/hardware/deebot/xmp9ds.py b/deebot_client/hardware/deebot/xmp9ds.py deleted file mode 100644 index d0087e71b..000000000 --- a/deebot_client/hardware/deebot/xmp9ds.py +++ /dev/null @@ -1,145 +0,0 @@ -"""DEEBOT GOAT A1600 RTK Capabilities.""" - -from __future__ import annotations - -from deebot_client.capabilities import ( - Capabilities, - CapabilityClean, - CapabilityCleanAction, - CapabilityCustomCommand, - CapabilityEvent, - CapabilityExecute, - CapabilityLifeSpan, - CapabilitySet, - CapabilitySetEnable, - CapabilitySettings, - CapabilityStats, - DeviceType, -) -from deebot_client.commands.json import ( - GetBorderSwitch, - GetChildLock, - GetCrossMapBorderWarning, - GetCutDirection, - GetMoveUpWarning, - GetSafeProtect, - SetBorderSwitch, - SetChildLock, - SetCrossMapBorderWarning, - SetCutDirection, - SetMoveUpWarning, - SetSafeProtect, -) -from deebot_client.commands.json.advanced_mode import GetAdvancedMode, SetAdvancedMode -from deebot_client.commands.json.auto_cut_direction import ( - GetAutoCutDirection, - SetAutoCutDirection, -) -from deebot_client.commands.json.battery import GetBattery -from deebot_client.commands.json.charge import Charge -from deebot_client.commands.json.charge_state import GetChargeState -from deebot_client.commands.json.clean import CleanV2, GetCleanInfoV2 -from deebot_client.commands.json.custom import CustomCommand -from deebot_client.commands.json.error import GetError -from deebot_client.commands.json.life_span import GetLifeSpan, ResetLifeSpan -from deebot_client.commands.json.network import GetNetInfo -from deebot_client.commands.json.play_sound import PlaySound -from deebot_client.commands.json.rain_delay import GetRainDelay, SetRainDelay -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.const import DataType -from deebot_client.events import ( - AdvancedModeEvent, - AutoCutDirectionEvent, - AvailabilityEvent, - BatteryEvent, - BorderSwitchEvent, - ChildLockEvent, - CrossMapBorderWarningEvent, - CustomCommandEvent, - CutDirectionEvent, - ErrorEvent, - LifeSpan, - LifeSpanEvent, - MoveUpWarningEvent, - NetworkInfoEvent, - RainDelayEvent, - ReportStatsEvent, - SafeProtectEvent, - StateEvent, - StatsEvent, - TotalStatsEvent, - TrueDetectEvent, - VolumeEvent, -) -from deebot_client.models import StaticDeviceInfo -from deebot_client.util import short_name - -from . import DEVICES - -DEVICES[short_name(__name__)] = StaticDeviceInfo( - DataType.JSON, - Capabilities( - device_type=DeviceType.MOWER, - availability=CapabilityEvent( - AvailabilityEvent, [GetBattery(is_available_check=True)] - ), - battery=CapabilityEvent(BatteryEvent, [GetBattery()]), - charge=CapabilityExecute(Charge), - clean=CapabilityClean( - action=CapabilityCleanAction(command=CleanV2), - ), - custom=CapabilityCustomCommand( - event=CustomCommandEvent, get=[], set=CustomCommand - ), - error=CapabilityEvent(ErrorEvent, [GetError()]), - life_span=CapabilityLifeSpan( - types=(LifeSpan.BLADE), - event=LifeSpanEvent, - get=[GetLifeSpan([LifeSpan.BLADE])], - reset=ResetLifeSpan, - ), - network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]), - play_sound=CapabilityExecute(PlaySound), - settings=CapabilitySettings( - advanced_mode=CapabilitySetEnable( - AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode - ), - auto_cut_direction=CapabilitySetEnable( - AutoCutDirectionEvent, [GetAutoCutDirection()], SetAutoCutDirection - ), - border_switch=CapabilitySetEnable( - BorderSwitchEvent, [GetBorderSwitch()], SetBorderSwitch - ), - cut_direction=CapabilitySet( - CutDirectionEvent, [GetCutDirection()], SetCutDirection - ), - child_lock=CapabilitySetEnable( - ChildLockEvent, [GetChildLock()], SetChildLock - ), - moveup_warning=CapabilitySetEnable( - MoveUpWarningEvent, [GetMoveUpWarning()], SetMoveUpWarning - ), - cross_map_border_warning=CapabilitySetEnable( - CrossMapBorderWarningEvent, - [GetCrossMapBorderWarning()], - SetCrossMapBorderWarning, - ), - rain_delay=CapabilitySet(RainDelayEvent, [GetRainDelay()], SetRainDelay), - safe_protect=CapabilitySetEnable( - SafeProtectEvent, [GetSafeProtect()], SetSafeProtect - ), - true_detect=CapabilitySetEnable( - TrueDetectEvent, [GetTrueDetect()], SetTrueDetect - ), - volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume), - ), - state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfoV2()]), - stats=CapabilityStats( - clean=CapabilityEvent(StatsEvent, [GetStats()]), - report=CapabilityEvent(ReportStatsEvent, []), - total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), - ), - ), -) From b84016fbee7474cee9fe072c42d073650ec42392 Mon Sep 17 00:00:00 2001 From: Joerg Zimmermann Date: Sun, 11 May 2025 20:13:37 +0200 Subject: [PATCH 3/3] Add initial support for Goat A1600 RTK (#852) --- deebot_client/hardware/deebot/xmp9ds.py | 141 ++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 deebot_client/hardware/deebot/xmp9ds.py diff --git a/deebot_client/hardware/deebot/xmp9ds.py b/deebot_client/hardware/deebot/xmp9ds.py new file mode 100644 index 000000000..6d8ab32ce --- /dev/null +++ b/deebot_client/hardware/deebot/xmp9ds.py @@ -0,0 +1,141 @@ +"""DEEBOT GOAT A1600 RTK Capabilities.""" + +from __future__ import annotations + +from deebot_client.capabilities import ( + Capabilities, + CapabilityClean, + CapabilityCleanAction, + CapabilityCustomCommand, + CapabilityEvent, + CapabilityExecute, + CapabilityLifeSpan, + CapabilitySet, + CapabilitySetEnable, + CapabilitySettings, + CapabilityStats, + DeviceType, +) +from deebot_client.commands.json import ( + GetBorderSwitch, + GetChildLock, + GetCrossMapBorderWarning, + GetCutDirection, + GetMoveUpWarning, + GetSafeProtect, + SetBorderSwitch, + SetChildLock, + SetCrossMapBorderWarning, + SetCutDirection, + SetMoveUpWarning, + SetSafeProtect, +) +from deebot_client.commands.json.advanced_mode import GetAdvancedMode, SetAdvancedMode +from deebot_client.commands.json.battery import GetBattery +from deebot_client.commands.json.charge import Charge +from deebot_client.commands.json.charge_state import GetChargeState +from deebot_client.commands.json.clean import CleanV2, GetCleanInfoV2 +from deebot_client.commands.json.custom import CustomCommand +from deebot_client.commands.json.error import GetError +from deebot_client.commands.json.life_span import GetLifeSpan, ResetLifeSpan +from deebot_client.commands.json.network import GetNetInfo +from deebot_client.commands.json.play_sound import PlaySound +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.const import DataType +from deebot_client.events import ( + AdvancedModeEvent, + AvailabilityEvent, + BatteryEvent, + BorderSwitchEvent, + ChildLockEvent, + CrossMapBorderWarningEvent, + CustomCommandEvent, + CutDirectionEvent, + ErrorEvent, + LifeSpan, + LifeSpanEvent, + MoveUpWarningEvent, + NetworkInfoEvent, + ReportStatsEvent, + SafeProtectEvent, + StateEvent, + StatsEvent, + TotalStatsEvent, + TrueDetectEvent, + VolumeEvent, +) +from deebot_client.models import StaticDeviceInfo +from deebot_client.util import short_name + +from . import DEVICES + +DEVICES[short_name(__name__)] = StaticDeviceInfo( + DataType.JSON, + Capabilities( + device_type=DeviceType.MOWER, + availability=CapabilityEvent( + AvailabilityEvent, [GetBattery(is_available_check=True)] + ), + battery=CapabilityEvent(BatteryEvent, [GetBattery()]), + charge=CapabilityExecute(Charge), + clean=CapabilityClean( + action=CapabilityCleanAction(command=CleanV2), + ), + custom=CapabilityCustomCommand( + event=CustomCommandEvent, get=[], set=CustomCommand + ), + error=CapabilityEvent(ErrorEvent, [GetError()]), + life_span=CapabilityLifeSpan( + types=(LifeSpan.BLADE, LifeSpan.LENS_BRUSH), + event=LifeSpanEvent, + get=[ + GetLifeSpan( + [ + LifeSpan.BLADE, + LifeSpan.LENS_BRUSH, + ] + ) + ], + reset=ResetLifeSpan, + ), + network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]), + play_sound=CapabilityExecute(PlaySound), + settings=CapabilitySettings( + advanced_mode=CapabilitySetEnable( + AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode + ), + border_switch=CapabilitySetEnable( + BorderSwitchEvent, [GetBorderSwitch()], SetBorderSwitch + ), + cut_direction=CapabilitySet( + CutDirectionEvent, [GetCutDirection()], SetCutDirection + ), + child_lock=CapabilitySetEnable( + ChildLockEvent, [GetChildLock()], SetChildLock + ), + moveup_warning=CapabilitySetEnable( + MoveUpWarningEvent, [GetMoveUpWarning()], SetMoveUpWarning + ), + cross_map_border_warning=CapabilitySetEnable( + CrossMapBorderWarningEvent, + [GetCrossMapBorderWarning()], + SetCrossMapBorderWarning, + ), + safe_protect=CapabilitySetEnable( + SafeProtectEvent, [GetSafeProtect()], SetSafeProtect + ), + true_detect=CapabilitySetEnable( + TrueDetectEvent, [GetTrueDetect()], SetTrueDetect + ), + volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume), + ), + state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfoV2()]), + stats=CapabilityStats( + clean=CapabilityEvent(StatsEvent, [GetStats()]), + report=CapabilityEvent(ReportStatsEvent, []), + total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]), + ), + ), +)