2727import json
2828import logging
2929import threading
30+ from collections .abc import Callable
3031from dataclasses import asdict , dataclass
3132from pathlib import Path
3233from typing import Any , cast
4344from roborock .devices .cache import Cache , CacheData
4445from roborock .devices .device import RoborockDevice
4546from roborock .devices .device_manager import DeviceManager , create_device_manager , create_home_data_api
47+ from roborock .devices .traits import Trait
48+ from roborock .devices .traits .v1 import V1TraitMixin
4649from roborock .protocol import MessageParser
4750from roborock .version_1_apis .roborock_mqtt_client_v1 import RoborockMqttClientV1
4851from roborock .web_api import RoborockApiClient
@@ -377,23 +380,30 @@ async def execute_scene(ctx, scene_id):
377380 await client .execute_scene (cache_data .user_data , scene_id )
378381
379382
383+ async def _v1_trait (context : RoborockContext , device_id : str , display_func : Callable [[], V1TraitMixin ]) -> Trait :
384+ device_manager = await context .get_device_manager ()
385+ device = await device_manager .get_device (device_id )
386+ if device .v1_properties is None :
387+ raise RoborockException (f"Device { device .name } does not support V1 protocol" )
388+
389+ trait = display_func (device .v1_properties )
390+ await trait .refresh ()
391+ return trait
392+
393+
394+ async def _display_v1_trait (context : RoborockContext , device_id : str , display_func : Callable [[], Trait ]) -> None :
395+ trait = await _v1_trait (context , device_id , display_func )
396+ click .echo (dump_json (trait .as_dict ()))
397+
398+
380399@session .command ()
381400@click .option ("--device_id" , required = True )
382401@click .pass_context
383402@async_command
384403async def status (ctx , device_id : str ):
385404 """Get device status."""
386405 context : RoborockContext = ctx .obj
387-
388- device_manager = await context .get_device_manager ()
389- device = await device_manager .get_device (device_id )
390-
391- if not (status_trait := device .traits .get ("status" )):
392- click .echo (f"Device { device .name } does not have a status trait" )
393- return
394-
395- status_result = await status_trait .get_status ()
396- click .echo (dump_json (status_result .as_dict ()))
406+ await _display_v1_trait (context , device_id , lambda v1 : v1 .status )
397407
398408
399409@session .command ()
@@ -403,15 +413,7 @@ async def status(ctx, device_id: str):
403413async def clean_summary (ctx , device_id : str ):
404414 """Get device clean summary."""
405415 context : RoborockContext = ctx .obj
406-
407- device_manager = await context .get_device_manager ()
408- device = await device_manager .get_device (device_id )
409- if not (clean_summary_trait := device .traits .get ("clean_summary" )):
410- click .echo (f"Device { device .name } does not have a clean summary trait" )
411- return
412-
413- clean_summary_result = await clean_summary_trait .get_clean_summary ()
414- click .echo (dump_json (clean_summary_result .as_dict ()))
416+ await _display_v1_trait (context , device_id , lambda v1 : v1 .clean_summary )
415417
416418
417419@session .command ()
@@ -421,17 +423,7 @@ async def clean_summary(ctx, device_id: str):
421423async def volume (ctx , device_id : str ):
422424 """Get device volume."""
423425 context : RoborockContext = ctx .obj
424-
425- device_manager = await context .get_device_manager ()
426- device = await device_manager .get_device (device_id )
427-
428- if not (volume_trait := device .traits .get ("sound_volume" )):
429- click .echo (f"Device { device .name } does not have a volume trait" )
430- return
431-
432- volume_result = await volume_trait .get_volume ()
433- click .echo (f"Device { device_id } volume:" )
434- click .echo (volume_result )
426+ await _display_v1_trait (context , device_id , lambda v1 : v1 .sound_volume )
435427
436428
437429@session .command ()
@@ -442,14 +434,7 @@ async def volume(ctx, device_id: str):
442434async def set_volume (ctx , device_id : str , volume : int ):
443435 """Set the devicevolume."""
444436 context : RoborockContext = ctx .obj
445-
446- device_manager = await context .get_device_manager ()
447- device = await device_manager .get_device (device_id )
448-
449- if not (volume_trait := device .traits .get ("sound_volume" )):
450- click .echo (f"Device { device .name } does not have a volume trait" )
451- return
452-
437+ volume_trait = await _v1_trait (context , device_id , lambda v1 : v1 .sound_volume )
453438 await volume_trait .set_volume (volume )
454439 click .echo (f"Set Device { device_id } volume to { volume } " )
455440
0 commit comments