1313import struct
1414import time
1515from random import randint
16- from typing import Any , Callable , Coroutine , Optional , Type
16+ from typing import Any , Callable , Coroutine , Optional , Type , TypeVar
1717
1818import aiohttp
1919
3030 ModelStatus ,
3131 MultiMapsList ,
3232 NetworkInfo ,
33+ RoborockBase ,
3334 RoomMapping ,
3435 S7MaxVStatus ,
3536 SmartWashParams ,
6364 RoborockCommand .GET_MAP_V1 ,
6465 RoborockCommand .GET_MULTI_MAP ,
6566]
67+ RT = TypeVar ("RT" , bound = RoborockBase )
6668
6769
6870def md5hex (message : str ) -> str :
@@ -228,36 +230,32 @@ def _get_payload(
228230 )
229231 return request_id , timestamp , payload
230232
231- async def send_command (self , method : RoborockCommand , params : Optional [list | dict ] = None ):
233+ async def send_command (
234+ self ,
235+ method : RoborockCommand ,
236+ params : Optional [list | dict ] = None ,
237+ return_type : Optional [Type [RT ]] = None ,
238+ ) -> RT :
232239 raise NotImplementedError
233240
234241 @fallback_cache
235242 async def get_status (self ) -> Status | None :
236- status = await self .send_command (RoborockCommand .GET_STATUS )
237- if isinstance (status , dict ):
238- _cls : Type [Status ] = ModelStatus .get (
239- self .device_info .model , S7MaxVStatus
240- ) # Default to S7 MAXV if we don't have the data
241- return _cls .from_dict (status )
242- return None
243+ _cls : Type [Status ] = ModelStatus .get (
244+ self .device_info .model , S7MaxVStatus
245+ ) # Default to S7 MAXV if we don't have the data
246+ return await self .send_command (RoborockCommand .GET_STATUS , return_type = _cls )
243247
244248 @fallback_cache
245249 async def get_dnd_timer (self ) -> DnDTimer | None :
246- dnd_timer = await self .send_command (RoborockCommand .GET_DND_TIMER )
247- if isinstance (dnd_timer , dict ):
248- return DnDTimer .from_dict (dnd_timer )
249- return None
250+ return await self .send_command (RoborockCommand .GET_DND_TIMER , return_type = DnDTimer )
250251
251252 @fallback_cache
252253 async def get_valley_electricity_timer (self ) -> ValleyElectricityTimer | None :
253- valley_electricity_timer = await self .send_command (RoborockCommand .GET_VALLEY_ELECTRICITY_TIMER )
254- if isinstance (valley_electricity_timer , dict ):
255- return ValleyElectricityTimer .from_dict (valley_electricity_timer )
256- return None
254+ return await self .send_command (RoborockCommand .GET_VALLEY_ELECTRICITY_TIMER , return_type = ValleyElectricityTimer )
257255
258256 @fallback_cache
259257 async def get_clean_summary (self ) -> CleanSummary | None :
260- clean_summary = await self .send_command (RoborockCommand .GET_CLEAN_SUMMARY )
258+ clean_summary : dict | list | int = await self .send_command (RoborockCommand .GET_CLEAN_SUMMARY )
261259 if isinstance (clean_summary , dict ):
262260 return CleanSummary .from_dict (clean_summary )
263261 elif isinstance (clean_summary , list ):
@@ -274,38 +272,23 @@ async def get_clean_summary(self) -> CleanSummary | None:
274272
275273 @fallback_cache
276274 async def get_clean_record (self , record_id : int ) -> CleanRecord | None :
277- clean_record = await self .send_command (RoborockCommand .GET_CLEAN_RECORD , [record_id ])
278- if isinstance (clean_record , dict ):
279- return CleanRecord .from_dict (clean_record )
280- return None
275+ return await self .send_command (RoborockCommand .GET_CLEAN_RECORD , [record_id ], return_type = CleanRecord )
281276
282277 @fallback_cache
283278 async def get_consumable (self ) -> Consumable | None :
284- consumable = await self .send_command (RoborockCommand .GET_CONSUMABLE )
285- if isinstance (consumable , dict ):
286- return Consumable .from_dict (consumable )
287- return None
279+ return await self .send_command (RoborockCommand .GET_CONSUMABLE , return_type = Consumable )
288280
289281 @fallback_cache
290282 async def get_wash_towel_mode (self ) -> WashTowelMode | None :
291- washing_mode = await self .send_command (RoborockCommand .GET_WASH_TOWEL_MODE )
292- if isinstance (washing_mode , dict ):
293- return WashTowelMode .from_dict (washing_mode )
294- return None
283+ return await self .send_command (RoborockCommand .GET_WASH_TOWEL_MODE , return_type = WashTowelMode )
295284
296285 @fallback_cache
297286 async def get_dust_collection_mode (self ) -> DustCollectionMode | None :
298- dust_collection = await self .send_command (RoborockCommand .GET_DUST_COLLECTION_MODE )
299- if isinstance (dust_collection , dict ):
300- return DustCollectionMode .from_dict (dust_collection )
301- return None
287+ return await self .send_command (RoborockCommand .GET_DUST_COLLECTION_MODE , return_type = DustCollectionMode )
302288
303289 @fallback_cache
304290 async def get_smart_wash_params (self ) -> SmartWashParams | None :
305- mop_wash_mode = await self .send_command (RoborockCommand .GET_SMART_WASH_PARAMS )
306- if isinstance (mop_wash_mode , dict ):
307- return SmartWashParams .from_dict (mop_wash_mode )
308- return None
291+ return await self .send_command (RoborockCommand .GET_SMART_WASH_PARAMS , return_type = SmartWashParams )
309292
310293 @fallback_cache
311294 async def get_dock_summary (self , dock_type : RoborockDockTypeCode ) -> DockSummary | None :
@@ -359,22 +342,16 @@ async def get_prop(self) -> DeviceProp | None:
359342
360343 @fallback_cache
361344 async def get_multi_maps_list (self ) -> MultiMapsList | None :
362- multi_maps_list = await self .send_command (RoborockCommand .GET_MULTI_MAPS_LIST )
363- if isinstance (multi_maps_list , dict ):
364- return MultiMapsList .from_dict (multi_maps_list )
365- return None
345+ return await self .send_command (RoborockCommand .GET_MULTI_MAPS_LIST , return_type = MultiMapsList )
366346
367347 @fallback_cache
368348 async def get_networking (self ) -> NetworkInfo | None :
369- networking_info = await self .send_command (RoborockCommand .GET_NETWORK_INFO )
370- if isinstance (networking_info , dict ):
371- return NetworkInfo .from_dict (networking_info )
372- return None
349+ return await self .send_command (RoborockCommand .GET_NETWORK_INFO , return_type = NetworkInfo )
373350
374351 @fallback_cache
375352 async def get_room_mapping (self ) -> list [RoomMapping ] | None :
376353 """Gets the mapping from segment id -> iot id. Only works on local api."""
377- mapping = await self .send_command (RoborockCommand .GET_ROOM_MAPPING )
354+ mapping : list = await self .send_command (RoborockCommand .GET_ROOM_MAPPING )
378355 if isinstance (mapping , list ):
379356 return [
380357 RoomMapping (segment_id = segment_id , iot_id = iot_id ) # type: ignore
@@ -385,10 +362,7 @@ async def get_room_mapping(self) -> list[RoomMapping] | None:
385362 @fallback_cache
386363 async def get_child_lock_status (self ) -> ChildLockStatus | None :
387364 """Gets current child lock status."""
388- child_lock_status = await self .send_command (RoborockCommand .GET_CHILD_LOCK_STATUS )
389- if isinstance (child_lock_status , dict ):
390- return ChildLockStatus .from_dict (child_lock_status )
391- return None
365+ return await self .send_command (RoborockCommand .GET_CHILD_LOCK_STATUS , return_type = ChildLockStatus )
392366
393367 @fallback_cache
394368 async def get_sound_volume (self ) -> int | None :
0 commit comments