roborock.data.zeo.zeo_containers

Data containers for Zeo (washing machine / dryer) devices.

  1"""Data containers for Zeo (washing machine / dryer) devices."""
  2
  3from dataclasses import dataclass
  4
  5from ..containers import RoborockBase
  6from .zeo_code_mappings import (
  7    ZeoDryAndCare,
  8    ZeoDryingMethod,
  9    ZeoDryingMode,
 10    ZeoMode,
 11    ZeoProgram,
 12    ZeoRinse,
 13    ZeoSoak,
 14    ZeoSpin,
 15    ZeoSteamVolume,
 16    ZeoTemperature,
 17)
 18
 19
 20@dataclass
 21class ZeoStartParams(RoborockBase):
 22    """Parameters that must be bundled with a START command.
 23
 24    All Zeo devices require ``mode`` and ``program`` to be sent together
 25    with the start signal. The remaining fields are optional and only
 26    included when the device reports a non-None value.
 27    """
 28
 29    mode: ZeoMode
 30    program: ZeoProgram
 31    temperature: ZeoTemperature | None = None
 32    rinse: ZeoRinse | None = None
 33    spin: ZeoSpin | None = None
 34    drying_mode: ZeoDryingMode | None = None
 35
 36
 37# ── DP 222 (LoadCloudProgram) bitfield decoder ──────────────────────────
 38# The official app packs all custom-program parameters into a single
 39# 32-bit integer at DP 222.  This mirrors WasherDpsCache.customMode in
 40# module 725 of the React Native plugin bundle.
 41
 42
 43@dataclass
 44class ZeoCustomMode(RoborockBase):
 45    """Decoded custom programme parameters from DP 222 (LoadCloudProgram).
 46
 47    Null / absent fields are represented as ``0`` which matches the
 48    official app's behaviour (the right-shifted-and-masked value is
 49    always non-negative).
 50    """
 51
 52    program: ZeoProgram
 53    """Wash program (bits 0-7)."""
 54
 55    mode: ZeoMode
 56    """Wash mode (bits 8-9)."""
 57
 58    temperature: ZeoTemperature
 59    """Temperature (bits 10-12)."""
 60
 61    rinse: ZeoRinse
 62    """Rinse cycle (bits 13-15)."""
 63
 64    spin: ZeoSpin
 65    """Spin speed (bits 16-18)."""
 66
 67    drying_mode: ZeoDryingMode
 68    """Drying mode (bits 19-21)."""
 69
 70    soak: ZeoSoak
 71    """Soak (bits 22-24)."""
 72
 73    dry_and_care: ZeoDryAndCare
 74    """Dry-care mode (bits 25-27)."""
 75
 76    steam_volume: ZeoSteamVolume
 77    """Steam volume (bits 28-30)."""
 78
 79    total_time_min: int = 0
 80    """Total programme time in minutes (from DP 239)."""
 81
 82    @classmethod
 83    def from_raw(cls, raw: int, total_time_min: int | None = None) -> "ZeoCustomMode":
 84        """Decode a raw 32-bit custom-programme value."""
 85        return cls(
 86            program=ZeoProgram(raw & 0xFF),
 87            mode=ZeoMode((raw >> 8) & 0x3),
 88            temperature=ZeoTemperature((raw >> 10) & 0x7),
 89            rinse=ZeoRinse((raw >> 13) & 0x7),
 90            spin=ZeoSpin((raw >> 16) & 0x7),
 91            drying_mode=ZeoDryingMode((raw >> 19) & 0x7),
 92            soak=ZeoSoak((raw >> 22) & 0x7),
 93            dry_and_care=ZeoDryAndCare((raw >> 25) & 0x7),
 94            steam_volume=ZeoSteamVolume((raw >> 28) & 0x7),
 95            total_time_min=total_time_min or 0,
 96        )
 97
 98
 99@dataclass
100class ZeoDryerCustomMode(RoborockBase):
101    """Decoded custom programme from DP 222 for a standalone dryer.
102
103    Dryers pack a different (shorter) bitfield than washers — only 5
104    fields after program/mode.  Mirrors ``WasherDpsCache.dryerCustomMode``
105    in module 725 of the plugin bundle.
106    """
107
108    program: ZeoProgram
109    """Drying program (bits 0-7)."""
110
111    mode: ZeoMode
112    """Drying mode (bits 8-10)."""
113
114    drying_mode: ZeoDryingMode
115    """Drying level (bits 11-13)."""
116
117    drying_method: ZeoDryingMethod
118    """Drying method (bits 14-16)."""
119
120    steam_volume: ZeoSteamVolume
121    """Steam volume (bits 17-19)."""
122
123    total_time_min: int = 0
124    """Total programme time in minutes (from DP 239)."""
125
126    @classmethod
127    def from_raw(cls, raw: int, total_time_min: int | None = None) -> "ZeoDryerCustomMode":
128        """Decode a raw 32-bit dryer custom-programme value."""
129        return cls(
130            program=ZeoProgram(raw & 0xFF),
131            # Dryer mode spans bits 8-10 (0x700, 3 bits) because the
132            # temperature field is absent from the dryer bitfield and
133            # bit 10 is re-allocated to mode.  Washer uses 2 bits
134            # (0x300, bits 8-9) to make room for temperature at 10-12.
135            mode=ZeoMode((raw >> 8) & 0x7),
136            drying_mode=ZeoDryingMode((raw >> 11) & 0x7),
137            drying_method=ZeoDryingMethod((raw >> 14) & 0x7),
138            steam_volume=ZeoSteamVolume((raw >> 17) & 0x7),
139            total_time_min=total_time_min or 0,
140        )
@dataclass
class ZeoStartParams(roborock.data.containers.RoborockBase):
21@dataclass
22class ZeoStartParams(RoborockBase):
23    """Parameters that must be bundled with a START command.
24
25    All Zeo devices require ``mode`` and ``program`` to be sent together
26    with the start signal. The remaining fields are optional and only
27    included when the device reports a non-None value.
28    """
29
30    mode: ZeoMode
31    program: ZeoProgram
32    temperature: ZeoTemperature | None = None
33    rinse: ZeoRinse | None = None
34    spin: ZeoSpin | None = None
35    drying_mode: ZeoDryingMode | None = None

Parameters that must be bundled with a START command.

All Zeo devices require mode and program to be sent together with the start signal. The remaining fields are optional and only included when the device reports a non-None value.

@dataclass
class ZeoCustomMode(roborock.data.containers.RoborockBase):
44@dataclass
45class ZeoCustomMode(RoborockBase):
46    """Decoded custom programme parameters from DP 222 (LoadCloudProgram).
47
48    Null / absent fields are represented as ``0`` which matches the
49    official app's behaviour (the right-shifted-and-masked value is
50    always non-negative).
51    """
52
53    program: ZeoProgram
54    """Wash program (bits 0-7)."""
55
56    mode: ZeoMode
57    """Wash mode (bits 8-9)."""
58
59    temperature: ZeoTemperature
60    """Temperature (bits 10-12)."""
61
62    rinse: ZeoRinse
63    """Rinse cycle (bits 13-15)."""
64
65    spin: ZeoSpin
66    """Spin speed (bits 16-18)."""
67
68    drying_mode: ZeoDryingMode
69    """Drying mode (bits 19-21)."""
70
71    soak: ZeoSoak
72    """Soak (bits 22-24)."""
73
74    dry_and_care: ZeoDryAndCare
75    """Dry-care mode (bits 25-27)."""
76
77    steam_volume: ZeoSteamVolume
78    """Steam volume (bits 28-30)."""
79
80    total_time_min: int = 0
81    """Total programme time in minutes (from DP 239)."""
82
83    @classmethod
84    def from_raw(cls, raw: int, total_time_min: int | None = None) -> "ZeoCustomMode":
85        """Decode a raw 32-bit custom-programme value."""
86        return cls(
87            program=ZeoProgram(raw & 0xFF),
88            mode=ZeoMode((raw >> 8) & 0x3),
89            temperature=ZeoTemperature((raw >> 10) & 0x7),
90            rinse=ZeoRinse((raw >> 13) & 0x7),
91            spin=ZeoSpin((raw >> 16) & 0x7),
92            drying_mode=ZeoDryingMode((raw >> 19) & 0x7),
93            soak=ZeoSoak((raw >> 22) & 0x7),
94            dry_and_care=ZeoDryAndCare((raw >> 25) & 0x7),
95            steam_volume=ZeoSteamVolume((raw >> 28) & 0x7),
96            total_time_min=total_time_min or 0,
97        )

Decoded custom programme parameters from DP 222 (LoadCloudProgram).

Null / absent fields are represented as 0 which matches the official app's behaviour (the right-shifted-and-masked value is always non-negative).

Wash program (bits 0-7).

Wash mode (bits 8-9).

Temperature (bits 10-12).

Rinse cycle (bits 13-15).

Spin speed (bits 16-18).

Drying mode (bits 19-21).

Dry-care mode (bits 25-27).

Steam volume (bits 28-30).

total_time_min: int = 0

Total programme time in minutes (from DP 239).

@classmethod
def from_raw( cls, raw: int, total_time_min: int | None = None) -> ZeoCustomMode:
83    @classmethod
84    def from_raw(cls, raw: int, total_time_min: int | None = None) -> "ZeoCustomMode":
85        """Decode a raw 32-bit custom-programme value."""
86        return cls(
87            program=ZeoProgram(raw & 0xFF),
88            mode=ZeoMode((raw >> 8) & 0x3),
89            temperature=ZeoTemperature((raw >> 10) & 0x7),
90            rinse=ZeoRinse((raw >> 13) & 0x7),
91            spin=ZeoSpin((raw >> 16) & 0x7),
92            drying_mode=ZeoDryingMode((raw >> 19) & 0x7),
93            soak=ZeoSoak((raw >> 22) & 0x7),
94            dry_and_care=ZeoDryAndCare((raw >> 25) & 0x7),
95            steam_volume=ZeoSteamVolume((raw >> 28) & 0x7),
96            total_time_min=total_time_min or 0,
97        )

Decode a raw 32-bit custom-programme value.

@dataclass
class ZeoDryerCustomMode(roborock.data.containers.RoborockBase):
100@dataclass
101class ZeoDryerCustomMode(RoborockBase):
102    """Decoded custom programme from DP 222 for a standalone dryer.
103
104    Dryers pack a different (shorter) bitfield than washers — only 5
105    fields after program/mode.  Mirrors ``WasherDpsCache.dryerCustomMode``
106    in module 725 of the plugin bundle.
107    """
108
109    program: ZeoProgram
110    """Drying program (bits 0-7)."""
111
112    mode: ZeoMode
113    """Drying mode (bits 8-10)."""
114
115    drying_mode: ZeoDryingMode
116    """Drying level (bits 11-13)."""
117
118    drying_method: ZeoDryingMethod
119    """Drying method (bits 14-16)."""
120
121    steam_volume: ZeoSteamVolume
122    """Steam volume (bits 17-19)."""
123
124    total_time_min: int = 0
125    """Total programme time in minutes (from DP 239)."""
126
127    @classmethod
128    def from_raw(cls, raw: int, total_time_min: int | None = None) -> "ZeoDryerCustomMode":
129        """Decode a raw 32-bit dryer custom-programme value."""
130        return cls(
131            program=ZeoProgram(raw & 0xFF),
132            # Dryer mode spans bits 8-10 (0x700, 3 bits) because the
133            # temperature field is absent from the dryer bitfield and
134            # bit 10 is re-allocated to mode.  Washer uses 2 bits
135            # (0x300, bits 8-9) to make room for temperature at 10-12.
136            mode=ZeoMode((raw >> 8) & 0x7),
137            drying_mode=ZeoDryingMode((raw >> 11) & 0x7),
138            drying_method=ZeoDryingMethod((raw >> 14) & 0x7),
139            steam_volume=ZeoSteamVolume((raw >> 17) & 0x7),
140            total_time_min=total_time_min or 0,
141        )

Decoded custom programme from DP 222 for a standalone dryer.

Dryers pack a different (shorter) bitfield than washers — only 5 fields after program/mode. Mirrors WasherDpsCache.dryerCustomMode in module 725 of the plugin bundle.

Drying program (bits 0-7).

Drying mode (bits 8-10).

Drying level (bits 11-13).

Drying method (bits 14-16).

Steam volume (bits 17-19).

total_time_min: int = 0

Total programme time in minutes (from DP 239).

@classmethod
def from_raw( cls, raw: int, total_time_min: int | None = None) -> ZeoDryerCustomMode:
127    @classmethod
128    def from_raw(cls, raw: int, total_time_min: int | None = None) -> "ZeoDryerCustomMode":
129        """Decode a raw 32-bit dryer custom-programme value."""
130        return cls(
131            program=ZeoProgram(raw & 0xFF),
132            # Dryer mode spans bits 8-10 (0x700, 3 bits) because the
133            # temperature field is absent from the dryer bitfield and
134            # bit 10 is re-allocated to mode.  Washer uses 2 bits
135            # (0x300, bits 8-9) to make room for temperature at 10-12.
136            mode=ZeoMode((raw >> 8) & 0x7),
137            drying_mode=ZeoDryingMode((raw >> 11) & 0x7),
138            drying_method=ZeoDryingMethod((raw >> 14) & 0x7),
139            steam_volume=ZeoSteamVolume((raw >> 17) & 0x7),
140            total_time_min=total_time_min or 0,
141        )

Decode a raw 32-bit dryer custom-programme value.