Skip to content

Commit

Permalink
Add auto empty message and commands (#603)
Browse files Browse the repository at this point in the history
  • Loading branch information
edenhaus authored Dec 20, 2024
1 parent 3ed2a37 commit dc55832
Show file tree
Hide file tree
Showing 15 changed files with 537 additions and 19 deletions.
55 changes: 40 additions & 15 deletions deebot_client/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from dataclasses import dataclass, field, fields, is_dataclass
from enum import StrEnum
from types import MappingProxyType
from typing import TYPE_CHECKING, Any, Generic, TypeVar
from typing import TYPE_CHECKING, Any, Generic, ParamSpec, TypeVar

from deebot_client.events import (
AdvancedModeEvent,
Expand Down Expand Up @@ -51,20 +51,23 @@
WaterInfoEvent,
WorkMode,
WorkModeEvent,
auto_empty,
)

if TYPE_CHECKING:
from collections.abc import Callable

from _typeshed import DataclassInstance

from deebot_client.command import Command, SetCommand
from deebot_client.command import Command
from deebot_client.commands.json.common import ExecuteCommand
from deebot_client.events.efficiency_mode import EfficiencyMode, EfficiencyModeEvent
from deebot_client.models import CleanAction, CleanMode


_T = TypeVar("_T")
_EVENT = TypeVar("_EVENT", bound=Event)
_P = ParamSpec("_P")


def _get_events(
Expand Down Expand Up @@ -92,14 +95,14 @@ class CapabilityEvent(Generic[_EVENT]):


@dataclass(frozen=True)
class CapabilitySet(CapabilityEvent[_EVENT], Generic[_EVENT, _T]):
class CapabilitySet(CapabilityEvent[_EVENT], Generic[_EVENT, _P]):
"""Capability setCommand with event."""

set: Callable[[_T], SetCommand]
set: Callable[_P, ExecuteCommand]


@dataclass(frozen=True)
class CapabilitySetEnable(CapabilitySet[_EVENT, bool]):
class CapabilitySetEnable(CapabilitySet[_EVENT, [bool]]):
"""Capability for SetEnableCommand with event."""


Expand All @@ -118,7 +121,7 @@ class CapabilityTypes(Generic[_T]):


@dataclass(frozen=True, kw_only=True)
class CapabilitySetTypes(CapabilitySet[_EVENT, _T | str], CapabilityTypes[_T]):
class CapabilitySetTypes(CapabilitySet[_EVENT, _P], CapabilityTypes[_T]):
"""Capability for set command and types."""


Expand All @@ -136,10 +139,12 @@ class CapabilityClean:

action: CapabilityCleanAction
continuous: CapabilitySetEnable[ContinuousCleaningEvent] | None = None
count: CapabilitySet[CleanCountEvent, int] | None = None
count: CapabilitySet[CleanCountEvent, [int]] | None = None
log: CapabilityEvent[CleanLogEvent] | None = None
preference: CapabilitySetEnable[CleanPreferenceEvent] | None = None
work_mode: CapabilitySetTypes[WorkModeEvent, WorkMode] | None = None
work_mode: CapabilitySetTypes[WorkModeEvent, [WorkMode | str], WorkMode] | None = (
None
)


@dataclass(frozen=True)
Expand Down Expand Up @@ -186,12 +191,13 @@ class CapabilitySettings:

advanced_mode: CapabilitySetEnable[AdvancedModeEvent] | None = None
carpet_auto_fan_boost: CapabilitySetEnable[CarpetAutoFanBoostEvent] | None = None
efficiency_mode: CapabilitySetTypes[EfficiencyModeEvent, EfficiencyMode] | None = (
None
)
efficiency_mode: (
CapabilitySetTypes[EfficiencyModeEvent, [EfficiencyMode | str], EfficiencyMode]
| None
) = None
border_switch: CapabilitySetEnable[BorderSwitchEvent] | None = None
child_lock: CapabilitySetEnable[ChildLockEvent] | None = None
cut_direction: CapabilitySet[CutDirectionEvent, int] | None = None
cut_direction: CapabilitySet[CutDirectionEvent, [int]] | None = None
moveup_warning: CapabilitySetEnable[MoveUpWarningEvent] | None = None
cross_map_border_warning: CapabilitySetEnable[CrossMapBorderWarningEvent] | None = (
None
Expand All @@ -201,7 +207,21 @@ class CapabilitySettings:
sweep_mode: CapabilitySetEnable[SweepModeEvent] | None = None
true_detect: CapabilitySetEnable[TrueDetectEvent] | None = None
voice_assistant: CapabilitySetEnable[VoiceAssistantStateEvent] | None = None
volume: CapabilitySet[VolumeEvent, int]
volume: CapabilitySet[VolumeEvent, [int]]


@dataclass(frozen=True, kw_only=True)
class CapabilityStation:
"""Capabilities for station."""

auto_empty: (
CapabilitySetTypes[
auto_empty.AutoEmptyEvent,
[bool | None, auto_empty.Frequency | str | None],
auto_empty.Frequency,
]
| None
) = None


@dataclass(frozen=True, kw_only=True)
Expand All @@ -216,15 +236,20 @@ class Capabilities(ABC):
clean: CapabilityClean
custom: CapabilityCustomCommand[CustomCommandEvent]
error: CapabilityEvent[ErrorEvent]
fan_speed: CapabilitySetTypes[FanSpeedEvent, FanSpeedLevel] | None = None
fan_speed: (
CapabilitySetTypes[FanSpeedEvent, [FanSpeedLevel | str], FanSpeedLevel] | None
) = None
life_span: CapabilityLifeSpan
map: CapabilityMap | None = None
network: CapabilityEvent[NetworkInfoEvent]
play_sound: CapabilityExecute
settings: CapabilitySettings
state: CapabilityEvent[StateEvent]
station: CapabilityStation = field(default_factory=CapabilityStation)
stats: CapabilityStats
water: CapabilitySetTypes[WaterInfoEvent, WaterAmount] | None = None
water: (
CapabilitySetTypes[WaterInfoEvent, [WaterAmount | str], WaterAmount] | None
) = None

_events: MappingProxyType[type[Event], list[Command]] = field(init=False)

Expand Down
4 changes: 4 additions & 0 deletions deebot_client/commands/json/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from deebot_client.command import Command, CommandMqttP2P

from . import auto_empty
from .advanced_mode import GetAdvancedMode, SetAdvancedMode
from .battery import GetBattery
from .border_switch import GetBorderSwitch, SetBorderSwitch
Expand Down Expand Up @@ -130,6 +131,9 @@
GetAdvancedMode,
SetAdvancedMode,

auto_empty.GetAutoEmpty,
auto_empty.SetAutoEmpty,

GetBorderSwitch,
SetBorderSwitch,

Expand Down
36 changes: 36 additions & 0 deletions deebot_client/commands/json/auto_empty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Auto empty commands."""

from __future__ import annotations

from typing import Any

from deebot_client.events.auto_empty import Frequency
from deebot_client.messages.json.auto_empty import OnAutoEmpty
from deebot_client.util import get_enum

from .common import ExecuteCommand, JsonGetCommand


class GetAutoEmpty(OnAutoEmpty, JsonGetCommand):
"""Get auto empty command."""

NAME = "getAutoEmpty"


class SetAutoEmpty(ExecuteCommand):
"""Set auto empty command."""

NAME = "setAutoEmpty"

def __init__(
self, enable: bool | None = None, frequency: Frequency | str | None = None
) -> None:
if frequency is not None and not isinstance(frequency, Frequency):
frequency = get_enum(Frequency, frequency)

params: dict[str, Any] = {}
if enable is not None:
params["enable"] = int(enable)
if frequency:
params["frequency"] = frequency.value
super().__init__(params)
2 changes: 1 addition & 1 deletion deebot_client/commands/json/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,5 @@ def __init_subclass__(cls, **kwargs: Any) -> None:
cls._mqtt_params = MappingProxyType({cls._field_name: InitParam(bool, _ENABLE)})
super().__init_subclass__(**kwargs)

def __init__(self, enable: bool) -> None: # noqa: FBT001
def __init__(self, enable: bool) -> None:
super().__init__({self._field_name: 1 if enable else 0})
2 changes: 1 addition & 1 deletion deebot_client/commands/json/ota.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ class SetOta(JsonSetCommand):

_mqtt_params = MappingProxyType({"autoSwitch": InitParam(bool, "auto_enabled")})

def __init__(self, auto_enabled: bool) -> None: # noqa: FBT001
def __init__(self, auto_enabled: bool) -> None:
super().__init__({"autoSwitch": 1 if auto_enabled else 0})
4 changes: 4 additions & 0 deletions deebot_client/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from deebot_client.events.base import Event

from . import auto_empty
from .auto_empty import AutoEmptyEvent
from .efficiency_mode import EfficiencyMode, EfficiencyModeEvent
from .fan_speed import FanSpeedEvent, FanSpeedLevel
from .map import (
Expand All @@ -31,6 +33,7 @@
from deebot_client.models import Room, State

__all__ = [
"AutoEmptyEvent",
"BatteryEvent",
"CachedMapInfoEvent",
"CleanJobStatus",
Expand All @@ -57,6 +60,7 @@
"WaterInfoEvent",
"WorkMode",
"WorkModeEvent",
"auto_empty",
]


Expand Down
29 changes: 29 additions & 0 deletions deebot_client/events/auto_empty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Auto empty event module."""

from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum, unique

from .base import Event as _Event

__all__ = ["AutoEmptyEvent", "Frequency"]


@unique
class Frequency(StrEnum):
"""Enum class for all possible frequencies."""

MIN_10 = "10"
MIN_15 = "15"
MIN_25 = "25"
AUTO = "auto"
SMART = "smart"


@dataclass(frozen=True)
class AutoEmptyEvent(_Event):
"""Auto empty event representation."""

enabled: bool
frequency: Frequency | None = None
16 changes: 16 additions & 0 deletions deebot_client/hardware/deebot/p95mgv.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
CapabilitySetEnable,
CapabilitySettings,
CapabilitySetTypes,
CapabilityStation,
CapabilityStats,
DeviceType,
)
from deebot_client.commands.json.advanced_mode import GetAdvancedMode, SetAdvancedMode
from deebot_client.commands.json.auto_empty import GetAutoEmpty, SetAutoEmpty
from deebot_client.commands.json.battery import GetBattery
from deebot_client.commands.json.carpet import (
GetCarpetAutoFanBoost,
Expand Down Expand Up @@ -97,6 +99,7 @@
VolumeEvent,
WaterAmount,
WaterInfoEvent,
auto_empty,
)
from deebot_client.events.efficiency_mode import EfficiencyMode
from deebot_client.models import StaticDeviceInfo
Expand Down Expand Up @@ -206,6 +209,19 @@
volume=CapabilitySet(VolumeEvent, [GetVolume()], SetVolume),
),
state=CapabilityEvent(StateEvent, [GetChargeState(), GetCleanInfo()]),
station=CapabilityStation(
auto_empty=CapabilitySetTypes(
event=auto_empty.AutoEmptyEvent,
get=[GetAutoEmpty()],
set=SetAutoEmpty,
types=(
auto_empty.Frequency.MIN_10,
auto_empty.Frequency.MIN_15,
auto_empty.Frequency.MIN_25,
auto_empty.Frequency.AUTO,
),
),
),
stats=CapabilityStats(
clean=CapabilityEvent(StatsEvent, [GetStats()]),
report=CapabilityEvent(ReportStatsEvent, []),
Expand Down
1 change: 0 additions & 1 deletion deebot_client/hardware/deebot/qhe2o2.py

This file was deleted.

Loading

0 comments on commit dc55832

Please sign in to comment.