Skip to content

Commit f431c5d

Browse files
committed
fix: add missing dock ids
1 parent c8cd20f commit f431c5d

3 files changed

Lines changed: 220 additions & 0 deletions

File tree

roborock/data/v1/v1_code_mappings.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,27 @@ class RoborockDockTypeCode(RoborockEnum):
365365
shell_e_dock = 21
366366
shell_2e_dock = 22
367367
shell_3c_dock = 23
368+
hera_dock = 24
369+
k1s_pro_dock = 26
368370
type_27_dock = 27
369371
k1c_lite_dock = 28
372+
k1r_dock = 29
370373
shell_2e_lite_dock = 30
374+
shell_4rc_dock = 31
375+
shell_4r_dock = 32
376+
shell_4p_dock = 33
377+
shell_4s_dock = 34
378+
o7_dock = 35
379+
k1d_dock = 37
380+
shell_3p_dock = 38
381+
shell_4d_dock = 39
371382
shell_2e_heat_dock = 40
383+
f1_dock = 41
384+
f1r_dock = 42
385+
f2r_dock = 43
386+
f1s_dock = 44
387+
o7h_dock = 45
388+
f1c_dock = 46
372389

373390

374391
class RoborockDockDustCollectionModeCode(RoborockEnum):

roborock/device_features.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,8 @@ def get_supported_features(self) -> list[str]:
676676
RoborockDockTypeCode.o4_dock,
677677
RoborockDockTypeCode.o5_dock,
678678
RoborockDockTypeCode.o6_dock,
679+
RoborockDockTypeCode.o7_dock,
680+
RoborockDockTypeCode.o7h_dock,
679681
}
680682

681683
_CLEAN_FLUID_AUTO_DELIVERY_DOCK_TYPES = {
@@ -685,6 +687,10 @@ def get_supported_features(self) -> list[str]:
685687
RoborockDockTypeCode.shell_3s_dock,
686688
RoborockDockTypeCode.o6_dock,
687689
RoborockDockTypeCode.couple_dock,
690+
RoborockDockTypeCode.type_27_dock,
691+
RoborockDockTypeCode.o7_dock,
692+
RoborockDockTypeCode.f1s_dock,
693+
RoborockDockTypeCode.o7h_dock,
688694
}
689695

690696
_CLEAN_FLUID_AUTO_DELIVERY_AM_DOCK_TYPES = {
@@ -696,6 +702,7 @@ def get_supported_features(self) -> list[str]:
696702
RoborockDockTypeCode.shell_e_dock,
697703
RoborockDockTypeCode.shell_2e_dock,
698704
RoborockDockTypeCode.shell_3c_dock,
705+
RoborockDockTypeCode.k1c_dock,
699706
}
700707

701708
_AUTO_STERILIZE_DOCK_TYPES = {
@@ -725,6 +732,18 @@ def get_supported_features(self) -> list[str]:
725732
RoborockDockTypeCode.shell_3s_dock,
726733
RoborockDockTypeCode.k1s_dock,
727734
RoborockDockTypeCode.shell_3c_dock,
735+
RoborockDockTypeCode.k1s_pro_dock,
736+
RoborockDockTypeCode.type_27_dock,
737+
RoborockDockTypeCode.k1r_dock,
738+
RoborockDockTypeCode.shell_4rc_dock,
739+
RoborockDockTypeCode.shell_4p_dock,
740+
RoborockDockTypeCode.shell_4s_dock,
741+
RoborockDockTypeCode.k1d_dock,
742+
RoborockDockTypeCode.shell_3p_dock,
743+
RoborockDockTypeCode.f1_dock,
744+
RoborockDockTypeCode.f2r_dock,
745+
RoborockDockTypeCode.f1s_dock,
746+
RoborockDockTypeCode.f1c_dock,
728747
}
729748

730749
_WATER_UPDOWN_DRAIN_DOCK_TYPES = {
@@ -745,6 +764,19 @@ def get_supported_features(self) -> list[str]:
745764
RoborockDockTypeCode.shell_e_dock,
746765
RoborockDockTypeCode.shell_2e_dock,
747766
RoborockDockTypeCode.shell_3c_dock,
767+
RoborockDockTypeCode.k1c_dock,
768+
RoborockDockTypeCode.hera_dock,
769+
RoborockDockTypeCode.k1s_pro_dock,
770+
RoborockDockTypeCode.type_27_dock,
771+
RoborockDockTypeCode.shell_4rc_dock,
772+
RoborockDockTypeCode.shell_4r_dock,
773+
RoborockDockTypeCode.shell_4p_dock,
774+
RoborockDockTypeCode.shell_4s_dock,
775+
RoborockDockTypeCode.o7_dock,
776+
RoborockDockTypeCode.shell_4d_dock,
777+
RoborockDockTypeCode.f1r_dock,
778+
RoborockDockTypeCode.f1s_dock,
779+
RoborockDockTypeCode.o7h_dock,
748780
}
749781

750782
_HATCH_DOOR_DOCK_COOL_FAN_DOCK_TYPES = {
@@ -755,6 +787,56 @@ def get_supported_features(self) -> list[str]:
755787
RoborockDockTypeCode.shell_2e_lite_dock,
756788
}
757789

790+
_HIGH_TMP_WATER_DOCK_TYPES = {
791+
RoborockDockTypeCode.k1r_dock,
792+
RoborockDockTypeCode.shell_4rc_dock,
793+
RoborockDockTypeCode.shell_2e_heat_dock,
794+
RoborockDockTypeCode.f1_dock,
795+
RoborockDockTypeCode.f1r_dock,
796+
RoborockDockTypeCode.f2r_dock,
797+
RoborockDockTypeCode.f1c_dock,
798+
}
799+
800+
_DOUBLE_SERIAL_COMMUNICATION_DOCK_TYPES = {
801+
RoborockDockTypeCode.k1s_pro_dock,
802+
RoborockDockTypeCode.type_27_dock,
803+
RoborockDockTypeCode.k1r_dock,
804+
RoborockDockTypeCode.shell_4r_dock,
805+
RoborockDockTypeCode.shell_4p_dock,
806+
RoborockDockTypeCode.shell_4s_dock,
807+
RoborockDockTypeCode.o7_dock,
808+
RoborockDockTypeCode.k1d_dock,
809+
RoborockDockTypeCode.shell_3p_dock,
810+
RoborockDockTypeCode.f1_dock,
811+
RoborockDockTypeCode.f1r_dock,
812+
RoborockDockTypeCode.f2r_dock,
813+
RoborockDockTypeCode.f1s_dock,
814+
RoborockDockTypeCode.o7h_dock,
815+
RoborockDockTypeCode.f1c_dock,
816+
}
817+
818+
_DOUBLE_SERIAL_COMMUNICATION_AM_DOCK_TYPES = {
819+
RoborockDockTypeCode.shell_4rc_dock,
820+
RoborockDockTypeCode.shell_4d_dock,
821+
}
822+
823+
_NO_WATER_FLOW_CAROUSEL_DOCK_TYPES = {
824+
RoborockDockTypeCode.f1r_dock,
825+
RoborockDockTypeCode.f2r_dock,
826+
RoborockDockTypeCode.f1s_dock,
827+
}
828+
829+
_SIMPLE_WASH_MODE_DOCK_TYPES = {
830+
RoborockDockTypeCode.f1_dock,
831+
RoborockDockTypeCode.f1r_dock,
832+
RoborockDockTypeCode.f2r_dock,
833+
RoborockDockTypeCode.f1c_dock,
834+
}
835+
836+
_STEAM_WASH_DOCK_TYPES = {
837+
RoborockDockTypeCode.o7h_dock,
838+
}
839+
758840

759841
@dataclass(frozen=True)
760842
class RoborockDockFeatures:
@@ -855,6 +937,28 @@ def is_hatch_door_dock_cool_fan_supported(self) -> bool:
855937
def is_special_support_wash_temp(self) -> bool:
856938
return self.dock_type in _SPECIAL_WASH_TEMP_DOCK_TYPES
857939

940+
@property
941+
def is_high_tmp_water_supported(self) -> bool:
942+
return self.dock_type in _HIGH_TMP_WATER_DOCK_TYPES
943+
944+
@property
945+
def is_double_serial_communication_supported(self) -> bool:
946+
return self.dock_type in _DOUBLE_SERIAL_COMMUNICATION_DOCK_TYPES or self._matches_am_variant(
947+
_DOUBLE_SERIAL_COMMUNICATION_AM_DOCK_TYPES
948+
)
949+
950+
@property
951+
def is_no_water_flow_carousel(self) -> bool:
952+
return self.dock_type in _NO_WATER_FLOW_CAROUSEL_DOCK_TYPES
953+
954+
@property
955+
def is_simple_wash_mode_supported(self) -> bool:
956+
return self.dock_type in _SIMPLE_WASH_MODE_DOCK_TYPES
957+
958+
@property
959+
def is_steam_wash_supported(self) -> bool:
960+
return self.dock_type in _STEAM_WASH_DOCK_TYPES
961+
858962

859963
WASH_N_FILL_DOCK_TYPES = [
860964
dock_type for dock_type in RoborockDockTypeCode if RoborockDockFeatures.from_dock_type(dock_type).is_washable

tests/test_supported_features.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,53 @@
99
from roborock.device_features import DeviceFeatures, RoborockDockFeatures, is_valid_dock, is_wash_n_fill_dock
1010
from tests import mock_data
1111

12+
# RR_API DockConfigs snapshot from the Qrevo Edge 2 bundle decoded on 2026-07-11.
13+
RR_API_DOCK_TYPES = {
14+
0: "o0_dock",
15+
1: "o1_dock",
16+
2: "o2_dock",
17+
3: "o3_dock",
18+
5: "oc_dock",
19+
6: "o3_plus_dock",
20+
7: "o4_dock",
21+
8: "pearl_dock",
22+
9: "pearl_plus_dock",
23+
10: "o5_dock",
24+
11: "shell_2s_dock",
25+
13: "couple_dock",
26+
14: "shell_3_dock",
27+
15: "shell_2c_dock",
28+
16: "shell_3s_dock",
29+
17: "k1_dock",
30+
18: "o6_dock",
31+
19: "k1c_dock",
32+
20: "k1s_dock",
33+
21: "shell_e_dock",
34+
22: "shell_2e_dock",
35+
23: "shell_3c_dock",
36+
24: "hera_dock",
37+
26: "k1s_pro_dock",
38+
27: "type_27_dock",
39+
28: "k1c_lite_dock",
40+
29: "k1r_dock",
41+
30: "shell_2e_lite_dock",
42+
31: "shell_4rc_dock",
43+
32: "shell_4r_dock",
44+
33: "shell_4p_dock",
45+
34: "shell_4s_dock",
46+
35: "o7_dock",
47+
37: "k1d_dock",
48+
38: "shell_3p_dock",
49+
39: "shell_4d_dock",
50+
40: "shell_2e_heat_dock",
51+
41: "f1_dock",
52+
42: "f1r_dock",
53+
43: "f2r_dock",
54+
44: "f1s_dock",
55+
45: "o7h_dock",
56+
46: "f1c_dock",
57+
}
58+
1259

1360
def test_supported_features_qrevo_maxv():
1461
"""Ensure that a QREVO MaxV has some more complicated features enabled."""
@@ -106,10 +153,27 @@ def test_new_feature_str_missing():
106153
(RoborockDockTypeCode.shell_e_dock, True, True),
107154
(RoborockDockTypeCode.shell_2e_dock, True, True),
108155
(RoborockDockTypeCode.shell_3c_dock, True, True),
156+
(RoborockDockTypeCode.hera_dock, True, True),
157+
(RoborockDockTypeCode.k1s_pro_dock, True, True),
109158
(RoborockDockTypeCode.type_27_dock, True, True),
110159
(RoborockDockTypeCode.k1c_lite_dock, True, True),
160+
(RoborockDockTypeCode.k1r_dock, True, True),
111161
(RoborockDockTypeCode.shell_2e_lite_dock, True, True),
162+
(RoborockDockTypeCode.shell_4rc_dock, True, True),
163+
(RoborockDockTypeCode.shell_4r_dock, True, True),
164+
(RoborockDockTypeCode.shell_4p_dock, True, True),
165+
(RoborockDockTypeCode.shell_4s_dock, True, True),
166+
(RoborockDockTypeCode.o7_dock, True, True),
167+
(RoborockDockTypeCode.k1d_dock, True, True),
168+
(RoborockDockTypeCode.shell_3p_dock, True, True),
169+
(RoborockDockTypeCode.shell_4d_dock, True, True),
112170
(RoborockDockTypeCode.shell_2e_heat_dock, True, True),
171+
(RoborockDockTypeCode.f1_dock, True, True),
172+
(RoborockDockTypeCode.f1r_dock, True, True),
173+
(RoborockDockTypeCode.f2r_dock, True, True),
174+
(RoborockDockTypeCode.f1s_dock, True, True),
175+
(RoborockDockTypeCode.o7h_dock, True, True),
176+
(RoborockDockTypeCode.f1c_dock, True, True),
113177
],
114178
)
115179
def test_dock_features(dock_type: RoborockDockTypeCode, is_collectable: bool, is_washable: bool) -> None:
@@ -122,6 +186,17 @@ def test_dock_features(dock_type: RoborockDockTypeCode, is_collectable: bool, is
122186
assert is_wash_n_fill_dock(dock_type) is dock_features.is_washable
123187

124188

189+
def test_all_rr_api_dock_types_are_mapped() -> None:
190+
"""Keep the enum synchronized with the RR_API DockConfigs snapshot."""
191+
mapped_docks = {
192+
dock_type.value: dock_type.name
193+
for dock_type in RoborockDockTypeCode
194+
if dock_type is not RoborockDockTypeCode.unknown
195+
}
196+
197+
assert mapped_docks == RR_API_DOCK_TYPES
198+
199+
125200
def test_dock_feature_flags_from_rr_api() -> None:
126201
"""Verify dock-specific feature flags that are not currently trait gates."""
127202
assert RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.shell_3s_dock).is_auto_sterilize_supported
@@ -135,6 +210,17 @@ def test_dock_feature_flags_from_rr_api() -> None:
135210
assert not RoborockDockFeatures.from_dock_type(
136211
RoborockDockTypeCode.shell_2e_heat_dock
137212
).is_water_updown_drain_supported
213+
assert RoborockDockFeatures.from_dock_type(
214+
RoborockDockTypeCode.shell_3p_dock
215+
).is_clean_carousel_self_clean_supported
216+
assert RoborockDockFeatures.from_dock_type(
217+
RoborockDockTypeCode.shell_3p_dock
218+
).is_double_serial_communication_supported
219+
assert RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.o7_dock).is_only_x_series
220+
assert RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.o7_dock).is_clean_fluid_auto_delivery_supported
221+
assert RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.o7h_dock).is_steam_wash_supported
222+
assert RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.f1_dock).is_simple_wash_mode_supported
223+
assert RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.f1r_dock).is_no_water_flow_carousel
138224

139225

140226
def test_dock_feature_flags_with_am_variants_from_rr_api() -> None:
@@ -166,6 +252,19 @@ def test_dock_feature_flags_with_am_variants_from_rr_api() -> None:
166252
RoborockDockTypeCode.shell_3c_dock, has_am=True
167253
).is_water_updown_drain_supported
168254

255+
shell_4rc = RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.shell_4rc_dock)
256+
shell_4rc_am = RoborockDockFeatures.from_dock_type(RoborockDockTypeCode.shell_4rc_dock, has_am=True)
257+
assert shell_4rc.is_clean_carousel_self_clean_supported
258+
assert not shell_4rc_am.is_clean_carousel_self_clean_supported
259+
assert not shell_4rc.is_water_updown_drain_supported
260+
assert shell_4rc_am.is_water_updown_drain_supported
261+
assert not shell_4rc.is_clean_fluid_auto_delivery_supported
262+
assert not shell_4rc_am.is_clean_fluid_auto_delivery_supported
263+
assert shell_4rc.is_high_tmp_water_supported
264+
assert shell_4rc_am.is_high_tmp_water_supported
265+
assert not shell_4rc.is_double_serial_communication_supported
266+
assert shell_4rc_am.is_double_serial_communication_supported
267+
169268

170269
@pytest.mark.parametrize(
171270
("device_filename"),

0 commit comments

Comments
 (0)