11"""
22Class Camera Shared.
33Keep the data between the modules.
4- Version: v0.1.10
4+ Version: v0.1.12
55"""
66
77import asyncio
@@ -54,129 +54,112 @@ class CameraShared:
5454 """
5555
5656 def __init__ (self , file_name ):
57- self .camera_mode : str = CameraModes .MAP_VIEW # Camera mode
58- self .frame_number : int = 0 # camera Frame number
59- self .destinations : list = [] # MQTT rand destinations
60- self .rand256_active_zone : list = [] # Active zone for rand256
61- self .rand256_zone_coordinates : list = [] # Active zone coordinates for rand256
62- self .is_rand : bool = False # MQTT rand data
63- self ._new_mqtt_message = False # New MQTT message
64- # Initialize last_image with default gray image (250x150 minimum)
65- self .last_image = Image .new (
66- "RGBA" , (250 , 150 ), (128 , 128 , 128 , 255 )
67- ) # Gray default image
68- self .new_image : PilPNG | None = None # New image received
69- self .binary_image : bytes | None = None # Current image in binary format
70- self .image_last_updated : float = 0.0 # Last image update time
71- self .image_format = "image/pil" # Image format
72- self .image_size = None # Image size
73- self .robot_size = None # Robot size
74- self .image_auto_zoom : bool = False # Auto zoom image
75- self .image_zoom_lock_ratio : bool = True # Zoom lock ratio
76- self .image_ref_height : int = 0 # Image reference height
77- self .image_ref_width : int = 0 # Image reference width
78- self .image_aspect_ratio : str = "None" # Change Image aspect ratio
79- self .image_grab = True # Grab image from MQTT
80- self .image_rotate : int = 0 # Rotate image
81- self .drawing_limit : float = 0.0 # Drawing CPU limit
82- self .current_room = None # Current room of rhe vacuum
83- self .user_colors = Colors # User base colors
84- self .rooms_colors = Colors # Rooms colors
85- self .vacuum_battery = 0 # Vacuum battery state
86- self .vacuum_connection = False # Vacuum connection state
87- self .vacuum_state = None # Vacuum state
88- self .charger_position = None # Vacuum Charger position
89- self .show_vacuum_state = None # Show vacuum state on the map
57+ self .camera_mode : str = CameraModes .MAP_VIEW
58+ self .frame_number : int = 0
59+ self .destinations : list = []
60+ self .rand256_active_zone : list = []
61+ self .rand256_zone_coordinates : list = []
62+ self .is_rand : bool = False
63+ self ._new_mqtt_message = False
64+ self .last_image = Image .new ("RGBA" , (250 , 150 ), (128 , 128 , 128 , 255 ))
65+ self .new_image : PilPNG | None = None
66+ self .binary_image : bytes | None = None
67+ self .image_last_updated : float = 0.0
68+ self .image_format = "image/pil"
69+ self .image_size = None
70+ self .robot_size = None
71+ self .image_auto_zoom : bool = False
72+ self .image_zoom_lock_ratio : bool = True
73+ self .image_ref_height : int = 0
74+ self .image_ref_width : int = 0
75+ self .image_aspect_ratio : str = "None"
76+ self .image_grab = True
77+ self .image_rotate : int = 0
78+ self .drawing_limit : float = 0.0
79+ self .current_room = None
80+ self .user_colors = Colors
81+ self .rooms_colors = Colors
82+ self .vacuum_battery = 0
83+ self .vacuum_connection = False
84+ self .vacuum_state = None
85+ self .charger_position = None
86+ self .show_vacuum_state = None
9087 self .vacuum_status_font : str = (
91- "custom_components/mqtt_vacuum_camera/utils/fonts/FiraSans.ttf" # Font
88+ "custom_components/mqtt_vacuum_camera/utils/fonts/FiraSans.ttf"
9289 )
93- self .vacuum_status_size : int = 50 # Vacuum status size
94- self .vacuum_status_position : bool = True # Vacuum status text image top
95- self .snapshot_take = False # Take snapshot
96- self .vacuum_error = None # Vacuum error
97- self .vacuum_api = None # Vacuum API
98- self .vacuum_ips = None # Vacuum IPs
99- self .vac_json_id = None # Vacuum json id
100- self .margins = "100" # Image margins
101- self .obstacles_data = None # Obstacles data
102- self .obstacles_pos = None # Obstacles position
103- self .offset_top = 0 # Image offset top
104- self .offset_down = 0 # Image offset down
105- self .offset_left = 0 # Image offset left
106- self .offset_right = 0 # Image offset right
107- self .export_svg = False # Export SVG
108- self .svg_path = None # SVG Export path
109- self .enable_snapshots = False # Enable snapshots
110- self .file_name = file_name # vacuum friendly name as File name
111- self .attr_calibration_points = None # Calibration points of the image
112- self .map_rooms = None # Rooms data from the vacuum
113- self .map_pred_zones = None # Predefined zones data
114- self .map_pred_points = None # Predefined points data
115- self .map_new_path = None # New path data
116- self .map_old_path = None # Old path data
117- self .user_language = None # User language
90+ self .vacuum_status_size : int = 50
91+ self .vacuum_status_position : bool = True
92+ self .snapshot_take = False
93+ self .vacuum_error = None
94+ self .vacuum_api = None
95+ self .vacuum_ips = None
96+ self .vac_json_id = None
97+ self .margins = "100"
98+ self .obstacles_data = None
99+ self .obstacles_pos = None
100+ self .offset_top = 0
101+ self .offset_down = 0
102+ self .offset_left = 0
103+ self .offset_right = 0
104+ self .export_svg = False
105+ self .svg_path = None
106+ self .enable_snapshots = False
107+ self .file_name = file_name
108+ self .attr_calibration_points = None
109+ self .map_rooms = None
110+ self .map_pred_zones = None
111+ self .map_pred_points = None
112+ self .map_new_path = None
113+ self .map_old_path = None
114+ self .user_language = None
118115 self .trim_crop_data = None
119- self .trims = TrimsData .from_dict (DEFAULT_VALUES ["trims_data" ]) # Trims data
116+ self .trims = TrimsData .from_dict (DEFAULT_VALUES ["trims_data" ])
120117 self .skip_room_ids : List [str ] = []
121- self .device_info = None # Store the device_info
118+ self .device_info = None
122119
123120 def vacuum_bat_charged (self ) -> bool :
124121 """Check if the vacuum is charging."""
125122 return (self .vacuum_state == "docked" ) and (int (self .vacuum_battery ) < 100 )
126123
127124 @staticmethod
128125 def _compose_obstacle_links (vacuum_host_ip : str , obstacles : list ) -> list | None :
129- """
130- Compose JSON with obstacle details including the image link.
131- """
126+ """Compose JSON with obstacle details including the image link."""
132127 obstacle_links = []
133128 if not obstacles or not vacuum_host_ip :
134129 return None
135130
136131 for obstacle in obstacles :
137- # Extract obstacle details
138132 label = obstacle .get ("label" , "" )
139133 points = obstacle .get ("points" , {})
140134 image_id = obstacle .get ("id" , "None" )
141135
142136 if label and points and image_id and vacuum_host_ip :
143- # Append formatted obstacle data
144137 if image_id != "None" :
145- # Compose the link
146138 image_link = (
147139 f"http://{ vacuum_host_ip } "
148140 f"/api/v2/robot/capabilities/ObstacleImagesCapability/img/{ image_id } "
149141 )
150142 obstacle_links .append (
151- {
152- "point" : points ,
153- "label" : label ,
154- "link" : image_link ,
155- }
143+ {"point" : points , "label" : label , "link" : image_link }
156144 )
157145 else :
158- obstacle_links .append (
159- {
160- "point" : points ,
161- "label" : label ,
162- }
163- )
146+ obstacle_links .append ({"point" : points , "label" : label })
164147 return obstacle_links
165148
166149 def update_user_colors (self , user_colors ):
167- """Update the user colors. """
150+ """Update user colors palette """
168151 self .user_colors = user_colors
169152
170153 def get_user_colors (self ):
171- """Get the user colors. """
154+ """Return user colors"""
172155 return self .user_colors
173156
174157 def update_rooms_colors (self , user_colors ):
175158 """Update the rooms colors."""
176159 self .rooms_colors = user_colors
177160
178161 def get_rooms_colors (self ):
179- """Get the rooms colors. """
162+ """Return rooms colors"""
180163 return self .rooms_colors
181164
182165 def reset_trims (self ) -> dict :
@@ -185,7 +168,7 @@ def reset_trims(self) -> dict:
185168 return self .trims
186169
187170 async def batch_update (self , ** kwargs ):
188- """Batch update multiple attributes. """
171+ """Update the data of Shared in Batch """
189172 for key , value in kwargs .items ():
190173 setattr (self , key , value )
191174
@@ -210,24 +193,32 @@ def generate_attributes(self) -> dict:
210193 )
211194 attrs [ATTR_OBSTACLES ] = self .obstacles_data
212195
213- if self .enable_snapshots :
214- attrs [ATTR_SNAPSHOT ] = self .snapshot_take
215- else :
216- attrs [ATTR_SNAPSHOT ] = False
196+ attrs [ATTR_SNAPSHOT ] = self .snapshot_take if self .enable_snapshots else False
217197
218- # Add dynamic shared attributes if they are available
219198 shared_attrs = {
220199 ATTR_ROOMS : self .map_rooms ,
221200 ATTR_ZONES : self .map_pred_zones ,
222201 ATTR_POINTS : self .map_pred_points ,
223202 }
224-
225203 for key , value in shared_attrs .items ():
226204 if value is not None :
227205 attrs [key ] = value
228206
229207 return attrs
230208
209+ def to_dict (self ) -> dict :
210+ """Return a dictionary with image and attributes data."""
211+ return {
212+ "image" : {
213+ "binary" : self .binary_image ,
214+ "pil_image_size" : self .new_image .size ,
215+ "size" : self .new_image .size if self .new_image else None ,
216+ "format" : self .image_format ,
217+ "updated" : self .image_last_updated ,
218+ },
219+ "attributes" : self .generate_attributes (),
220+ }
221+
231222
232223class CameraSharedManager :
233224 """Camera Shared Manager class."""
0 commit comments