@@ -107,22 +107,32 @@ def _decamelize(s: str):
107107 return re .sub ("([A-Z]+)" , "_\\ 1" , s ).lower ()
108108
109109
110- def _attr_repr (obj : Any , attrs : list [str ]) -> str :
111- """Return a string representation of the object including specified attributes."""
110+ def _attr_repr (obj : Any ) -> str :
111+ """Return a string representation of the object including specified attributes.
112+
113+ This reproduces the default repr behavior of dataclasses, but also includes
114+ properties. This must be called by the child class's __repr__ method since
115+ the parent RoborockBase class does not know about the child class's attributes.
116+ """
112117 # Reproduce default repr behavior
113- items = (f"{ k } ={ v !r} " for k , v in obj .__dict__ .items () if not k .startswith ("_" ))
114- default_repr = "{}({})" .format (type (obj ).__name__ , ", " .join (items ))
115- # Append additional attributes
116- parts = [default_repr [:- 1 ]]
117- for attr in attrs :
118- value = getattr (obj , attr , None )
119- parts .append (f", { attr } ={ repr (value )} " )
120- parts .append (")" )
121- return "" .join (parts )
122-
123-
124- @dataclass
118+ parts = []
119+ for k in dir (obj ):
120+ if k .startswith ("_" ):
121+ continue
122+ try :
123+ v = getattr (obj , k )
124+ except (RuntimeError , Exception ):
125+ continue
126+ if callable (v ):
127+ continue
128+ parts .append (f"{ k } ={ v !r} " )
129+ return f"{ type (obj ).__name__ } ({ ', ' .join (parts )} )"
130+
131+
132+ @dataclass (repr = False )
125133class RoborockBase :
134+ """Base class for all Roborock data classes."""
135+
126136 @staticmethod
127137 def _convert_to_class_obj (class_type : type , value ):
128138 if get_origin (class_type ) is list :
@@ -208,7 +218,7 @@ def end_time(self) -> datetime.time | None:
208218 )
209219
210220 def __repr__ (self ) -> str :
211- return _attr_repr (self , [ "start_time" , "end_time" ] )
221+ return _attr_repr (self )
212222
213223
214224@dataclass
@@ -462,18 +472,7 @@ def current_map(self) -> int | None:
462472 return None
463473
464474 def __repr__ (self ) -> str :
465- return _attr_repr (
466- self ,
467- [
468- "square_meter_clean_area" ,
469- "error_code_name" ,
470- "state_name" ,
471- "water_box_mode_name" ,
472- "fan_power_name" ,
473- "mop_mode_name" ,
474- "current_map" ,
475- ],
476- )
475+ return _attr_repr (self )
477476
478477
479478@dataclass
@@ -638,8 +637,9 @@ def square_meter_clean_area(self) -> float | None:
638637 return None
639638 return round (self .clean_area / 1000000 , 1 ) if self .clean_area is not None else None
640639
641- def __repr__ (self ):
642- return _attr_repr (self , ["square_meter_clean_area" ])
640+ def __repr__ (self ) -> str :
641+ """Return a string representation of the object including all attributes."""
642+ return _attr_repr (self )
643643
644644
645645@dataclass
@@ -671,7 +671,7 @@ def end_datetime(self) -> datetime.datetime | None:
671671 return datetime .datetime .fromtimestamp (self .end ).astimezone (timezone .utc ) if self .end else None
672672
673673 def __repr__ (self ) -> str :
674- return _attr_repr (self , [ "square_meter_area" , "begin_datetime" , "end_datetime" ] )
674+ return _attr_repr (self )
675675
676676
677677@dataclass
@@ -727,20 +727,7 @@ def mop_roller_time_left(self) -> int | None:
727727 return MOP_ROLLER_REPLACE_TIME - self .moproller_work_time if self .moproller_work_time is not None else None
728728
729729 def __repr__ (self ) -> str :
730- return _attr_repr (
731- self ,
732- [
733- "main_brush_time_left" ,
734- "side_brush_time_left" ,
735- "filter_time_left" ,
736- "sensor_time_left" ,
737- "strainer_time_left" ,
738- "dust_collection_time_left" ,
739- "cleaning_brush_time_left" ,
740- "mop_roller_time_left" ,
741- ],
742- )
743-
730+ return _attr_repr (self )
744731
745732@dataclass
746733class MultiMapsListMapInfoBakMaps (RoborockBase ):
@@ -830,7 +817,7 @@ def product_nickname(self) -> RoborockProductNickname:
830817 return SHORT_MODEL_TO_ENUM .get (self .model .split ("." )[- 1 ], RoborockProductNickname .PEARLPLUS )
831818
832819 def __repr__ (self ) -> str :
833- return _attr_repr (self , [ "product_nickname" ] )
820+ return _attr_repr (self )
834821
835822
836823@dataclass
@@ -923,7 +910,7 @@ def product_nickname(self) -> RoborockProductNickname | None:
923910 return None
924911
925912 def __repr__ (self ) -> str :
926- return _attr_repr (self , [ "product_nickname" ] )
913+ return _attr_repr (self )
927914
928915
929916@dataclass
0 commit comments