1414import struct
1515import time
1616from random import randint
17- from typing import Any , Callable , Coroutine , Optional
17+ from typing import Any , Callable , Coroutine , Mapping , Optional
1818
1919import aiohttp
2020from Crypto .Cipher import AES
@@ -85,8 +85,8 @@ async def request(self, method: str, url: str, params=None, data=None, headers=N
8585
8686
8787class RoborockClient :
88- def __init__ (self , endpoint : str , device_info : RoborockDeviceInfo ) -> None :
89- self .device_info = device_info
88+ def __init__ (self , endpoint : str , devices_info : Mapping [ str , RoborockDeviceInfo ] ) -> None :
89+ self .devices_info = devices_info
9090 self ._endpoint = endpoint
9191 self ._nonce = secrets .token_bytes (16 )
9292 self ._waiting_queue : dict [int , RoborockFuture ] = {}
@@ -200,27 +200,27 @@ def _get_payload(self, method: RoborockCommand, params: Optional[list] = None, s
200200 )
201201 return request_id , timestamp , payload
202202
203- async def send_command (self , method : RoborockCommand , params : Optional [list ] = None ):
203+ async def send_command (self , device_id : str , method : RoborockCommand , params : Optional [list ] = None ):
204204 raise NotImplementedError
205205
206- async def get_status (self ) -> Status | None :
207- status = await self .send_command (RoborockCommand .GET_STATUS )
206+ async def get_status (self , device_id : str ) -> Status | None :
207+ status = await self .send_command (device_id , RoborockCommand .GET_STATUS )
208208 if isinstance (status , dict ):
209209 return Status .from_dict (status )
210210 return None
211211
212- async def get_dnd_timer (self ) -> DNDTimer | None :
212+ async def get_dnd_timer (self , device_id : str ) -> DNDTimer | None :
213213 try :
214- dnd_timer = await self .send_command (RoborockCommand .GET_DND_TIMER )
214+ dnd_timer = await self .send_command (device_id , RoborockCommand .GET_DND_TIMER )
215215 if isinstance (dnd_timer , dict ):
216216 return DNDTimer .from_dict (dnd_timer )
217217 except RoborockTimeout as e :
218218 _LOGGER .error (e )
219219 return None
220220
221- async def get_clean_summary (self ) -> CleanSummary | None :
221+ async def get_clean_summary (self , device_id : str ) -> CleanSummary | None :
222222 try :
223- clean_summary = await self .send_command (RoborockCommand .GET_CLEAN_SUMMARY )
223+ clean_summary = await self .send_command (device_id , RoborockCommand .GET_CLEAN_SUMMARY )
224224 if isinstance (clean_summary , dict ):
225225 return CleanSummary .from_dict (clean_summary )
226226 elif isinstance (clean_summary , list ):
@@ -232,54 +232,55 @@ async def get_clean_summary(self) -> CleanSummary | None:
232232 _LOGGER .error (e )
233233 return None
234234
235- async def get_clean_record (self , record_id : int ) -> CleanRecord | None :
235+ async def get_clean_record (self , device_id : str , record_id : int ) -> CleanRecord | None :
236236 try :
237- clean_record = await self .send_command (RoborockCommand .GET_CLEAN_RECORD , [record_id ])
237+ clean_record = await self .send_command (device_id , RoborockCommand .GET_CLEAN_RECORD , [record_id ])
238238 if isinstance (clean_record , dict ):
239239 return CleanRecord .from_dict (clean_record )
240240 except RoborockTimeout as e :
241241 _LOGGER .error (e )
242242 return None
243243
244- async def get_consumable (self ) -> Consumable | None :
244+ async def get_consumable (self , device_id : str ) -> Consumable | None :
245245 try :
246- consumable = await self .send_command (RoborockCommand .GET_CONSUMABLE )
246+ consumable = await self .send_command (device_id , RoborockCommand .GET_CONSUMABLE )
247247 if isinstance (consumable , dict ):
248248 return Consumable .from_dict (consumable )
249249 except RoborockTimeout as e :
250250 _LOGGER .error (e )
251251 return None
252252
253- async def get_wash_towel_mode (self ) -> WashTowelMode | None :
253+ async def get_wash_towel_mode (self , device_id : str ) -> WashTowelMode | None :
254254 try :
255- washing_mode = await self .send_command (RoborockCommand .GET_WASH_TOWEL_MODE )
255+ washing_mode = await self .send_command (device_id , RoborockCommand .GET_WASH_TOWEL_MODE )
256256 if isinstance (washing_mode , dict ):
257257 return WashTowelMode .from_dict (washing_mode )
258258 except RoborockTimeout as e :
259259 _LOGGER .error (e )
260260 return None
261261
262- async def get_dust_collection_mode (self ) -> DustCollectionMode | None :
262+ async def get_dust_collection_mode (self , device_id : str ) -> DustCollectionMode | None :
263263 try :
264- dust_collection = await self .send_command (RoborockCommand .GET_DUST_COLLECTION_MODE )
264+ dust_collection = await self .send_command (device_id , RoborockCommand .GET_DUST_COLLECTION_MODE )
265265 if isinstance (dust_collection , dict ):
266266 return DustCollectionMode .from_dict (dust_collection )
267267 except RoborockTimeout as e :
268268 _LOGGER .error (e )
269269 return None
270270
271- async def get_smart_wash_params (self ) -> SmartWashParams | None :
271+ async def get_smart_wash_params (self , device_id : str ) -> SmartWashParams | None :
272272 try :
273- mop_wash_mode = await self .send_command (RoborockCommand .GET_SMART_WASH_PARAMS )
273+ mop_wash_mode = await self .send_command (device_id , RoborockCommand .GET_SMART_WASH_PARAMS )
274274 if isinstance (mop_wash_mode , dict ):
275275 return SmartWashParams .from_dict (mop_wash_mode )
276276 except RoborockTimeout as e :
277277 _LOGGER .error (e )
278278 return None
279279
280- async def get_dock_summary (self , dock_type : RoborockEnum ) -> DockSummary | None :
280+ async def get_dock_summary (self , device_id : str , dock_type : RoborockEnum ) -> DockSummary | None :
281281 """Gets the status summary from the dock with the methods available for a given dock.
282282
283+ :param device_id: Device id
283284 :param dock_type: RoborockDockTypeCode"""
284285 try :
285286 commands : list [
@@ -288,11 +289,11 @@ async def get_dock_summary(self, dock_type: RoborockEnum) -> DockSummary | None:
288289 Any ,
289290 DustCollectionMode | WashTowelMode | SmartWashParams | None ,
290291 ]
291- ] = [self .get_dust_collection_mode ()]
292+ ] = [self .get_dust_collection_mode (device_id )]
292293 if dock_type == RoborockDockTypeCode ["3" ]:
293294 commands += [
294- self .get_wash_towel_mode (),
295- self .get_smart_wash_params (),
295+ self .get_wash_towel_mode (device_id ),
296+ self .get_smart_wash_params (device_id ),
296297 ]
297298 [dust_collection_mode , wash_towel_mode , smart_wash_params ] = unpack_list (
298299 list (await asyncio .gather (* commands )), 3
@@ -303,21 +304,21 @@ async def get_dock_summary(self, dock_type: RoborockEnum) -> DockSummary | None:
303304 _LOGGER .error (e )
304305 return None
305306
306- async def get_prop (self ) -> DeviceProp | None :
307+ async def get_prop (self , device_id : str ) -> DeviceProp | None :
307308 [status , dnd_timer , clean_summary , consumable ] = await asyncio .gather (
308309 * [
309- self .get_status (),
310- self .get_dnd_timer (),
311- self .get_clean_summary (),
312- self .get_consumable (),
310+ self .get_status (device_id ),
311+ self .get_dnd_timer (device_id ),
312+ self .get_clean_summary (device_id ),
313+ self .get_consumable (device_id ),
313314 ]
314315 )
315316 last_clean_record = None
316317 if clean_summary and clean_summary .records and len (clean_summary .records ) > 0 :
317- last_clean_record = await self .get_clean_record (clean_summary .records [0 ])
318+ last_clean_record = await self .get_clean_record (device_id , clean_summary .records [0 ])
318319 dock_summary = None
319320 if status and status .dock_type is not None and status .dock_type != RoborockDockTypeCode ["0" ]:
320- dock_summary = await self .get_dock_summary (status .dock_type )
321+ dock_summary = await self .get_dock_summary (device_id , status .dock_type )
321322 if any ([status , dnd_timer , clean_summary , consumable ]):
322323 return DeviceProp (
323324 status ,
@@ -329,27 +330,27 @@ async def get_prop(self) -> DeviceProp | None:
329330 )
330331 return None
331332
332- async def get_multi_maps_list (self ) -> MultiMapsList | None :
333+ async def get_multi_maps_list (self , device_id ) -> MultiMapsList | None :
333334 try :
334- multi_maps_list = await self .send_command (RoborockCommand .GET_MULTI_MAPS_LIST )
335+ multi_maps_list = await self .send_command (device_id , RoborockCommand .GET_MULTI_MAPS_LIST )
335336 if isinstance (multi_maps_list , dict ):
336337 return MultiMapsList .from_dict (multi_maps_list )
337338 except RoborockTimeout as e :
338339 _LOGGER .error (e )
339340 return None
340341
341- async def get_networking (self ) -> NetworkInfo | None :
342+ async def get_networking (self , device_id ) -> NetworkInfo | None :
342343 try :
343- networking_info = await self .send_command (RoborockCommand .GET_NETWORK_INFO )
344+ networking_info = await self .send_command (device_id , RoborockCommand .GET_NETWORK_INFO )
344345 if isinstance (networking_info , dict ):
345346 return NetworkInfo .from_dict (networking_info )
346347 except RoborockTimeout as e :
347348 _LOGGER .error (e )
348349 return None
349350
350- async def get_room_mapping (self ) -> list [RoomMapping ]:
351+ async def get_room_mapping (self , device_id : str ) -> list [RoomMapping ]:
351352 """Gets the mapping from segment id -> iot id. Only works on local api."""
352- mapping = await self .send_command (RoborockCommand .GET_ROOM_MAPPING )
353+ mapping = await self .send_command (device_id , RoborockCommand .GET_ROOM_MAPPING )
353354 if isinstance (mapping , list ):
354355 return [
355356 RoomMapping (segment_id = segment_id , iot_id = iot_id ) # type: ignore
0 commit comments