@@ -691,6 +691,103 @@ async def set_vacuum_mode(self, serial: str, value: str):
691691 raise
692692
693693
694+ async def exec_device_command (self , serial : str , action : str ):
695+ """Execute a device command via execCmdService.
696+
697+ Discovered actions for the Luma Smart Litter Box:
698+ CLEAN / STOP_CLEAN / SUSPEND_CLEAN / RESTART_CLEAN
699+ EMPTY / STOP_EMPTY / RESTART_EMPTY
700+ LEVELING / RESTART_LEVELING
701+ VACUUM (air purifier)
702+ OPEN_DOOR / CLOSE_DOOR
703+ STOP / CANCEL
704+ """
705+ _LOGGER .debug (f"Executing device command: serial={ serial } , action={ action } " )
706+ try :
707+ request_id = str (uuid .uuid4 ()).replace ("-" , "" )
708+ response = await self .session .post ("/device/device/execCmdService" , json = {
709+ "deviceSn" : serial ,
710+ "action" : action ,
711+ "requestId" : request_id ,
712+ })
713+ _LOGGER .debug (f"execCmdService({ action } ) returned: { response } " )
714+ return response
715+ except Exception as e :
716+ _LOGGER .error (f"Failed to exec command { action } for device { serial } : { e } " )
717+ raise
718+
719+ async def trigger_manual_clean (self , serial : str ):
720+ """Trigger a manual clean cycle on a litter box device."""
721+ return await self .exec_device_command (serial , "CLEAN" )
722+
723+ async def trigger_empty_waste (self , serial : str ):
724+ """Trigger waste bin emptying on a litter box device."""
725+ return await self .exec_device_command (serial , "EMPTY" )
726+
727+ async def trigger_level_litter (self , serial : str ):
728+ """Trigger litter leveling on a litter box device."""
729+ return await self .exec_device_command (serial , "LEVELING" )
730+
731+ async def trigger_stop_device_action (self , serial : str ):
732+ """Stop the current device action."""
733+ return await self .exec_device_command (serial , "STOP" )
734+
735+ async def trigger_open_door (self , serial : str ):
736+ """Open the litter box door."""
737+ return await self .exec_device_command (serial , "OPEN_DOOR" )
738+
739+ async def trigger_close_door (self , serial : str ):
740+ """Close the litter box door."""
741+ return await self .exec_device_command (serial , "CLOSE_DOOR" )
742+
743+ async def trigger_vacuum (self , serial : str ):
744+ """Trigger the air purifier (vacuum) on a litter box device."""
745+ return await self .exec_device_command (serial , "VACUUM" )
746+
747+ async def set_clean_mode (self , serial : str , clean_mode : str , auto_delay_sec : int = 60 ):
748+ """Set the litter box clean mode (AUTO/MANUAL) and auto-delay."""
749+ _LOGGER .debug (f"Setting clean mode: serial={ serial } , mode={ clean_mode } , delay={ auto_delay_sec } " )
750+ try :
751+ response = await self .session .post ("/device/setting/updateCleanModeSetting" , json = {
752+ "deviceSn" : serial ,
753+ "cleanMode" : clean_mode ,
754+ "autoDelaySec" : auto_delay_sec ,
755+ })
756+ _LOGGER .debug (f"Clean mode update returned code: { response } " )
757+ return response
758+ except Exception as e :
759+ _LOGGER .error (f"Failed to set clean mode for device { serial } : { e } " )
760+ raise
761+
762+ async def set_deodorization_setting (self , serial : str , mode : str , switch : bool ):
763+ """Update deodorization mode and master switch."""
764+ _LOGGER .debug (f"Setting deodorization: serial={ serial } , mode={ mode } , switch={ switch } " )
765+ try :
766+ response = await self .session .post ("/device/setting/updateDeodorizationSetting" , json = {
767+ "deviceSn" : serial ,
768+ "deodorizationMode" : mode ,
769+ "deodorizationModeSwitch" : switch ,
770+ })
771+ _LOGGER .debug (f"Deodorization setting returned code: { response } " )
772+ return response
773+ except Exception as e :
774+ _LOGGER .error (f"Failed to set deodorization for device { serial } : { e } " )
775+ raise
776+
777+ async def set_volume (self , serial : str , volume : int ):
778+ """Set speaker volume (0-100)."""
779+ _LOGGER .debug (f"Setting volume: serial={ serial } , volume={ volume } " )
780+ try :
781+ response = await self .session .post ("/device/setting/updateVolumeSetting" , json = {
782+ "deviceSn" : serial ,
783+ "volume" : volume ,
784+ })
785+ _LOGGER .debug (f"Volume setting returned code: { response } " )
786+ return response
787+ except Exception as e :
788+ _LOGGER .error (f"Failed to set volume for device { serial } : { e } " )
789+ raise
790+
694791 # Not supported by the dockstream device firmware yet. hoping that maybe it will be in the future, so leaving code here.
695792 # async def set_water_sensing_delay(self, serial: str, value: float, current_mode: int):
696793 # """Set the water sensing delay."""
0 commit comments