roborock.data.b01_q7.b01_q7_containers
1import datetime 2import json 3from dataclasses import dataclass, field 4from functools import cached_property 5 6from ...exceptions import RoborockException 7from ..containers import RoborockBase 8from .b01_q7_code_mappings import ( 9 B01Fault, 10 CleanPathPreferenceMapping, 11 CleanRepeatMapping, 12 CleanTypeMapping, 13 DustCollectionStateMapping, 14 SCWindMapping, 15 StationStateMapping, 16 WaterLevelMapping, 17 WorkModeMapping, 18 WorkStatusMapping, 19) 20 21 22@dataclass 23class NetStatus(RoborockBase): 24 """Represents the network status of the device.""" 25 26 rssi: str 27 loss: int 28 ping: int 29 ip: str 30 mac: str 31 ssid: str 32 frequency: int 33 bssid: str 34 35 36@dataclass 37class OrderTotal(RoborockBase): 38 """Represents the order total information.""" 39 40 total: int 41 enable: int 42 43 44@dataclass 45class Privacy(RoborockBase): 46 """Represents the privacy settings of the device.""" 47 48 ai_recognize: int 49 dirt_recognize: int 50 pet_recognize: int 51 carpet_turbo: int 52 carpet_avoid: int 53 carpet_show: int 54 map_uploads: int 55 ai_agent: int 56 ai_avoidance: int 57 record_uploads: int 58 along_floor: int 59 auto_upgrade: int 60 61 62@dataclass 63class PvCharging(RoborockBase): 64 """Represents the photovoltaic charging status.""" 65 66 status: int 67 begin_time: int 68 end_time: int 69 70 71@dataclass 72class Recommend(RoborockBase): 73 """Represents cleaning recommendations.""" 74 75 sill: int 76 wall: int 77 room_id: list[int] = field(default_factory=list) 78 79 80@dataclass 81class Q7MapListEntry(RoborockBase): 82 """Single map list entry returned by `service.get_map_list`.""" 83 84 id: int | None = None 85 cur: bool | None = None 86 87 88@dataclass 89class Q7MapList(RoborockBase): 90 """Map list response returned by `service.get_map_list`.""" 91 92 map_list: list[Q7MapListEntry] = field(default_factory=list) 93 94 @property 95 def current_map_id(self) -> int | None: 96 """Current map id, preferring the entry marked current.""" 97 if not self.map_list: 98 return None 99 100 ordered = sorted(self.map_list, key=lambda entry: entry.cur or False, reverse=True) 101 first = next(iter(ordered), None) 102 if first is None or not isinstance(first.id, int): 103 return None 104 return first.id 105 106 107@dataclass 108class B01Props(RoborockBase): 109 """ 110 Represents the complete properties and status for a Roborock B01 model. 111 This dataclass is generated based on the device's status JSON object. 112 """ 113 114 status: WorkStatusMapping | None = None 115 fault: B01Fault | None = None 116 wind: SCWindMapping | None = None 117 water: WaterLevelMapping | None = None 118 mode: CleanTypeMapping | None = None 119 quantity: int | None = None # The Q7 L5 reports its battery level as 'quantity' 120 alarm: int | None = None 121 volume: int | None = None 122 hypa: int | None = None 123 main_brush: int | None = None 124 side_brush: int | None = None 125 mop_life: int | None = None 126 main_sensor: int | None = None 127 net_status: NetStatus | None = None 128 repeat_state: CleanRepeatMapping | None = None 129 tank_state: int | None = None 130 sweep_type: int | None = None 131 clean_path_preference: CleanPathPreferenceMapping | None = None 132 cloth_state: int | None = None 133 time_zone: int | None = None 134 time_zone_info: str | None = None 135 language: int | None = None 136 cleaning_time: int | None = None 137 real_clean_time: int | None = None 138 cleaning_area: int | None = None 139 custom_type: int | None = None 140 sound: int | None = None 141 work_mode: WorkModeMapping | None = None 142 station_act: StationStateMapping | None = None 143 charge_state: int | None = None 144 current_map_id: int | None = None 145 map_num: int | None = None 146 dust_action: DustCollectionStateMapping | None = None # Read-only; prop.set is rejected with code 1 on the Q7 M5+. 147 quiet_is_open: int | None = None 148 quiet_begin_time: int | None = None 149 quiet_end_time: int | None = None 150 clean_finish: int | None = None 151 voice_type: int | None = None 152 voice_type_version: int | None = None 153 order_total: OrderTotal | None = None 154 build_map: int | None = None 155 privacy: Privacy | None = None 156 dust_auto_state: int | None = None 157 dust_frequency: int | None = None 158 child_lock: int | None = None 159 multi_floor: int | None = None 160 map_save: int | None = None 161 light_mode: int | None = None 162 green_laser: int | None = None 163 dust_bag_used: int | None = None 164 order_save_mode: int | None = None 165 manufacturer: str | None = None 166 back_to_wash: int | None = None 167 charge_station_type: int | None = None 168 pv_cut_charge: int | None = None 169 pv_charging: PvCharging | None = None 170 serial_number: str | None = None 171 recommend: Recommend | None = None 172 add_sweep_status: int | None = None 173 174 @property 175 def battery(self) -> int | None: 176 """ 177 Returns device battery level as a percentage. 178 """ 179 return self.quantity 180 181 @property 182 def main_brush_time_left(self) -> int | None: 183 """ 184 Returns estimated remaining life of the main brush in minutes. 185 Total life is 300 hours (18000 minutes). 186 """ 187 if self.main_brush is None: 188 return None 189 return max(0, 18000 - self.main_brush) 190 191 @property 192 def side_brush_time_left(self) -> int | None: 193 """ 194 Returns estimated remaining life of the side brush in minutes. 195 Total life is 200 hours (12000 minutes). 196 """ 197 if self.side_brush is None: 198 return None 199 return max(0, 12000 - self.side_brush) 200 201 @property 202 def filter_time_left(self) -> int | None: 203 """ 204 Returns estimated remaining life of the filter (hypa) in minutes. 205 Total life is 150 hours (9000 minutes). 206 """ 207 if self.hypa is None: 208 return None 209 return max(0, 9000 - self.hypa) 210 211 @property 212 def mop_life_time_left(self) -> int | None: 213 """ 214 Returns estimated remaining life of the mop in minutes. 215 Total life is 180 hours (10800 minutes). 216 """ 217 if self.mop_life is None: 218 return None 219 return max(0, 10800 - self.mop_life) 220 221 @property 222 def sensor_dirty_time_left(self) -> int | None: 223 """ 224 Returns estimated time until sensors need cleaning in minutes. 225 Maintenance interval is typically 30 hours (1800 minutes). 226 """ 227 if self.main_sensor is None: 228 return None 229 return max(0, 1800 - self.main_sensor) 230 231 @property 232 def status_name(self) -> str | None: 233 """Returns the name of the current status.""" 234 return self.status.value if self.status is not None else None 235 236 @property 237 def fault_name(self) -> str | None: 238 """Returns the name of the current fault.""" 239 return self.fault.value if self.fault is not None else None 240 241 @property 242 def wind_name(self) -> str | None: 243 """Returns the name of the current fan speed (wind).""" 244 return self.wind.value if self.wind is not None else None 245 246 @property 247 def work_mode_name(self) -> str | None: 248 """Returns the name of the current work mode.""" 249 return self.work_mode.value if self.work_mode is not None else None 250 251 @property 252 def repeat_state_name(self) -> str | None: 253 """Returns the name of the current repeat state.""" 254 return self.repeat_state.value if self.repeat_state is not None else None 255 256 @property 257 def clean_path_preference_name(self) -> str | None: 258 """Returns the name of the current clean path preference.""" 259 return self.clean_path_preference.value if self.clean_path_preference is not None else None 260 261 262@dataclass 263class CleanRecordDetail(RoborockBase): 264 """Represents a single clean record detail (from `record_list[].detail`).""" 265 266 record_start_time: int | None = None 267 method: int | None = None 268 record_use_time: int | None = None 269 clean_count: int | None = None 270 # This is seemingly returned in meters (non-squared) 271 record_clean_area: int | None = None 272 record_clean_mode: int | None = None 273 record_clean_way: int | None = None 274 record_task_status: int | None = None 275 record_faultcode: int | None = None 276 record_dust_num: int | None = None 277 clean_current_map: int | None = None 278 record_map_url: str | None = None 279 280 @property 281 def start_datetime(self) -> datetime.datetime | None: 282 """Convert the start datetime into a datetime object.""" 283 if self.record_start_time is not None: 284 return datetime.datetime.fromtimestamp(self.record_start_time).astimezone(datetime.UTC) 285 return None 286 287 @property 288 def square_meters_area_cleaned(self) -> float | None: 289 """Returns the area cleaned in square meters.""" 290 if self.record_clean_area is not None: 291 return self.record_clean_area / 100 292 return None 293 294 295@dataclass 296class CleanRecordListItem(RoborockBase): 297 """Represents an entry in the clean record list returned by `service.get_record_list`.""" 298 299 url: str | None = None 300 detail: str | None = None 301 302 @cached_property 303 def detail_parsed(self) -> CleanRecordDetail | None: 304 """Parse and return the detail as a CleanRecordDetail object.""" 305 if self.detail is None: 306 return None 307 try: 308 parsed = json.loads(self.detail) 309 except json.JSONDecodeError as ex: 310 raise RoborockException(f"Invalid B01 record detail JSON: {self.detail!r}") from ex 311 return CleanRecordDetail.from_dict(parsed) 312 313 314@dataclass 315class CleanRecordList(RoborockBase): 316 """Represents the clean record list response from `service.get_record_list`.""" 317 318 total_area: int | None = None 319 total_time: int | None = None # stored in seconds 320 total_count: int | None = None 321 record_list: list[CleanRecordListItem] = field(default_factory=list) 322 323 @property 324 def square_meters_area_cleaned(self) -> float | None: 325 """Returns the area cleaned in square meters.""" 326 if self.total_area is not None: 327 return self.total_area / 100 328 return None 329 330 331@dataclass 332class CleanRecordSummary(RoborockBase): 333 """Represents clean record totals for B01/Q7 devices.""" 334 335 total_time: int | None = None 336 total_area: int | None = None 337 total_count: int | None = None 338 last_record_detail: CleanRecordDetail | None = None
23@dataclass 24class NetStatus(RoborockBase): 25 """Represents the network status of the device.""" 26 27 rssi: str 28 loss: int 29 ping: int 30 ip: str 31 mac: str 32 ssid: str 33 frequency: int 34 bssid: str
Represents the network status of the device.
Inherited Members
37@dataclass 38class OrderTotal(RoborockBase): 39 """Represents the order total information.""" 40 41 total: int 42 enable: int
Represents the order total information.
Inherited Members
45@dataclass 46class Privacy(RoborockBase): 47 """Represents the privacy settings of the device.""" 48 49 ai_recognize: int 50 dirt_recognize: int 51 pet_recognize: int 52 carpet_turbo: int 53 carpet_avoid: int 54 carpet_show: int 55 map_uploads: int 56 ai_agent: int 57 ai_avoidance: int 58 record_uploads: int 59 along_floor: int 60 auto_upgrade: int
Represents the privacy settings of the device.
Inherited Members
63@dataclass 64class PvCharging(RoborockBase): 65 """Represents the photovoltaic charging status.""" 66 67 status: int 68 begin_time: int 69 end_time: int
Represents the photovoltaic charging status.
Inherited Members
72@dataclass 73class Recommend(RoborockBase): 74 """Represents cleaning recommendations.""" 75 76 sill: int 77 wall: int 78 room_id: list[int] = field(default_factory=list)
Represents cleaning recommendations.
Inherited Members
81@dataclass 82class Q7MapListEntry(RoborockBase): 83 """Single map list entry returned by `service.get_map_list`.""" 84 85 id: int | None = None 86 cur: bool | None = None
Single map list entry returned by service.get_map_list.
Inherited Members
89@dataclass 90class Q7MapList(RoborockBase): 91 """Map list response returned by `service.get_map_list`.""" 92 93 map_list: list[Q7MapListEntry] = field(default_factory=list) 94 95 @property 96 def current_map_id(self) -> int | None: 97 """Current map id, preferring the entry marked current.""" 98 if not self.map_list: 99 return None 100 101 ordered = sorted(self.map_list, key=lambda entry: entry.cur or False, reverse=True) 102 first = next(iter(ordered), None) 103 if first is None or not isinstance(first.id, int): 104 return None 105 return first.id
Map list response returned by service.get_map_list.
95 @property 96 def current_map_id(self) -> int | None: 97 """Current map id, preferring the entry marked current.""" 98 if not self.map_list: 99 return None 100 101 ordered = sorted(self.map_list, key=lambda entry: entry.cur or False, reverse=True) 102 first = next(iter(ordered), None) 103 if first is None or not isinstance(first.id, int): 104 return None 105 return first.id
Current map id, preferring the entry marked current.
Inherited Members
108@dataclass 109class B01Props(RoborockBase): 110 """ 111 Represents the complete properties and status for a Roborock B01 model. 112 This dataclass is generated based on the device's status JSON object. 113 """ 114 115 status: WorkStatusMapping | None = None 116 fault: B01Fault | None = None 117 wind: SCWindMapping | None = None 118 water: WaterLevelMapping | None = None 119 mode: CleanTypeMapping | None = None 120 quantity: int | None = None # The Q7 L5 reports its battery level as 'quantity' 121 alarm: int | None = None 122 volume: int | None = None 123 hypa: int | None = None 124 main_brush: int | None = None 125 side_brush: int | None = None 126 mop_life: int | None = None 127 main_sensor: int | None = None 128 net_status: NetStatus | None = None 129 repeat_state: CleanRepeatMapping | None = None 130 tank_state: int | None = None 131 sweep_type: int | None = None 132 clean_path_preference: CleanPathPreferenceMapping | None = None 133 cloth_state: int | None = None 134 time_zone: int | None = None 135 time_zone_info: str | None = None 136 language: int | None = None 137 cleaning_time: int | None = None 138 real_clean_time: int | None = None 139 cleaning_area: int | None = None 140 custom_type: int | None = None 141 sound: int | None = None 142 work_mode: WorkModeMapping | None = None 143 station_act: StationStateMapping | None = None 144 charge_state: int | None = None 145 current_map_id: int | None = None 146 map_num: int | None = None 147 dust_action: DustCollectionStateMapping | None = None # Read-only; prop.set is rejected with code 1 on the Q7 M5+. 148 quiet_is_open: int | None = None 149 quiet_begin_time: int | None = None 150 quiet_end_time: int | None = None 151 clean_finish: int | None = None 152 voice_type: int | None = None 153 voice_type_version: int | None = None 154 order_total: OrderTotal | None = None 155 build_map: int | None = None 156 privacy: Privacy | None = None 157 dust_auto_state: int | None = None 158 dust_frequency: int | None = None 159 child_lock: int | None = None 160 multi_floor: int | None = None 161 map_save: int | None = None 162 light_mode: int | None = None 163 green_laser: int | None = None 164 dust_bag_used: int | None = None 165 order_save_mode: int | None = None 166 manufacturer: str | None = None 167 back_to_wash: int | None = None 168 charge_station_type: int | None = None 169 pv_cut_charge: int | None = None 170 pv_charging: PvCharging | None = None 171 serial_number: str | None = None 172 recommend: Recommend | None = None 173 add_sweep_status: int | None = None 174 175 @property 176 def battery(self) -> int | None: 177 """ 178 Returns device battery level as a percentage. 179 """ 180 return self.quantity 181 182 @property 183 def main_brush_time_left(self) -> int | None: 184 """ 185 Returns estimated remaining life of the main brush in minutes. 186 Total life is 300 hours (18000 minutes). 187 """ 188 if self.main_brush is None: 189 return None 190 return max(0, 18000 - self.main_brush) 191 192 @property 193 def side_brush_time_left(self) -> int | None: 194 """ 195 Returns estimated remaining life of the side brush in minutes. 196 Total life is 200 hours (12000 minutes). 197 """ 198 if self.side_brush is None: 199 return None 200 return max(0, 12000 - self.side_brush) 201 202 @property 203 def filter_time_left(self) -> int | None: 204 """ 205 Returns estimated remaining life of the filter (hypa) in minutes. 206 Total life is 150 hours (9000 minutes). 207 """ 208 if self.hypa is None: 209 return None 210 return max(0, 9000 - self.hypa) 211 212 @property 213 def mop_life_time_left(self) -> int | None: 214 """ 215 Returns estimated remaining life of the mop in minutes. 216 Total life is 180 hours (10800 minutes). 217 """ 218 if self.mop_life is None: 219 return None 220 return max(0, 10800 - self.mop_life) 221 222 @property 223 def sensor_dirty_time_left(self) -> int | None: 224 """ 225 Returns estimated time until sensors need cleaning in minutes. 226 Maintenance interval is typically 30 hours (1800 minutes). 227 """ 228 if self.main_sensor is None: 229 return None 230 return max(0, 1800 - self.main_sensor) 231 232 @property 233 def status_name(self) -> str | None: 234 """Returns the name of the current status.""" 235 return self.status.value if self.status is not None else None 236 237 @property 238 def fault_name(self) -> str | None: 239 """Returns the name of the current fault.""" 240 return self.fault.value if self.fault is not None else None 241 242 @property 243 def wind_name(self) -> str | None: 244 """Returns the name of the current fan speed (wind).""" 245 return self.wind.value if self.wind is not None else None 246 247 @property 248 def work_mode_name(self) -> str | None: 249 """Returns the name of the current work mode.""" 250 return self.work_mode.value if self.work_mode is not None else None 251 252 @property 253 def repeat_state_name(self) -> str | None: 254 """Returns the name of the current repeat state.""" 255 return self.repeat_state.value if self.repeat_state is not None else None 256 257 @property 258 def clean_path_preference_name(self) -> str | None: 259 """Returns the name of the current clean path preference.""" 260 return self.clean_path_preference.value if self.clean_path_preference is not None else None
Represents the complete properties and status for a Roborock B01 model. This dataclass is generated based on the device's status JSON object.
175 @property 176 def battery(self) -> int | None: 177 """ 178 Returns device battery level as a percentage. 179 """ 180 return self.quantity
Returns device battery level as a percentage.
182 @property 183 def main_brush_time_left(self) -> int | None: 184 """ 185 Returns estimated remaining life of the main brush in minutes. 186 Total life is 300 hours (18000 minutes). 187 """ 188 if self.main_brush is None: 189 return None 190 return max(0, 18000 - self.main_brush)
Returns estimated remaining life of the main brush in minutes. Total life is 300 hours (18000 minutes).
192 @property 193 def side_brush_time_left(self) -> int | None: 194 """ 195 Returns estimated remaining life of the side brush in minutes. 196 Total life is 200 hours (12000 minutes). 197 """ 198 if self.side_brush is None: 199 return None 200 return max(0, 12000 - self.side_brush)
Returns estimated remaining life of the side brush in minutes. Total life is 200 hours (12000 minutes).
202 @property 203 def filter_time_left(self) -> int | None: 204 """ 205 Returns estimated remaining life of the filter (hypa) in minutes. 206 Total life is 150 hours (9000 minutes). 207 """ 208 if self.hypa is None: 209 return None 210 return max(0, 9000 - self.hypa)
Returns estimated remaining life of the filter (hypa) in minutes. Total life is 150 hours (9000 minutes).
212 @property 213 def mop_life_time_left(self) -> int | None: 214 """ 215 Returns estimated remaining life of the mop in minutes. 216 Total life is 180 hours (10800 minutes). 217 """ 218 if self.mop_life is None: 219 return None 220 return max(0, 10800 - self.mop_life)
Returns estimated remaining life of the mop in minutes. Total life is 180 hours (10800 minutes).
222 @property 223 def sensor_dirty_time_left(self) -> int | None: 224 """ 225 Returns estimated time until sensors need cleaning in minutes. 226 Maintenance interval is typically 30 hours (1800 minutes). 227 """ 228 if self.main_sensor is None: 229 return None 230 return max(0, 1800 - self.main_sensor)
Returns estimated time until sensors need cleaning in minutes. Maintenance interval is typically 30 hours (1800 minutes).
232 @property 233 def status_name(self) -> str | None: 234 """Returns the name of the current status.""" 235 return self.status.value if self.status is not None else None
Returns the name of the current status.
237 @property 238 def fault_name(self) -> str | None: 239 """Returns the name of the current fault.""" 240 return self.fault.value if self.fault is not None else None
Returns the name of the current fault.
242 @property 243 def wind_name(self) -> str | None: 244 """Returns the name of the current fan speed (wind).""" 245 return self.wind.value if self.wind is not None else None
Returns the name of the current fan speed (wind).
247 @property 248 def work_mode_name(self) -> str | None: 249 """Returns the name of the current work mode.""" 250 return self.work_mode.value if self.work_mode is not None else None
Returns the name of the current work mode.
252 @property 253 def repeat_state_name(self) -> str | None: 254 """Returns the name of the current repeat state.""" 255 return self.repeat_state.value if self.repeat_state is not None else None
Returns the name of the current repeat state.
257 @property 258 def clean_path_preference_name(self) -> str | None: 259 """Returns the name of the current clean path preference.""" 260 return self.clean_path_preference.value if self.clean_path_preference is not None else None
Returns the name of the current clean path preference.
Inherited Members
263@dataclass 264class CleanRecordDetail(RoborockBase): 265 """Represents a single clean record detail (from `record_list[].detail`).""" 266 267 record_start_time: int | None = None 268 method: int | None = None 269 record_use_time: int | None = None 270 clean_count: int | None = None 271 # This is seemingly returned in meters (non-squared) 272 record_clean_area: int | None = None 273 record_clean_mode: int | None = None 274 record_clean_way: int | None = None 275 record_task_status: int | None = None 276 record_faultcode: int | None = None 277 record_dust_num: int | None = None 278 clean_current_map: int | None = None 279 record_map_url: str | None = None 280 281 @property 282 def start_datetime(self) -> datetime.datetime | None: 283 """Convert the start datetime into a datetime object.""" 284 if self.record_start_time is not None: 285 return datetime.datetime.fromtimestamp(self.record_start_time).astimezone(datetime.UTC) 286 return None 287 288 @property 289 def square_meters_area_cleaned(self) -> float | None: 290 """Returns the area cleaned in square meters.""" 291 if self.record_clean_area is not None: 292 return self.record_clean_area / 100 293 return None
Represents a single clean record detail (from record_list[].detail).
281 @property 282 def start_datetime(self) -> datetime.datetime | None: 283 """Convert the start datetime into a datetime object.""" 284 if self.record_start_time is not None: 285 return datetime.datetime.fromtimestamp(self.record_start_time).astimezone(datetime.UTC) 286 return None
Convert the start datetime into a datetime object.
288 @property 289 def square_meters_area_cleaned(self) -> float | None: 290 """Returns the area cleaned in square meters.""" 291 if self.record_clean_area is not None: 292 return self.record_clean_area / 100 293 return None
Returns the area cleaned in square meters.
Inherited Members
296@dataclass 297class CleanRecordListItem(RoborockBase): 298 """Represents an entry in the clean record list returned by `service.get_record_list`.""" 299 300 url: str | None = None 301 detail: str | None = None 302 303 @cached_property 304 def detail_parsed(self) -> CleanRecordDetail | None: 305 """Parse and return the detail as a CleanRecordDetail object.""" 306 if self.detail is None: 307 return None 308 try: 309 parsed = json.loads(self.detail) 310 except json.JSONDecodeError as ex: 311 raise RoborockException(f"Invalid B01 record detail JSON: {self.detail!r}") from ex 312 return CleanRecordDetail.from_dict(parsed)
Represents an entry in the clean record list returned by service.get_record_list.
303 @cached_property 304 def detail_parsed(self) -> CleanRecordDetail | None: 305 """Parse and return the detail as a CleanRecordDetail object.""" 306 if self.detail is None: 307 return None 308 try: 309 parsed = json.loads(self.detail) 310 except json.JSONDecodeError as ex: 311 raise RoborockException(f"Invalid B01 record detail JSON: {self.detail!r}") from ex 312 return CleanRecordDetail.from_dict(parsed)
Parse and return the detail as a CleanRecordDetail object.
Inherited Members
315@dataclass 316class CleanRecordList(RoborockBase): 317 """Represents the clean record list response from `service.get_record_list`.""" 318 319 total_area: int | None = None 320 total_time: int | None = None # stored in seconds 321 total_count: int | None = None 322 record_list: list[CleanRecordListItem] = field(default_factory=list) 323 324 @property 325 def square_meters_area_cleaned(self) -> float | None: 326 """Returns the area cleaned in square meters.""" 327 if self.total_area is not None: 328 return self.total_area / 100 329 return None
Represents the clean record list response from service.get_record_list.
324 @property 325 def square_meters_area_cleaned(self) -> float | None: 326 """Returns the area cleaned in square meters.""" 327 if self.total_area is not None: 328 return self.total_area / 100 329 return None
Returns the area cleaned in square meters.
Inherited Members
332@dataclass 333class CleanRecordSummary(RoborockBase): 334 """Represents clean record totals for B01/Q7 devices.""" 335 336 total_time: int | None = None 337 total_area: int | None = None 338 total_count: int | None = None 339 last_record_detail: CleanRecordDetail | None = None
Represents clean record totals for B01/Q7 devices.