Skip to content

Commit 64c4b78

Browse files
committed
Add initial support for Goat A1600 RTK (#852)
1 parent 5830188 commit 64c4b78

5 files changed

Lines changed: 238 additions & 0 deletions

File tree

deebot_client/commands/json/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from . import auto_empty, station_action, station_state
88
from .advanced_mode import GetAdvancedMode, SetAdvancedMode
9+
from .auto_cut_direction import GetAutoCutDirection, SetAutoCutDirection
910
from .battery import GetBattery
1011
from .border_switch import GetBorderSwitch, SetBorderSwitch
1112
from .carpet import GetCarpetAutoFanBoost, SetCarpetAutoFanBoost
@@ -39,6 +40,7 @@
3940
from .ota import GetOta, SetOta
4041
from .play_sound import PlaySound
4142
from .pos import GetPos
43+
from .rain_delay import GetRainDelay, SetRainDelay
4244
from .relocation import SetRelocationState
4345
from .safe_protect import GetSafeProtect, SetSafeProtect
4446
from .stats import GetStats, GetTotalStats
@@ -61,6 +63,7 @@
6163
"CleanV2",
6264
"ClearMap",
6365
"GetAdvancedMode",
66+
"GetAutoCutDirection",
6467
"GetBattery",
6568
"GetBorderSwitch",
6669
"GetCachedMapInfo",
@@ -91,6 +94,7 @@
9194
"GetNetInfoLegacy",
9295
"GetOta",
9396
"GetPos",
97+
"GetRainDelay",
9498
"GetSafeProtect",
9599
"GetStats",
96100
"GetSweepMode",
@@ -103,6 +107,7 @@
103107
"PlaySound",
104108
"ResetLifeSpan",
105109
"SetAdvancedMode",
110+
"SetAutoCutDirection",
106111
"SetBorderSwitch",
107112
"SetCarpetAutoFanBoost",
108113
"SetChildLock",
@@ -116,6 +121,7 @@
116121
"SetMoveUpWarning",
117122
"SetMultimapState",
118123
"SetOta",
124+
"SetRainDelay",
119125
"SetRelocationState",
120126
"SetSafeProtect",
121127
"SetSweepMode",
@@ -132,6 +138,9 @@
132138
GetAdvancedMode,
133139
SetAdvancedMode,
134140

141+
GetAutoCutDirection,
142+
SetAutoCutDirection,
143+
135144
auto_empty.GetAutoEmpty,
136145
auto_empty.SetAutoEmpty,
137146

@@ -208,6 +217,9 @@
208217

209218
GetPos,
210219

220+
GetRainDelay,
221+
SetRainDelay,
222+
211223
SetRelocationState,
212224

213225
GetSafeProtect,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Auto cut direction command module."""
2+
3+
from __future__ import annotations
4+
5+
from deebot_client.events import AutoCutDirectionEvent
6+
7+
from .common import GetEnableCommand, SetEnableCommand
8+
9+
10+
class GetAutoCutDirection(GetEnableCommand):
11+
"""Get auto cut direction command."""
12+
13+
NAME = "getAutoCutDirection"
14+
EVENT_TYPE = AutoCutDirectionEvent
15+
16+
17+
class SetAutoCutDirection(SetEnableCommand):
18+
"""Set auto cut direction command."""
19+
20+
NAME = "setAutoCutDirection"
21+
get_command = GetAutoCutDirection
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""Rain delay module."""
2+
3+
from __future__ import annotations
4+
5+
from types import MappingProxyType
6+
from typing import TYPE_CHECKING, Any
7+
8+
from deebot_client.command import InitParam
9+
from deebot_client.events import RainDelayEvent
10+
from deebot_client.message import HandlingResult
11+
12+
from .common import JsonGetCommand, JsonSetCommand
13+
14+
if TYPE_CHECKING:
15+
from deebot_client.event_bus import EventBus
16+
17+
18+
class GetRainDelay(JsonGetCommand):
19+
"""Get cut direction command."""
20+
21+
NAME = "getRainDelay"
22+
23+
@classmethod
24+
def _handle_body_data_dict(
25+
cls, event_bus: EventBus, data: dict[str, Any]
26+
) -> HandlingResult:
27+
"""Handle message->body->data and notify the correct event subscribers.
28+
29+
:return: A message response
30+
"""
31+
event_bus.notify(RainDelayEvent(enable=data["enable"], delay=data["delay"]))
32+
return HandlingResult.success()
33+
34+
35+
class SetRainDelay(JsonSetCommand):
36+
"""Set rain delay command."""
37+
38+
NAME = "setRainDelay"
39+
get_command = GetRainDelay
40+
_mqtt_params = MappingProxyType(
41+
{"enable": InitParam(bool), "delay": InitParam(int)}
42+
)
43+
44+
def __init__(self, enable: bool, delay: int) -> None:
45+
super().__init__({"enable": enable, "delay": delay})

deebot_client/events/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
__all__ = [
3636
"AutoEmptyEvent",
37+
"AutoCutDirectionEvent",
3738
"BatteryEvent",
3839
"CachedMapInfoEvent",
3940
"CleanJobStatus",
@@ -54,6 +55,7 @@
5455
"NetworkInfoEvent",
5556
"Position",
5657
"PositionsEvent",
58+
"RainDelayEvent",
5759
"StationEvent",
5860
"SweepModeEvent",
5961
"WorkMode",
@@ -236,6 +238,11 @@ class AdvancedModeEvent(EnableEvent):
236238
"""Advanced mode event."""
237239

238240

241+
@dataclass(frozen=True)
242+
class AutoCutDirectionEvent(EnableEvent):
243+
"""Auto cut direction event."""
244+
245+
239246
@dataclass(frozen=True)
240247
class ContinuousCleaningEvent(EnableEvent):
241248
"""Continuous cleaning event."""
@@ -308,3 +315,11 @@ class FirmwareEvent(Event):
308315
"""Firmware event."""
309316

310317
version: str
318+
319+
320+
@dataclass(frozen=True)
321+
class RainDelayEvent(Event):
322+
"""Rain delay event representation."""
323+
324+
enable: bool
325+
delay: int
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
"""DEEBOT GOAT A1600 RTK Capabilities."""
2+
3+
from __future__ import annotations
4+
5+
from deebot_client.capabilities import (
6+
Capabilities,
7+
CapabilityClean,
8+
CapabilityCleanAction,
9+
CapabilityCustomCommand,
10+
CapabilityEvent,
11+
CapabilityExecute,
12+
CapabilityLifeSpan,
13+
CapabilitySet,
14+
CapabilitySetEnable,
15+
CapabilitySettings,
16+
CapabilityStats,
17+
DeviceType,
18+
)
19+
from deebot_client.commands.json import (
20+
GetBorderSwitch,
21+
GetChildLock,
22+
GetCrossMapBorderWarning,
23+
GetCutDirection,
24+
GetMoveUpWarning,
25+
GetSafeProtect,
26+
SetBorderSwitch,
27+
SetChildLock,
28+
SetCrossMapBorderWarning,
29+
SetCutDirection,
30+
SetMoveUpWarning,
31+
SetSafeProtect,
32+
)
33+
from deebot_client.commands.json.advanced_mode import GetAdvancedMode, SetAdvancedMode
34+
from deebot_client.commands.json.auto_cut_direction import (
35+
GetAutoCutDirection,
36+
SetAutoCutDirection,
37+
)
38+
from deebot_client.commands.json.battery import GetBattery
39+
from deebot_client.commands.json.charge import Charge
40+
from deebot_client.commands.json.charge_state import GetChargeState
41+
from deebot_client.commands.json.clean import CleanV2, GetCleanInfoV2
42+
from deebot_client.commands.json.custom import CustomCommand
43+
from deebot_client.commands.json.error import GetError
44+
from deebot_client.commands.json.life_span import GetLifeSpan, ResetLifeSpan
45+
from deebot_client.commands.json.network import GetNetInfo
46+
from deebot_client.commands.json.play_sound import PlaySound
47+
from deebot_client.commands.json.rain_delay import GetRainDelay, SetRainDelay
48+
from deebot_client.commands.json.stats import GetStats, GetTotalStats
49+
from deebot_client.commands.json.true_detect import GetTrueDetect, SetTrueDetect
50+
from deebot_client.commands.json.volume import GetVolume, SetVolume
51+
from deebot_client.const import DataType
52+
from deebot_client.events import (
53+
AdvancedModeEvent,
54+
AutoCutDirectionEvent,
55+
AvailabilityEvent,
56+
BatteryEvent,
57+
BorderSwitchEvent,
58+
ChildLockEvent,
59+
CrossMapBorderWarningEvent,
60+
CustomCommandEvent,
61+
CutDirectionEvent,
62+
ErrorEvent,
63+
LifeSpan,
64+
LifeSpanEvent,
65+
MoveUpWarningEvent,
66+
NetworkInfoEvent,
67+
RainDelayEvent,
68+
ReportStatsEvent,
69+
SafeProtectEvent,
70+
StateEvent,
71+
StatsEvent,
72+
TotalStatsEvent,
73+
TrueDetectEvent,
74+
VolumeEvent,
75+
)
76+
from deebot_client.models import StaticDeviceInfo
77+
from deebot_client.util import short_name
78+
79+
from . import DEVICES
80+
81+
DEVICES[short_name(__name__)] = StaticDeviceInfo(
82+
DataType.JSON,
83+
Capabilities(
84+
device_type=DeviceType.MOWER,
85+
availability=CapabilityEvent(
86+
AvailabilityEvent, [GetBattery(is_available_check=True)]
87+
),
88+
battery=CapabilityEvent(BatteryEvent, [GetBattery()]),
89+
charge=CapabilityExecute(Charge),
90+
clean=CapabilityClean(
91+
action=CapabilityCleanAction(command=CleanV2),
92+
),
93+
custom=CapabilityCustomCommand(
94+
event=CustomCommandEvent, get=[], set=CustomCommand
95+
),
96+
error=CapabilityEvent(ErrorEvent, [GetError()]),
97+
life_span=CapabilityLifeSpan(
98+
types=(LifeSpan.BLADE),
99+
event=LifeSpanEvent,
100+
get=[GetLifeSpan([LifeSpan.BLADE])],
101+
reset=ResetLifeSpan,
102+
),
103+
network=CapabilityEvent(NetworkInfoEvent, [GetNetInfo()]),
104+
play_sound=CapabilityExecute(PlaySound),
105+
settings=CapabilitySettings(
106+
advanced_mode=CapabilitySetEnable(
107+
AdvancedModeEvent, [GetAdvancedMode()], SetAdvancedMode
108+
),
109+
auto_cut_direction=CapabilitySetEnable(
110+
AutoCutDirectionEvent, [GetAutoCutDirection()], SetAutoCutDirection
111+
),
112+
border_switch=CapabilitySetEnable(
113+
BorderSwitchEvent, [GetBorderSwitch()], SetBorderSwitch
114+
),
115+
cut_direction=CapabilitySet(
116+
CutDirectionEvent, [GetCutDirection()], SetCutDirection
117+
),
118+
child_lock=CapabilitySetEnable(
119+
ChildLockEvent, [GetChildLock()], SetChildLock
120+
),
121+
moveup_warning=CapabilitySetEnable(
122+
MoveUpWarningEvent, [GetMoveUpWarning()], SetMoveUpWarning
123+
),
124+
cross_map_border_warning=CapabilitySetEnable(
125+
CrossMapBorderWarningEvent,
126+
[GetCrossMapBorderWarning()],
127+
SetCrossMapBorderWarning,
128+
),
129+
rain_delay=CapabilitySet(RainDelayEvent, [GetRainDelay()], SetRainDelay),
130+
safe_protect=CapabilitySetEnable(
131+
SafeProtectEvent, [GetSafeProtect()], SetSafeProtect
132+
),
133+
true_detect=CapabilitySetEnable(
134+
TrueDetectEvent, [GetTrueDetect()], SetTrueDetect
135+
),
136+
volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume),
137+
),
138+
state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfoV2()]),
139+
stats=CapabilityStats(
140+
clean=CapabilityEvent(StatsEvent, [GetStats()]),
141+
report=CapabilityEvent(ReportStatsEvent, []),
142+
total=CapabilityEvent(TotalStatsEvent, [GetTotalStats()]),
143+
),
144+
),
145+
)

0 commit comments

Comments
 (0)