Skip to content

Commit 476083d

Browse files
committed
added dock_summary information
1 parent 9b20345 commit 476083d

File tree

5 files changed

+121
-38
lines changed

5 files changed

+121
-38
lines changed

roborock/api.py

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""The Roborock api."""
2+
23
from __future__ import annotations
34

45
import asyncio
@@ -23,9 +24,16 @@
2324
import paho.mqtt.client as mqtt
2425
from Crypto.Cipher import AES
2526
from Crypto.Util.Padding import pad, unpad
26-
from roborock.code_mappings import STATE_CODE_TO_STATUS
2727

28-
from roborock.containers import (
28+
from roborock.exceptions import (
29+
RoborockException,
30+
CommandVacuumError,
31+
VacuumError,
32+
RoborockTimeout,
33+
)
34+
from .code_mappings import STATE_CODE_TO_STATUS, WASH_MODE_MAP, DUST_COLLECTION_MAP, RoborockDockType, \
35+
RoborockDockDustCollectionType, RoborockDockWashingModeType
36+
from .containers import (
2937
UserData,
3038
HomeDataDevice,
3139
Status,
@@ -35,20 +43,17 @@
3543
CleanRecord,
3644
HomeData,
3745
MultiMapsList,
46+
SmartWashParameters,
47+
3848
)
39-
from roborock.exceptions import (
40-
RoborockException,
41-
CommandVacuumError,
42-
VacuumError,
43-
RoborockTimeout,
44-
)
45-
from roborock.roborock_queue import RoborockQueue
46-
from roborock.typing import (
49+
from .roborock_queue import RoborockQueue
50+
from .typing import (
4751
RoborockDeviceInfo,
4852
RoborockDeviceProp,
4953
RoborockCommand,
54+
RoborockDockSummary,
5055
)
51-
from roborock.util import run_in_executor
56+
from .util import run_in_executor
5257

5358
_LOGGER = logging.getLogger(__name__)
5459
QUEUE_TIMEOUT = 4
@@ -78,17 +83,17 @@ def __init__(self, base_url: str, base_headers: dict = None) -> None:
7883
self.base_headers = base_headers or {}
7984

8085
async def request(
81-
self, method: str, url: str, params=None, data=None, headers=None
86+
self, method: str, url: str, params=None, data=None, headers=None
8287
) -> dict | list:
8388
_url = "/".join(s.strip("/") for s in [self.base_url, url])
8489
_headers = {**self.base_headers, **(headers or {})}
8590
async with aiohttp.ClientSession() as session:
8691
async with session.request(
87-
method,
88-
_url,
89-
params=params,
90-
data=data,
91-
headers=_headers,
92+
method,
93+
_url,
94+
params=params,
95+
data=data,
96+
headers=_headers,
9297
) as resp:
9398
return await resp.json()
9499

@@ -369,7 +374,7 @@ def _send_msg_raw(self, device_id, protocol, timestamp, payload) -> None:
369374
raise RoborockException(f"Failed to publish (rc: {info.rc})")
370375

371376
async def send_command(
372-
self, device_id: str, method: RoborockCommand, params: list = None
377+
self, device_id: str, method: RoborockCommand, params: list = None
373378
):
374379
await self.validate_connection()
375380
timestamp = math.floor(time.time())
@@ -439,6 +444,29 @@ async def get_consumable(self, device_id: str) -> Consumable:
439444
if isinstance(consumable, dict):
440445
return Consumable(consumable)
441446

447+
async def get_washing_mode(self, device_id: str) -> RoborockDockWashingModeType:
448+
washing_mode = await self.send_command(device_id, RoborockCommand.GET_WASH_TOWEL_MODE)
449+
return WASH_MODE_MAP.get(washing_mode)
450+
451+
async def get_dust_collection_mode(self, device_id: str) -> RoborockDockDustCollectionType:
452+
dust_collection = await self.send_command(device_id, RoborockCommand.GET_DUST_COLLECTION_MODE)
453+
return DUST_COLLECTION_MAP.get(dust_collection)
454+
455+
async def get_mop_wash_mode(self, device_id: str) -> SmartWashParameters:
456+
mop_wash_mode = await self.send_command(device_id, RoborockCommand.GET_SMART_WASH_PARAMS)
457+
if isinstance(mop_wash_mode, dict):
458+
return SmartWashParameters(mop_wash_mode)
459+
460+
async def get_dock_summary(self, device_id: str, dock_type: RoborockDockType) -> RoborockDockSummary:
461+
collection_mode = await self.get_dust_collection_mode(device_id)
462+
mop_wash = None
463+
washing_mode = None
464+
if dock_type == RoborockDockType.EMPTY_WASH_FILL_DOCK:
465+
[mop_wash, washing_mode] = await asyncio.gather(
466+
*[self.get_mop_wash_mode(device_id), self.get_washing_mode(device_id)])
467+
468+
return RoborockDockSummary(collection_mode, washing_mode, mop_wash)
469+
442470
async def get_prop(self, device_id: str) -> RoborockDeviceProp:
443471
[status, dnd_timer, clean_summary, consumable] = await asyncio.gather(
444472
*[
@@ -453,9 +481,12 @@ async def get_prop(self, device_id: str) -> RoborockDeviceProp:
453481
last_clean_record = await self.get_clean_record(
454482
device_id, clean_summary.records[0]
455483
)
484+
dock_summary = None
485+
if status.dock_type != RoborockDockType.NO_DOCK:
486+
dock_summary = await self.get_dock_summary(device_id, status.dock_type)
456487
if any([status, dnd_timer, clean_summary, consumable]):
457488
return RoborockDeviceProp(
458-
status, dnd_timer, clean_summary, consumable, last_clean_record
489+
status, dnd_timer, clean_summary, consumable, last_clean_record, dock_summary
459490
)
460491

461492
async def get_multi_maps_list(self, device_id) -> MultiMapsList:

roborock/code_mappings.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
from __future__ import annotations
22

3+
from enum import Enum
34
from typing import Any
45

6+
7+
class RoborockDockType(str, Enum):
8+
NO_DOCK = "No dock"
9+
AUTO_EMPTY = "Roborock auto-empty dock" # Dust collection
10+
EMPTY_WASH_FILL_DOCK = "Roborock empty wash fill dock"
11+
AUTO_EMPTY_PURE = "Roborock auto-empty pure dock"
12+
UNKNOWN = "Unknown Dock - please submit an issue"
13+
14+
15+
class RoborockDockDustCollectionType(str, Enum):
16+
SMART = "smart"
17+
QUICK = "quick"
18+
DAILY = "daily"
19+
STRONG = "strong"
20+
MAX = "max"
21+
22+
23+
class RoborockDockWashingModeType(str, Enum):
24+
LIGHT = "light"
25+
BALANCED = "balanced"
26+
DEEP = "deep"
27+
28+
529
STATE_CODE_TO_STATUS: dict[int | Any, str | Any] = {
630
1: "starting",
731
2: "charger_disconnected",
@@ -88,3 +112,22 @@
88112
38: 'water empty',
89113
39: 'waste water tank full',
90114
}
115+
116+
DOCK_TYPE_MAP = {
117+
0: RoborockDockType.NO_DOCK,
118+
3: RoborockDockType.EMPTY_WASH_FILL_DOCK,
119+
}
120+
121+
DUST_COLLECTION_MAP = {
122+
0: RoborockDockDustCollectionType.SMART,
123+
1: RoborockDockDustCollectionType.QUICK,
124+
2: RoborockDockDustCollectionType.DAILY,
125+
3: RoborockDockDustCollectionType.STRONG,
126+
4: RoborockDockDustCollectionType.MAX,
127+
}
128+
129+
WASH_MODE_MAP = {
130+
0: RoborockDockWashingModeType.LIGHT,
131+
1: RoborockDockWashingModeType.BALANCED,
132+
2: RoborockDockWashingModeType.DEEP,
133+
}

roborock/containers.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from enum import Enum
22

3-
from roborock.code_mappings import STATE_CODE_TO_STATUS, ERROR_CODE_TO_TEXT, FAN_SPEED_CODES, MOP_MODE_CODES, \
4-
MOP_INTENSITY_CODES, DOCK_ERROR_TO_TEXT
3+
from .code_mappings import STATE_CODE_TO_STATUS, ERROR_CODE_TO_TEXT, FAN_SPEED_CODES, MOP_MODE_CODES, \
4+
MOP_INTENSITY_CODES, DOCK_ERROR_TO_TEXT, DOCK_TYPE_MAP, RoborockDockType
55

66

77
class UserDataRRiotReferenceField(str, Enum):
@@ -770,9 +770,13 @@ def water_shortage_status(self) -> int:
770770
return self.get(StatusField.WATER_SHORTAGE_STATUS)
771771

772772
@property
773-
def dock_type(self) -> int:
773+
def dock_type_code(self) -> int:
774774
return self.get(StatusField.DOCK_TYPE)
775775

776+
@property
777+
def dock_type(self) -> RoborockDockType:
778+
return DOCK_TYPE_MAP.get(self.get(StatusField.DOCK_TYPE), RoborockDockType.UNKNOWN)
779+
776780
@property
777781
def dust_collection_status(self) -> int:
778782
return self.get(StatusField.DUST_COLLECTION_STATUS)
@@ -811,7 +815,7 @@ def dock_error_status_code(self) -> int:
811815

812816
@property
813817
def dock_error_status(self) -> str:
814-
return self.get(DOCK_ERROR_TO_TEXT.get(StatusField.DOCK_ERROR_STATUS))
818+
return DOCK_ERROR_TO_TEXT.get(self.get(StatusField.DOCK_ERROR_STATUS))
815819

816820
@property
817821
def charge_status(self) -> int:
@@ -1040,12 +1044,3 @@ def smart_wash(self) -> int:
10401044
@property
10411045
def wash_interval(self) -> int:
10421046
return self.get(SmartWashField.WASH_INTERVAL)
1043-
1044-
1045-
class WashTowelMode(RoborockBase):
1046-
def __init__(self, data: dict[str, any]) -> None:
1047-
super().__init__(data)
1048-
1049-
@property
1050-
def wash_mode(self) -> int:
1051-
return self.get(WashTowelField.WASH_MODE)

roborock/typing.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from enum import Enum
22

3-
from roborock.containers import HomeDataDevice, HomeDataProduct, Status, CleanSummary, Consumable, \
4-
DNDTimer, CleanRecord
3+
from .code_mappings import RoborockDockDustCollectionType, RoborockDockWashingModeType
4+
from .containers import HomeDataDevice, HomeDataProduct, Status, CleanSummary, Consumable, \
5+
DNDTimer, CleanRecord, SmartWashParameters
56

67

78
class RoborockDevicePropField(str, Enum):
@@ -60,14 +61,23 @@ def __init__(self, device: HomeDataDevice, product: HomeDataProduct):
6061
self.product = product
6162

6263

64+
class RoborockDockSummary:
65+
def __init__(self, dust_collection_mode: RoborockDockDustCollectionType,
66+
washing_mode_type: RoborockDockWashingModeType, mop_wash: SmartWashParameters) -> None:
67+
self.dust_collection_mode = dust_collection_mode
68+
self.washing_mode_type = washing_mode_type
69+
self.mop_wash = mop_wash
70+
71+
6372
class RoborockDeviceProp:
6473
def __init__(self, status: Status, dnd_timer: DNDTimer, clean_summary: CleanSummary, consumable: Consumable,
65-
last_clean_record: CleanRecord):
74+
last_clean_record: CleanRecord, dock_summary: RoborockDockSummary):
6675
self.status = status
6776
self.dnd_timer = dnd_timer
6877
self.clean_summary = clean_summary
6978
self.consumable = consumable
7079
self.last_clean_record = last_clean_record
80+
self.dock_summary = dock_summary
7181

7282
def update(self, device_prop: 'RoborockDeviceProp'):
7383
if device_prop.status:
@@ -80,3 +90,5 @@ def update(self, device_prop: 'RoborockDeviceProp'):
8090
self.consumable = device_prop.consumable
8191
if device_prop.last_clean_record:
8292
self.last_clean_record = device_prop.last_clean_record
93+
if device_prop.dock_summary:
94+
self.dock_summary = device_prop.dock_summary

tests/test_containers.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from roborock import UserData, HomeData, Consumable, Status, DNDTimer, CleanSummary, CleanRecord
1+
from roborock import UserData, HomeData, Consumable, Status, DNDTimer, CleanSummary, CleanRecord, RoborockDockType
22
from .mock_data import USER_DATA, HOME_DATA_RAW, CONSUMABLE, STATUS, DND_TIMER, CLEAN_SUMMARY, CLEAN_RECORD
33

44

@@ -124,7 +124,8 @@ def test_status():
124124
assert s.home_sec_enable_password == 0
125125
assert s.adbumper_status == [0, 0, 0]
126126
assert s.water_shortage_status == 0
127-
assert s.dock_type == 3
127+
assert s.dock_type_code == 3
128+
assert s.dock_type == RoborockDockType.EMPTY_WASH_FILL_DOCK
128129
assert s.dust_collection_status == 0
129130
assert s.auto_dust_collection == 1
130131
assert s.avoid_count == 19
@@ -133,7 +134,8 @@ def test_status():
133134
assert s.debug_mode == 0
134135
assert s.collision_avoid_status == 1
135136
assert s.switch_map_mode == 0
136-
assert s.dock_error_status == 0
137+
assert s.dock_error_status_code == 0
138+
assert s.dock_error_status == "ok"
137139
assert s.charge_status == 1
138140
assert s.unsave_map_reason == 0
139141
assert s.unsave_map_flag == 0

0 commit comments

Comments
 (0)