|
46 | 46 | ClearWaterBoxStatus, |
47 | 47 | DirtyWaterBoxStatus, |
48 | 48 | DustBagStatus, |
| 49 | + RoborockChargeStatus, |
49 | 50 | RoborockCleanType, |
50 | 51 | RoborockDockDustCollectionModeCode, |
51 | 52 | RoborockDockErrorCode, |
| 53 | + RoborockDockState, |
52 | 54 | RoborockDockTypeCode, |
53 | 55 | RoborockErrorCode, |
54 | 56 | RoborockFanPowerCode, |
@@ -98,13 +100,14 @@ class FieldNameBase(StrEnum): |
98 | 100 |
|
99 | 101 |
|
100 | 102 | class StatusField(FieldNameBase): |
101 | | - """An enum that represents a field in the `Status` class. |
| 103 | + """An enum that represents a field in the `StatusV2` class. |
102 | 104 |
|
103 | 105 | This is used with `roborock.devices.traits.v1.status.DeviceFeaturesTrait` |
104 | 106 | to understand if a feature is supported by the device using `is_field_supported`. |
105 | 107 |
|
106 | | - The enum values are names of fields in the `Status` class. Each field is annotated |
107 | | - with a metadata value to determine if the field is supported by the device. |
| 108 | + The enum values are names of fields in the `StatusV2` class. Each field is |
| 109 | + annotated with `dps` metadata to map the field to a `RoborockDataProtocol` |
| 110 | + value used to check support against the product schema. |
108 | 111 | """ |
109 | 112 |
|
110 | 113 | STATE = "state" |
@@ -161,7 +164,9 @@ class Status(RoborockBase): |
161 | 164 | collision_avoid_status: int | None = None |
162 | 165 | switch_map_mode: int | None = None |
163 | 166 | dock_error_status: RoborockDockErrorCode | None = None |
164 | | - charge_status: int | None = field(default=None, metadata={"dps": RoborockDataProtocol.CHARGE_STATUS}) |
| 167 | + charge_status: RoborockChargeStatus | None = field( |
| 168 | + default=None, metadata={"dps": RoborockDataProtocol.CHARGE_STATUS} |
| 169 | + ) |
165 | 170 | unsave_map_reason: int | None = None |
166 | 171 | unsave_map_flag: int | None = None |
167 | 172 | wash_status: int | None = None |
@@ -329,7 +334,9 @@ class StatusV2(RoborockBase): |
329 | 334 | collision_avoid_status: int | None = None |
330 | 335 | switch_map_mode: int | None = None |
331 | 336 | dock_error_status: RoborockDockErrorCode | None = None |
332 | | - charge_status: int | None = field(default=None, metadata={"dps": RoborockDataProtocol.CHARGE_STATUS}) |
| 337 | + charge_status: RoborockChargeStatus | None = field( |
| 338 | + default=None, metadata={"dps": RoborockDataProtocol.CHARGE_STATUS} |
| 339 | + ) |
333 | 340 | unsave_map_reason: int | None = None |
334 | 341 | unsave_map_flag: int | None = None |
335 | 342 | wash_status: int | None = None |
@@ -414,6 +421,41 @@ def dock_cool_fan_status(self) -> int | None: |
414 | 421 | return (self.dss >> 15) & 3 |
415 | 422 | return None |
416 | 423 |
|
| 424 | + @property |
| 425 | + def dock_state(self) -> RoborockDockState: |
| 426 | + """A synthesized, high-level dock state reflecting the UI's display. |
| 427 | +
|
| 428 | + This property simplifies integration by handling the complex logic |
| 429 | + of checking state, charge_status, and battery level simultaneously. It handles |
| 430 | + newer off-peak charging logic seamlessly while maintaining backwards compatibility |
| 431 | + with older devices. |
| 432 | + """ |
| 433 | + if self.state is None or self.state == RoborockStateCode.unknown: |
| 434 | + return RoborockDockState.unknown |
| 435 | + |
| 436 | + # 6. DUSTING |
| 437 | + if self.state == RoborockStateCode.emptying_the_bin: |
| 438 | + return RoborockDockState.dusting |
| 439 | + |
| 440 | + # 5. FULL |
| 441 | + if self.state == RoborockStateCode.charging_complete or ( |
| 442 | + self.state == RoborockStateCode.charging and self.battery == 100 |
| 443 | + ): |
| 444 | + return RoborockDockState.full |
| 445 | + |
| 446 | + # 3 & 4. CHARGING and CHARGE_WAITING |
| 447 | + if self.state == RoborockStateCode.charging: |
| 448 | + if self.charge_status == RoborockChargeStatus.charge_waiting: |
| 449 | + return RoborockDockState.off_peak_waiting |
| 450 | + return RoborockDockState.charging |
| 451 | + |
| 452 | + # 2. RECHARGING |
| 453 | + if self.state in (RoborockStateCode.returning_home, RoborockStateCode.docking): |
| 454 | + return RoborockDockState.returning |
| 455 | + |
| 456 | + # 1. IDLE (Not on dock, or doing something else) |
| 457 | + return RoborockDockState.idle |
| 458 | + |
417 | 459 | def __repr__(self) -> str: |
418 | 460 | return _attr_repr(self) |
419 | 461 |
|
@@ -629,8 +671,9 @@ class ConsumableField(FieldNameBase): |
629 | 671 | This is used with `roborock.devices.traits.v1.status.DeviceFeaturesTrait` |
630 | 672 | to understand if a feature is supported by the device using `is_field_supported`. |
631 | 673 |
|
632 | | - The enum values are names of fields in the `Consumable` class. Each field is annotated |
633 | | - with a metadata value to determine if the field is supported by the device. |
| 674 | + The enum values are names of fields in the `Consumable` class. Each field is |
| 675 | + annotated with `dps` metadata to map the field to a `RoborockDataProtocol` |
| 676 | + value used to check support against the product schema. |
634 | 677 | """ |
635 | 678 |
|
636 | 679 | MAIN_BRUSH_WORK_TIME = "main_brush_work_time" |
|
0 commit comments