1919 DyadWarmLevel ,
2020 DyadWaterLevel ,
2121 RoborockDyadStateCode ,
22+ ZeoDetergentType ,
23+ ZeoDryingMode ,
24+ ZeoError ,
25+ ZeoMode ,
26+ ZeoProgram ,
27+ ZeoRinse ,
28+ ZeoSoftenerType ,
29+ ZeoSpin ,
30+ ZeoState ,
31+ ZeoTemperature ,
2232)
23- from roborock .containers import DyadProductInfo , DyadSndState
33+ from roborock .containers import DyadProductInfo , DyadSndState , RoborockCategory
2434from roborock .roborock_message import (
2535 RoborockDyadDataProtocol ,
2636 RoborockMessage ,
2737 RoborockMessageProtocol ,
38+ RoborockZeoProtocol ,
2839)
2940
3041
3142@dataclasses .dataclass
32- class DyadProtocolCacheEntry :
43+ class A01ProtocolCacheEntry :
3344 post_process_fn : Callable
3445 value : typing .Any | None = None
3546
3647
3748# Right now this cache is not active, it was too much complexity for the initial addition of dyad.
3849protocol_entries = {
39- RoborockDyadDataProtocol .STATUS : DyadProtocolCacheEntry (lambda val : RoborockDyadStateCode (val ).name ),
40- RoborockDyadDataProtocol .SELF_CLEAN_MODE : DyadProtocolCacheEntry (lambda val : DyadSelfCleanMode (val ).name ),
41- RoborockDyadDataProtocol .SELF_CLEAN_LEVEL : DyadProtocolCacheEntry (lambda val : DyadSelfCleanLevel (val ).name ),
42- RoborockDyadDataProtocol .WARM_LEVEL : DyadProtocolCacheEntry (lambda val : DyadWarmLevel (val ).name ),
43- RoborockDyadDataProtocol .CLEAN_MODE : DyadProtocolCacheEntry (lambda val : DyadCleanMode (val ).name ),
44- RoborockDyadDataProtocol .SUCTION : DyadProtocolCacheEntry (lambda val : DyadSuction (val ).name ),
45- RoborockDyadDataProtocol .WATER_LEVEL : DyadProtocolCacheEntry (lambda val : DyadWaterLevel (val ).name ),
46- RoborockDyadDataProtocol .BRUSH_SPEED : DyadProtocolCacheEntry (lambda val : DyadBrushSpeed (val ).name ),
47- RoborockDyadDataProtocol .POWER : DyadProtocolCacheEntry (lambda val : int (val )),
48- RoborockDyadDataProtocol .AUTO_DRY : DyadProtocolCacheEntry (lambda val : bool (val )),
49- RoborockDyadDataProtocol .MESH_LEFT : DyadProtocolCacheEntry (lambda val : int (360000 - val * 60 )),
50- RoborockDyadDataProtocol .BRUSH_LEFT : DyadProtocolCacheEntry (lambda val : int (360000 - val * 60 )),
51- RoborockDyadDataProtocol .ERROR : DyadProtocolCacheEntry (lambda val : DyadError (val ).name ),
52- RoborockDyadDataProtocol .VOLUME_SET : DyadProtocolCacheEntry (lambda val : int (val )),
53- RoborockDyadDataProtocol .STAND_LOCK_AUTO_RUN : DyadProtocolCacheEntry (lambda val : bool (val )),
54- RoborockDyadDataProtocol .AUTO_DRY_MODE : DyadProtocolCacheEntry (lambda val : bool (val )),
55- RoborockDyadDataProtocol .SILENT_DRY_DURATION : DyadProtocolCacheEntry (lambda val : int (val )), # in minutes
56- RoborockDyadDataProtocol .SILENT_MODE : DyadProtocolCacheEntry (lambda val : bool (val )),
57- RoborockDyadDataProtocol .SILENT_MODE_START_TIME : DyadProtocolCacheEntry (
50+ RoborockDyadDataProtocol .STATUS : A01ProtocolCacheEntry (lambda val : RoborockDyadStateCode (val ).name ),
51+ RoborockDyadDataProtocol .SELF_CLEAN_MODE : A01ProtocolCacheEntry (lambda val : DyadSelfCleanMode (val ).name ),
52+ RoborockDyadDataProtocol .SELF_CLEAN_LEVEL : A01ProtocolCacheEntry (lambda val : DyadSelfCleanLevel (val ).name ),
53+ RoborockDyadDataProtocol .WARM_LEVEL : A01ProtocolCacheEntry (lambda val : DyadWarmLevel (val ).name ),
54+ RoborockDyadDataProtocol .CLEAN_MODE : A01ProtocolCacheEntry (lambda val : DyadCleanMode (val ).name ),
55+ RoborockDyadDataProtocol .SUCTION : A01ProtocolCacheEntry (lambda val : DyadSuction (val ).name ),
56+ RoborockDyadDataProtocol .WATER_LEVEL : A01ProtocolCacheEntry (lambda val : DyadWaterLevel (val ).name ),
57+ RoborockDyadDataProtocol .BRUSH_SPEED : A01ProtocolCacheEntry (lambda val : DyadBrushSpeed (val ).name ),
58+ RoborockDyadDataProtocol .POWER : A01ProtocolCacheEntry (lambda val : int (val )),
59+ RoborockDyadDataProtocol .AUTO_DRY : A01ProtocolCacheEntry (lambda val : bool (val )),
60+ RoborockDyadDataProtocol .MESH_LEFT : A01ProtocolCacheEntry (lambda val : int (360000 - val * 60 )),
61+ RoborockDyadDataProtocol .BRUSH_LEFT : A01ProtocolCacheEntry (lambda val : int (360000 - val * 60 )),
62+ RoborockDyadDataProtocol .ERROR : A01ProtocolCacheEntry (lambda val : DyadError (val ).name ),
63+ RoborockDyadDataProtocol .VOLUME_SET : A01ProtocolCacheEntry (lambda val : int (val )),
64+ RoborockDyadDataProtocol .STAND_LOCK_AUTO_RUN : A01ProtocolCacheEntry (lambda val : bool (val )),
65+ RoborockDyadDataProtocol .AUTO_DRY_MODE : A01ProtocolCacheEntry (lambda val : bool (val )),
66+ RoborockDyadDataProtocol .SILENT_DRY_DURATION : A01ProtocolCacheEntry (lambda val : int (val )), # in minutes
67+ RoborockDyadDataProtocol .SILENT_MODE : A01ProtocolCacheEntry (lambda val : bool (val )),
68+ RoborockDyadDataProtocol .SILENT_MODE_START_TIME : A01ProtocolCacheEntry (
5869 lambda val : time (hour = int (val / 60 ), minute = val % 60 )
5970 ), # in minutes since 00:00
60- RoborockDyadDataProtocol .SILENT_MODE_END_TIME : DyadProtocolCacheEntry (
71+ RoborockDyadDataProtocol .SILENT_MODE_END_TIME : A01ProtocolCacheEntry (
6172 lambda val : time (hour = int (val / 60 ), minute = val % 60 )
6273 ), # in minutes since 00:00
63- RoborockDyadDataProtocol .RECENT_RUN_TIME : DyadProtocolCacheEntry (
74+ RoborockDyadDataProtocol .RECENT_RUN_TIME : A01ProtocolCacheEntry (
6475 lambda val : [int (v ) for v in val .split ("," )]
6576 ), # minutes of cleaning in past few days.
66- RoborockDyadDataProtocol .TOTAL_RUN_TIME : DyadProtocolCacheEntry (lambda val : int (val )),
67- RoborockDyadDataProtocol .SND_STATE : DyadProtocolCacheEntry (lambda val : DyadSndState .from_dict (val )),
68- RoborockDyadDataProtocol .PRODUCT_INFO : DyadProtocolCacheEntry (lambda val : DyadProductInfo .from_dict (val )),
77+ RoborockDyadDataProtocol .TOTAL_RUN_TIME : A01ProtocolCacheEntry (lambda val : int (val )),
78+ RoborockDyadDataProtocol .SND_STATE : A01ProtocolCacheEntry (lambda val : DyadSndState .from_dict (val )),
79+ RoborockDyadDataProtocol .PRODUCT_INFO : A01ProtocolCacheEntry (lambda val : DyadProductInfo .from_dict (val )),
80+ }
81+
82+ zeo_data_protocol_entries = {
83+ # ro
84+ RoborockZeoProtocol .STATE : A01ProtocolCacheEntry (lambda val : ZeoState (val ).name ),
85+ RoborockZeoProtocol .COUNTDOWN : A01ProtocolCacheEntry (lambda val : int (val )),
86+ RoborockZeoProtocol .WASHING_LEFT : A01ProtocolCacheEntry (lambda val : int (val )),
87+ RoborockZeoProtocol .ERROR : A01ProtocolCacheEntry (lambda val : ZeoError (val ).name ),
88+ RoborockZeoProtocol .TIMES_AFTER_CLEAN : A01ProtocolCacheEntry (lambda val : int (val )),
89+ RoborockZeoProtocol .DETERGENT_EMPTY : A01ProtocolCacheEntry (lambda val : bool (val )),
90+ RoborockZeoProtocol .SOFTENER_EMPTY : A01ProtocolCacheEntry (lambda val : bool (val )),
91+ # rw
92+ RoborockZeoProtocol .MODE : A01ProtocolCacheEntry (lambda val : ZeoMode (val ).name ),
93+ RoborockZeoProtocol .PROGRAM : A01ProtocolCacheEntry (lambda val : ZeoProgram (val ).name ),
94+ RoborockZeoProtocol .TEMP : A01ProtocolCacheEntry (lambda val : ZeoTemperature (val ).name ),
95+ RoborockZeoProtocol .RINSE_TIMES : A01ProtocolCacheEntry (lambda val : ZeoRinse (val ).name ),
96+ RoborockZeoProtocol .SPIN_LEVEL : A01ProtocolCacheEntry (lambda val : ZeoSpin (val ).name ),
97+ RoborockZeoProtocol .DRYING_MODE : A01ProtocolCacheEntry (lambda val : ZeoDryingMode (val ).name ),
98+ RoborockZeoProtocol .DETERGENT_TYPE : A01ProtocolCacheEntry (lambda val : ZeoDetergentType (val ).name ),
99+ RoborockZeoProtocol .SOFTENER_TYPE : A01ProtocolCacheEntry (lambda val : ZeoSoftenerType (val ).name ),
100+ RoborockZeoProtocol .SOUND_SET : A01ProtocolCacheEntry (lambda val : bool (val )),
69101}
70102
71103
72104class RoborockClientA01 (RoborockClient ):
73- def __init__ (self , endpoint : str , device_info : DeviceData ):
74- super ().__init__ (endpoint , device_info )
105+ def __init__ (self , endpoint : str , device_info : DeviceData , category : RoborockCategory , queue_timeout : int = 4 ):
106+ super ().__init__ (endpoint , device_info , queue_timeout )
107+ self .category = category
75108
76109 def on_message_received (self , messages : list [RoborockMessage ]) -> None :
77110 for message in messages :
@@ -87,14 +120,23 @@ def on_message_received(self, messages: list[RoborockMessage]) -> None:
87120 continue
88121 payload_json = json .loads (payload .decode ())
89122 for data_point_number , data_point in payload_json .get ("dps" ).items ():
90- data_point_protocol = RoborockDyadDataProtocol (int (data_point_number ))
91- if data_point_protocol in protocol_entries :
123+ data_point_protocol : RoborockDyadDataProtocol | RoborockZeoProtocol
124+ entries : dict
125+ if self .category == RoborockCategory .WET_DRY_VAC :
126+ data_point_protocol = RoborockDyadDataProtocol (int (data_point_number ))
127+ entries = protocol_entries
128+ elif self .category == RoborockCategory .WASHING_MACHINE :
129+ data_point_protocol = RoborockZeoProtocol (int (data_point_number ))
130+ entries = zeo_data_protocol_entries
131+ else :
132+ continue
133+ if data_point_protocol in entries :
92134 # Auto convert into data struct we want.
93- converted_response = protocol_entries [data_point_protocol ].post_process_fn (data_point )
135+ converted_response = entries [data_point_protocol ].post_process_fn (data_point )
94136 queue = self ._waiting_queue .get (int (data_point_number ))
95137 if queue and queue .protocol == protocol :
96138 queue .resolve ((converted_response , None ))
97139
98- async def update_values (self , dyad_data_protocols : list [RoborockDyadDataProtocol ]):
140+ async def update_values (self , dyad_data_protocols : list [RoborockDyadDataProtocol | RoborockZeoProtocol ]):
99141 """This should handle updating for each given protocol."""
100142 raise NotImplementedError
0 commit comments