roborock.devices.traits.v1.clean_summary
1import logging 2from typing import Self 3 4from roborock.data import CleanRecord, CleanSummaryWithDetail 5from roborock.devices.traits.v1 import common 6from roborock.roborock_typing import RoborockCommand 7from roborock.util import unpack_list 8 9_LOGGER = logging.getLogger(__name__) 10 11 12class CleanSummaryTrait(CleanSummaryWithDetail, common.V1TraitMixin): 13 """Trait for managing the clean summary of Roborock devices.""" 14 15 command = RoborockCommand.GET_CLEAN_SUMMARY 16 17 async def refresh(self) -> None: 18 """Refresh the clean summary data and last clean record. 19 20 Assumes that the clean summary has already been fetched. 21 """ 22 await super().refresh() 23 if not self.records: 24 _LOGGER.debug("No clean records available in clean summary.") 25 self.last_clean_record = None 26 return 27 last_record_id = self.records[0] 28 self.last_clean_record = await self.get_clean_record(last_record_id) 29 30 @classmethod 31 def _parse_type_response(cls, response: common.V1ResponseData) -> Self: 32 """Parse the response from the device into a CleanSummary.""" 33 if isinstance(response, dict): 34 return cls.from_dict(response) 35 elif isinstance(response, list): 36 clean_time, clean_area, clean_count, records = unpack_list(response, 4) 37 return cls( 38 clean_time=clean_time, 39 clean_area=clean_area, 40 clean_count=clean_count, 41 records=records, 42 ) 43 elif isinstance(response, int): 44 return cls(clean_time=response) 45 raise ValueError(f"Unexpected clean summary format: {response!r}") 46 47 async def get_clean_record(self, record_id: int) -> CleanRecord: 48 """Load a specific clean record by ID.""" 49 response = await self.rpc_channel.send_command(RoborockCommand.GET_CLEAN_RECORD, params=[record_id]) 50 return self._parse_clean_record_response(response) 51 52 @classmethod 53 def _parse_clean_record_response(cls, response: common.V1ResponseData) -> CleanRecord: 54 """Parse the response from the device into a CleanRecord.""" 55 if isinstance(response, list) and len(response) == 1: 56 response = response[0] 57 if isinstance(response, dict): 58 return CleanRecord.from_dict(response) 59 if isinstance(response, list): 60 if isinstance(response[-1], dict): 61 records = [CleanRecord.from_dict(rec) for rec in response] 62 final_record = records[-1] 63 try: 64 # This code is semi-presumptuous - so it is put in a try finally to be safe. 65 final_record.begin = records[0].begin 66 final_record.begin_datetime = records[0].begin_datetime 67 final_record.start_type = records[0].start_type 68 for rec in records[0:-1]: 69 final_record.duration = (final_record.duration or 0) + (rec.duration or 0) 70 final_record.area = (final_record.area or 0) + (rec.area or 0) 71 final_record.avoid_count = (final_record.avoid_count or 0) + (rec.avoid_count or 0) 72 final_record.wash_count = (final_record.wash_count or 0) + (rec.wash_count or 0) 73 final_record.square_meter_area = (final_record.square_meter_area or 0) + ( 74 rec.square_meter_area or 0 75 ) 76 return final_record 77 except Exception: 78 # Return final record when an exception occurred 79 return final_record 80 # There are still a few unknown variables in this. 81 begin, end, duration, area = unpack_list(response, 4) 82 return CleanRecord(begin=begin, end=end, duration=duration, area=area) 83 raise ValueError(f"Unexpected clean record format: {response!r}")
class
CleanSummaryTrait(roborock.data.v1.v1_containers.CleanSummaryWithDetail, roborock.devices.traits.v1.common.V1TraitMixin):
13class CleanSummaryTrait(CleanSummaryWithDetail, common.V1TraitMixin): 14 """Trait for managing the clean summary of Roborock devices.""" 15 16 command = RoborockCommand.GET_CLEAN_SUMMARY 17 18 async def refresh(self) -> None: 19 """Refresh the clean summary data and last clean record. 20 21 Assumes that the clean summary has already been fetched. 22 """ 23 await super().refresh() 24 if not self.records: 25 _LOGGER.debug("No clean records available in clean summary.") 26 self.last_clean_record = None 27 return 28 last_record_id = self.records[0] 29 self.last_clean_record = await self.get_clean_record(last_record_id) 30 31 @classmethod 32 def _parse_type_response(cls, response: common.V1ResponseData) -> Self: 33 """Parse the response from the device into a CleanSummary.""" 34 if isinstance(response, dict): 35 return cls.from_dict(response) 36 elif isinstance(response, list): 37 clean_time, clean_area, clean_count, records = unpack_list(response, 4) 38 return cls( 39 clean_time=clean_time, 40 clean_area=clean_area, 41 clean_count=clean_count, 42 records=records, 43 ) 44 elif isinstance(response, int): 45 return cls(clean_time=response) 46 raise ValueError(f"Unexpected clean summary format: {response!r}") 47 48 async def get_clean_record(self, record_id: int) -> CleanRecord: 49 """Load a specific clean record by ID.""" 50 response = await self.rpc_channel.send_command(RoborockCommand.GET_CLEAN_RECORD, params=[record_id]) 51 return self._parse_clean_record_response(response) 52 53 @classmethod 54 def _parse_clean_record_response(cls, response: common.V1ResponseData) -> CleanRecord: 55 """Parse the response from the device into a CleanRecord.""" 56 if isinstance(response, list) and len(response) == 1: 57 response = response[0] 58 if isinstance(response, dict): 59 return CleanRecord.from_dict(response) 60 if isinstance(response, list): 61 if isinstance(response[-1], dict): 62 records = [CleanRecord.from_dict(rec) for rec in response] 63 final_record = records[-1] 64 try: 65 # This code is semi-presumptuous - so it is put in a try finally to be safe. 66 final_record.begin = records[0].begin 67 final_record.begin_datetime = records[0].begin_datetime 68 final_record.start_type = records[0].start_type 69 for rec in records[0:-1]: 70 final_record.duration = (final_record.duration or 0) + (rec.duration or 0) 71 final_record.area = (final_record.area or 0) + (rec.area or 0) 72 final_record.avoid_count = (final_record.avoid_count or 0) + (rec.avoid_count or 0) 73 final_record.wash_count = (final_record.wash_count or 0) + (rec.wash_count or 0) 74 final_record.square_meter_area = (final_record.square_meter_area or 0) + ( 75 rec.square_meter_area or 0 76 ) 77 return final_record 78 except Exception: 79 # Return final record when an exception occurred 80 return final_record 81 # There are still a few unknown variables in this. 82 begin, end, duration, area = unpack_list(response, 4) 83 return CleanRecord(begin=begin, end=end, duration=duration, area=area) 84 raise ValueError(f"Unexpected clean record format: {response!r}")
Trait for managing the clean summary of Roborock devices.
async def
refresh(self) -> None:
18 async def refresh(self) -> None: 19 """Refresh the clean summary data and last clean record. 20 21 Assumes that the clean summary has already been fetched. 22 """ 23 await super().refresh() 24 if not self.records: 25 _LOGGER.debug("No clean records available in clean summary.") 26 self.last_clean_record = None 27 return 28 last_record_id = self.records[0] 29 self.last_clean_record = await self.get_clean_record(last_record_id)
Refresh the clean summary data and last clean record.
Assumes that the clean summary has already been fetched.
48 async def get_clean_record(self, record_id: int) -> CleanRecord: 49 """Load a specific clean record by ID.""" 50 response = await self.rpc_channel.send_command(RoborockCommand.GET_CLEAN_RECORD, params=[record_id]) 51 return self._parse_clean_record_response(response)
Load a specific clean record by ID.