valetudo-map-parser 0.1.10rc6__py3-none-any.whl → 0.1.11b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -269,8 +269,6 @@ class ImageDraw:
269
269
  zone_clean = self.img_h.data.find_zone_entities(m_json)
270
270
  except (ValueError, KeyError):
271
271
  zone_clean = None
272
- else:
273
- _LOGGER.info("%s: Got zones.", self.file_name)
274
272
 
275
273
  if zone_clean:
276
274
  # Process zones sequentially to avoid memory-intensive array copies
@@ -8,25 +8,22 @@ Version: 0.1.10
8
8
  from __future__ import annotations
9
9
 
10
10
  import asyncio
11
- import numpy as np
12
11
 
12
+ import numpy as np
13
+ from mvcrender.autocrop import AutoCrop
13
14
  from PIL import Image
14
15
 
15
16
  from .config.async_utils import AsyncPIL
16
-
17
- # from .config.auto_crop import AutoCrop
18
- from mvcrender.autocrop import AutoCrop
19
17
  from .config.drawable_elements import DrawableElement
20
18
  from .config.shared import CameraShared
21
-
22
19
  from .config.types import (
23
20
  COLORS,
24
21
  LOGGER,
25
22
  CalibrationPoints,
26
23
  Colors,
24
+ JsonType,
27
25
  RoomsProperties,
28
26
  RoomStore,
29
- JsonType,
30
27
  )
31
28
  from .config.utils import (
32
29
  BaseHandler,
@@ -49,9 +46,7 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
49
46
  self.calibration_data = None # camera shared data.
50
47
  self.data = ImageData # imported Image Data Module.
51
48
  # Initialize drawing configuration using the shared utility function
52
- self.drawing_config, self.draw, self.enhanced_draw = initialize_drawing_config(
53
- self
54
- )
49
+ self.drawing_config, self.draw = initialize_drawing_config(self)
55
50
 
56
51
  self.go_to = None # vacuum go to data
57
52
  self.img_hash = None # hash of the image calculated to check differences.
@@ -60,7 +55,6 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
60
55
  None # persistent working buffer to avoid per-frame allocations
61
56
  )
62
57
  self.active_zones = [] # vacuum active zones.
63
- self.svg_wait = False # SVG image creation wait.
64
58
  self.imd = ImDraw(self) # Image Draw class.
65
59
  self.color_grey = (128, 128, 128, 255)
66
60
  self.file_name = self.shared.file_name # file name of the vacuum.
@@ -79,7 +73,7 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
79
73
  json_data
80
74
  )
81
75
  if room_properties:
82
- rooms = RoomStore(self.file_name, room_properties)
76
+ _ = RoomStore(self.file_name, room_properties)
83
77
  # Convert room_properties to the format expected by async_get_robot_in_room
84
78
  self.rooms_pos = []
85
79
  for room_id, room_data in room_properties.items():
@@ -260,7 +254,12 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
260
254
  )
261
255
  LOGGER.info("%s: Completed base Layers", self.file_name)
262
256
  # Copy the new array in base layer.
257
+ # Delete old base layer before creating new one to free memory
258
+ if self.img_base_layer is not None:
259
+ del self.img_base_layer
263
260
  self.img_base_layer = await self.async_copy_array(img_np_array)
261
+ # Delete source array after copying to free memory
262
+ del img_np_array
264
263
 
265
264
  self.shared.frame_number = self.frame_number
266
265
  self.frame_number += 1
@@ -274,6 +273,9 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
274
273
  or self.img_work_layer.shape != self.img_base_layer.shape
275
274
  or self.img_work_layer.dtype != self.img_base_layer.dtype
276
275
  ):
276
+ # Delete old buffer before creating new one to free memory
277
+ if self.img_work_layer is not None:
278
+ del self.img_work_layer
277
279
  self.img_work_layer = np.empty_like(self.img_base_layer)
278
280
 
279
281
  # Copy the base layer into the persistent working buffer (no new allocation per frame)
@@ -348,21 +350,11 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
348
350
  robot_state=self.shared.vacuum_state,
349
351
  )
350
352
 
351
- # Update element map for robot position
352
- if (
353
- hasattr(self.shared, "element_map")
354
- and self.shared.element_map is not None
355
- ):
356
- update_element_map_with_robot(
357
- self.shared.element_map,
358
- robot_position,
359
- DrawableElement.ROBOT,
360
- )
361
353
  # Synchronize zooming state from ImageDraw to handler before auto-crop
362
354
  self.zooming = self.imd.img_h.zooming
363
355
 
364
356
  # Resize the image
365
- img_np_array = self.async_auto_trim_and_zoom_image(
357
+ img_np_array = self.auto_trim_and_zoom_image(
366
358
  img_np_array,
367
359
  colors["background"],
368
360
  int(self.shared.margins),
@@ -8,22 +8,22 @@ Version: v0.1.10
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
- import numpy as np
11
+ from dataclasses import asdict, dataclass, field
12
12
  from typing import (
13
- List,
14
- Sequence,
15
- TypeVar,
16
13
  Any,
17
- TypedDict,
18
- NotRequired,
19
14
  Literal,
15
+ NotRequired,
20
16
  Optional,
17
+ Sequence,
18
+ TypedDict,
19
+ TypeVar,
21
20
  )
22
21
 
23
- from dataclasses import dataclass, field, asdict
22
+ import numpy as np
24
23
 
25
24
  from .config.types import ImageSize, JsonType
26
25
 
26
+
27
27
  T = TypeVar("T")
28
28
 
29
29
  # --- Common Nested Structures ---
@@ -373,6 +373,11 @@ class ImageData:
373
373
  Else:
374
374
  (min_x_mm, min_y_mm, max_x_mm, max_y_mm)
375
375
  """
376
+
377
+ def to_mm(coord):
378
+ """Convert pixel coordinates to millimeters."""
379
+ return round(coord * pixel_size * 10)
380
+
376
381
  if not pixels:
377
382
  raise ValueError("Pixels list cannot be empty.")
378
383
 
@@ -393,7 +398,6 @@ class ImageData:
393
398
  min_y = min(min_y, y)
394
399
 
395
400
  if rand:
396
- to_mm = lambda v: v * pixel_size * 10
397
401
  return (to_mm(max_x), to_mm(max_y)), (to_mm(min_x), to_mm(min_y))
398
402
 
399
403
  return (
@@ -539,16 +543,18 @@ class RandImageData:
539
543
  return None
540
544
 
541
545
  @staticmethod
542
- def get_rrm_currently_cleaned_zones(json_data: JsonType) -> dict:
546
+ def get_rrm_currently_cleaned_zones(json_data: JsonType) -> list[dict[str, Any]]:
543
547
  """Get the currently cleaned zones from the json."""
544
548
  re_zones = json_data.get("currently_cleaned_zones", [])
545
549
  formatted_zones = RandImageData._rrm_valetudo_format_zone(re_zones)
546
550
  return formatted_zones
547
551
 
548
552
  @staticmethod
549
- def get_rrm_forbidden_zones(json_data: JsonType) -> dict:
553
+ def get_rrm_forbidden_zones(json_data: JsonType) -> list[dict[str, Any]]:
550
554
  """Get the forbidden zones from the json."""
551
- re_zones = json_data.get("forbidden_zones", [])
555
+ re_zones = json_data.get("forbidden_zones", []) + json_data.get(
556
+ "forbidden_mop_zones", []
557
+ )
552
558
  formatted_zones = RandImageData._rrm_valetudo_format_zone(re_zones)
553
559
  return formatted_zones
554
560
 
@@ -2,27 +2,26 @@
2
2
  Image Handler Module for Valetudo Re Vacuums.
3
3
  It returns the PIL PNG image frame relative to the Map Data extrapolated from the vacuum json.
4
4
  It also returns calibration, rooms data to the card and other images information to the camera.
5
- Version: 0.1.9.a6
5
+ Version: 0.1.10
6
6
  """
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
- import logging
11
10
  import uuid
12
11
  from typing import Any
13
12
 
14
13
  import numpy as np
14
+ from mvcrender.autocrop import AutoCrop
15
15
 
16
16
  from .config.async_utils import AsyncPIL
17
-
18
- # from .config.auto_crop import AutoCrop
19
- from mvcrender.autocrop import AutoCrop
20
17
  from .config.drawable_elements import DrawableElement
21
18
  from .config.types import (
22
19
  COLORS,
23
20
  DEFAULT_IMAGE_SIZE,
24
21
  DEFAULT_PIXEL_SIZE,
22
+ LOGGER,
25
23
  Colors,
24
+ Destinations,
26
25
  JsonType,
27
26
  PilPNG,
28
27
  RobotPosition,
@@ -39,9 +38,6 @@ from .reimg_draw import ImageDraw
39
38
  from .rooms_handler import RandRoomsHandler
40
39
 
41
40
 
42
- _LOGGER = logging.getLogger(__name__)
43
-
44
-
45
41
  # noinspection PyTypeChecker
46
42
  class ReImageHandler(BaseHandler, AutoCrop):
47
43
  """
@@ -59,11 +55,10 @@ class ReImageHandler(BaseHandler, AutoCrop):
59
55
  self.data = RandImageData # Image Data
60
56
 
61
57
  # Initialize drawing configuration using the shared utility function
62
- self.drawing_config, self.draw, self.enhanced_draw = initialize_drawing_config(
63
- self
64
- )
58
+ self.drawing_config, self.draw = initialize_drawing_config(self)
65
59
  self.go_to = None # Go to position data
66
60
  self.img_base_layer = None # Base image layer
61
+ self.img_work_layer = None # Persistent working buffer (reused across frames)
67
62
  self.img_rotate = shared_data.image_rotate # Image rotation
68
63
  self.room_propriety = None # Room propriety data
69
64
  self.active_zones = None # Active zones
@@ -74,7 +69,9 @@ class ReImageHandler(BaseHandler, AutoCrop):
74
69
  ) # Room data handler
75
70
 
76
71
  async def extract_room_properties(
77
- self, json_data: JsonType, destinations: JsonType
72
+ self,
73
+ json_data: JsonType,
74
+ destinations: Destinations | None = None,
78
75
  ) -> RoomsProperties:
79
76
  """Extract the room properties."""
80
77
  # unsorted_id = RandImageData.get_rrm_segments_ids(json_data)
@@ -89,9 +86,10 @@ class ReImageHandler(BaseHandler, AutoCrop):
89
86
  json_data, size_x, size_y, top, left, True
90
87
  )
91
88
 
92
- dest_json = destinations
93
- zones_data = dict(dest_json).get("zones", [])
94
- points_data = dict(dest_json).get("spots", [])
89
+
90
+ dest_json = destinations if destinations else {}
91
+ zones_data = dest_json.get("zones", [])
92
+ points_data = dest_json.get("spots", [])
95
93
 
96
94
  # Use the RandRoomsHandler to extract room properties
97
95
  room_properties = await self.rooms_handler.async_extract_room_properties(
@@ -100,39 +98,35 @@ class ReImageHandler(BaseHandler, AutoCrop):
100
98
 
101
99
  # Update self.rooms_pos from room_properties for compatibility with other methods
102
100
  self.rooms_pos = []
103
- room_ids = [] # Collect room IDs for shared.map_rooms
104
101
  for room_id, room_data in room_properties.items():
105
102
  self.rooms_pos.append(
106
103
  {"name": room_data["name"], "outline": room_data["outline"]}
107
104
  )
108
- # Store the room number (segment ID) for MQTT active zone mapping
109
- room_ids.append(room_data["number"])
110
-
111
- # Update shared.map_rooms with the room IDs for MQTT active zone mapping
112
- self.shared.map_rooms = room_ids
113
105
 
106
+ # Update shared.map_rooms with the full room properties (consistent with Hypfer)
107
+ self.shared.map_rooms = room_properties
114
108
  # get the zones and points data
115
- zone_properties = await self.async_zone_propriety(zones_data)
109
+ self.shared.map_pred_zones = await self.async_zone_propriety(zones_data)
116
110
  # get the points data
117
- point_properties = await self.async_points_propriety(points_data)
111
+ self.shared.map_pred_points = await self.async_points_propriety(points_data)
118
112
 
119
- if not (room_properties or zone_properties):
113
+ if not (room_properties or self.shared.map_pred_zones):
120
114
  self.rooms_pos = None
121
115
 
122
- rooms = RoomStore(self.file_name, room_properties)
123
- return room_properties, zone_properties, point_properties
116
+ _ = RoomStore(self.file_name, room_properties)
117
+ return room_properties
124
118
  except (RuntimeError, ValueError) as e:
125
- _LOGGER.warning(
119
+ LOGGER.warning(
126
120
  "No rooms Data or Error in extract_room_properties: %s",
127
121
  e,
128
122
  exc_info=True,
129
123
  )
130
- return None, None, None
124
+ return None
131
125
 
132
126
  async def get_image_from_rrm(
133
127
  self,
134
128
  m_json: JsonType, # json data
135
- destinations: None = None, # MQTT destinations for labels
129
+ destinations: Destinations | None = None, # MQTT destinations for labels
136
130
  ) -> PilPNG | None:
137
131
  """Generate Images from the json data.
138
132
  @param m_json: The JSON data to use to draw the image.
@@ -146,12 +140,12 @@ class ReImageHandler(BaseHandler, AutoCrop):
146
140
 
147
141
  try:
148
142
  if (m_json is not None) and (not isinstance(m_json, tuple)):
149
- _LOGGER.info("%s: Composing the image for the camera.", self.file_name)
143
+ LOGGER.info("%s: Composing the image for the camera.", self.file_name)
150
144
  self.json_data = m_json
151
145
  size_x, size_y = self.data.get_rrm_image_size(m_json)
152
146
  self.img_size = DEFAULT_IMAGE_SIZE
153
147
  self.json_id = str(uuid.uuid4()) # image id
154
- _LOGGER.info("Vacuum Data ID: %s", self.json_id)
148
+ LOGGER.info("Vacuum Data ID: %s", self.json_id)
155
149
 
156
150
  (
157
151
  img_np_array,
@@ -163,10 +157,24 @@ class ReImageHandler(BaseHandler, AutoCrop):
163
157
 
164
158
  # Increment frame number
165
159
  self.frame_number += 1
166
- img_np_array = await self.async_copy_array(self.img_base_layer)
167
160
  if self.frame_number > 5:
168
161
  self.frame_number = 0
169
162
 
163
+ # Ensure persistent working buffer exists and matches base (allocate only when needed)
164
+ if (
165
+ self.img_work_layer is None
166
+ or self.img_work_layer.shape != self.img_base_layer.shape
167
+ or self.img_work_layer.dtype != self.img_base_layer.dtype
168
+ ):
169
+ # Delete old buffer before creating new one to free memory
170
+ if self.img_work_layer is not None:
171
+ del self.img_work_layer
172
+ self.img_work_layer = np.empty_like(self.img_base_layer)
173
+
174
+ # Copy the base layer into the persistent working buffer (no new allocation per frame)
175
+ np.copyto(self.img_work_layer, self.img_base_layer)
176
+ img_np_array = self.img_work_layer
177
+
170
178
  # Draw map elements
171
179
  img_np_array = await self._draw_map_elements(
172
180
  img_np_array, m_json, colors, robot_position, robot_position_angle
@@ -174,11 +182,11 @@ class ReImageHandler(BaseHandler, AutoCrop):
174
182
 
175
183
  # Return PIL Image using async utilities
176
184
  pil_img = await AsyncPIL.async_fromarray(img_np_array, mode="RGBA")
177
- del img_np_array # free memory
185
+ # Note: Don't delete img_np_array here as it's the persistent work buffer
178
186
  return await self._finalize_image(pil_img)
179
187
 
180
188
  except (RuntimeError, RuntimeWarning) as e:
181
- _LOGGER.warning(
189
+ LOGGER.warning(
182
190
  "%s: Runtime Error %s during image creation.",
183
191
  self.file_name,
184
192
  str(e),
@@ -192,6 +200,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
192
200
  async def _setup_robot_and_image(
193
201
  self, m_json, size_x, size_y, colors, destinations
194
202
  ):
203
+ """Set up the elements of the map and the image."""
195
204
  (
196
205
  _,
197
206
  robot_position,
@@ -214,13 +223,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
214
223
  colors["background"],
215
224
  DEFAULT_PIXEL_SIZE,
216
225
  )
217
- _LOGGER.info("%s: Completed base Layers", self.file_name)
218
-
219
- # Update element map for rooms
220
- if 0 < room_id <= 15:
221
- # This is a simplification - in a real implementation we would
222
- # need to identify the exact pixels that belong to each room
223
- pass
226
+ LOGGER.info("%s: Completed base Layers", self.file_name)
224
227
 
225
228
  if room_id > 0 and not self.room_propriety:
226
229
  self.room_propriety = await self.get_rooms_attributes(destinations)
@@ -229,14 +232,23 @@ class ReImageHandler(BaseHandler, AutoCrop):
229
232
  if not self.rooms_pos and not self.room_propriety:
230
233
  self.room_propriety = await self.get_rooms_attributes(destinations)
231
234
 
232
- # Always check robot position for zooming (fallback)
233
- if self.rooms_pos and robot_position and not hasattr(self, "robot_pos"):
235
+ # Always check robot position for zooming (update if room info is missing)
236
+ if (
237
+ self.rooms_pos
238
+ and robot_position
239
+ and (self.robot_pos is None or "in_room" not in self.robot_pos)
240
+ ):
234
241
  self.robot_pos = await self.async_get_robot_in_room(
235
242
  (robot_position[0] * 10),
236
243
  (robot_position[1] * 10),
237
244
  robot_position_angle,
238
245
  )
246
+ # Delete old base layer before creating new one to free memory
247
+ if self.img_base_layer is not None:
248
+ del self.img_base_layer
239
249
  self.img_base_layer = await self.async_copy_array(img_np_array)
250
+ # Delete source array after copying to free memory
251
+ del img_np_array
240
252
  else:
241
253
  # If floor is disabled, create an empty image
242
254
  background_color = self.drawing_config.get_property(
@@ -245,7 +257,12 @@ class ReImageHandler(BaseHandler, AutoCrop):
245
257
  img_np_array = await self.draw.create_empty_image(
246
258
  size_x, size_y, background_color
247
259
  )
260
+ # Delete old base layer before creating new one to free memory
261
+ if self.img_base_layer is not None:
262
+ del self.img_base_layer
248
263
  self.img_base_layer = await self.async_copy_array(img_np_array)
264
+ # Delete source array after copying to free memory
265
+ del img_np_array
249
266
 
250
267
  # Check active zones BEFORE auto-crop to enable proper zoom functionality
251
268
  # This needs to run on every frame, not just frame 0
@@ -277,7 +294,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
277
294
  # Restore original rooms_pos
278
295
  self.rooms_pos = original_rooms_pos
279
296
 
280
- except Exception as e:
297
+ except (ValueError, KeyError, TypeError):
281
298
  # Fallback to robot-position-based zoom if room extraction fails
282
299
  if (
283
300
  self.shared.image_auto_zoom
@@ -291,6 +308,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
291
308
  async def _draw_map_elements(
292
309
  self, img_np_array, m_json, colors, robot_position, robot_position_angle
293
310
  ):
311
+ """Draw map elements on the image."""
294
312
  # Draw charger if enabled
295
313
  if self.drawing_config.is_enabled(DrawableElement.CHARGER):
296
314
  img_np_array, self.charger_pos = await self.imd.async_draw_charger(
@@ -350,7 +368,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
350
368
  else:
351
369
  self.zooming = False
352
370
 
353
- img_np_array = self.async_auto_trim_and_zoom_image(
371
+ img_np_array = self.auto_trim_and_zoom_image(
354
372
  img_np_array,
355
373
  detect_colour=colors["background"],
356
374
  margin_size=int(self.shared.margins),
@@ -361,22 +379,24 @@ class ReImageHandler(BaseHandler, AutoCrop):
361
379
  return img_np_array
362
380
 
363
381
  async def _finalize_image(self, pil_img):
364
- if not self.shared.image_ref_width or not self.shared.image_ref_height:
365
- _LOGGER.warning(
366
- "Image finalization failed: Invalid image dimensions. Returning original image."
367
- )
368
- return pil_img
382
+ """Finalize the image by resizing if needed."""
383
+ if pil_img is None:
384
+ LOGGER.warning("%s: Image is None. Returning None.", self.file_name)
385
+ return None
369
386
  if self.check_zoom_and_aspect_ratio():
370
387
  resize_params = self.prepare_resize_params(pil_img, True)
371
388
  pil_img = await self.async_resize_images(resize_params)
389
+ else:
390
+ LOGGER.warning(
391
+ "%s: Invalid image dimensions. Returning original image.",
392
+ self.file_name,
393
+ )
372
394
  return pil_img
373
395
 
374
396
  async def get_rooms_attributes(
375
397
  self, destinations: JsonType = None
376
398
  ) -> tuple[RoomsProperties, Any, Any]:
377
399
  """Return the rooms attributes."""
378
- if self.room_propriety:
379
- return self.room_propriety
380
400
  if self.json_data and destinations:
381
401
  self.room_propriety = await self.extract_room_properties(
382
402
  self.json_data, destinations
@@ -401,6 +421,12 @@ class ReImageHandler(BaseHandler, AutoCrop):
401
421
  }
402
422
  # Handle active zones
403
423
  self.active_zones = self.shared.rand256_active_zone
424
+ LOGGER.debug(
425
+ "%s: Robot is in %s room (polygon detection). %s",
426
+ self.file_name,
427
+ self.robot_in_room["room"],
428
+ self.active_zones,
429
+ )
404
430
  self.zooming = False
405
431
  if self.active_zones and (
406
432
  self.robot_in_room["id"] in range(len(self.active_zones))
@@ -515,7 +541,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
515
541
  """Return the map calibration data."""
516
542
  if not self.calibration_data and self.crop_img_size:
517
543
  self.calibration_data = []
518
- _LOGGER.info(
544
+ LOGGER.info(
519
545
  "%s: Getting Calibrations points %s",
520
546
  self.file_name,
521
547
  str(self.crop_area),
@@ -6,17 +6,12 @@ Version: 0.1.9.b42
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- import logging
10
-
11
9
  from .config.drawable import Drawable
12
10
  from .config.drawable_elements import DrawableElement
13
- from .config.types import Color, JsonType, NumpyArray
11
+ from .config.types import LOGGER, Color, JsonType, NumpyArray
14
12
  from .map_data import ImageData, RandImageData
15
13
 
16
14
 
17
- _LOGGER = logging.getLogger(__name__)
18
-
19
-
20
15
  class ImageDraw:
21
16
  """Class to handle the image creation."""
22
17
 
@@ -48,7 +43,7 @@ class ImageDraw:
48
43
  )
49
44
  return np_array
50
45
  except KeyError as e:
51
- _LOGGER.warning(
46
+ LOGGER.warning(
52
47
  "%s: Error in extraction of go-to target: %s",
53
48
  self.file_name,
54
49
  e,
@@ -70,7 +65,7 @@ class ImageDraw:
70
65
  )
71
66
  except ValueError as e:
72
67
  self.img_h.segment_data = None
73
- _LOGGER.info("%s: No segments data found: %s", self.file_name, e)
68
+ LOGGER.info("%s: No segments data found: %s", self.file_name, e)
74
69
 
75
70
  async def async_draw_base_layer(
76
71
  self,
@@ -87,13 +82,13 @@ class ImageDraw:
87
82
  walls_data = self.data.get_rrm_walls(m_json)
88
83
  floor_data = self.data.get_rrm_floor(m_json)
89
84
 
90
- _LOGGER.info("%s: Empty image with background color", self.file_name)
85
+ LOGGER.info("%s: Empty image with background color", self.file_name)
91
86
  img_np_array = await self.draw.create_empty_image(
92
87
  self.img_h.img_size["x"], self.img_h.img_size["y"], color_background
93
88
  )
94
89
  room_id = 0
95
90
  if self.img_h.frame_number == 0:
96
- _LOGGER.info("%s: Overlapping Layers", self.file_name)
91
+ LOGGER.info("%s: Overlapping Layers", self.file_name)
97
92
 
98
93
  # checking if there are segments too (sorted pixels in the raw data).
99
94
  await self.async_segment_data(m_json, size_x, size_y, pos_top, pos_left)
@@ -148,10 +143,10 @@ class ImageDraw:
148
143
  room_id = 0
149
144
  rooms_list = [color_wall]
150
145
  if not segment_data:
151
- _LOGGER.info("%s: No segments data found.", self.file_name)
146
+ LOGGER.info("%s: No segments data found.", self.file_name)
152
147
  return room_id, img_np_array
153
148
 
154
- _LOGGER.info("%s: Drawing segments.", self.file_name)
149
+ LOGGER.info("%s: Drawing segments.", self.file_name)
155
150
  for pixels in segment_data:
156
151
  room_color = self.img_h.shared.rooms_colors[room_id]
157
152
  rooms_list.append(room_color)
@@ -211,7 +206,7 @@ class ImageDraw:
211
206
  self.data.get_rrm_charger_position(m_json)
212
207
  )
213
208
  except KeyError as e:
214
- _LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
209
+ LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
215
210
  else:
216
211
  if charger_pos:
217
212
  charger_pos_dictionary = {
@@ -238,7 +233,7 @@ class ImageDraw:
238
233
  zone_clean = None
239
234
 
240
235
  if zone_clean:
241
- _LOGGER.info("%s: Got zones.", self.file_name)
236
+ LOGGER.info("%s: Got zones.", self.file_name)
242
237
  return await self.draw.zones(np_array, zone_clean, color_zone_clean)
243
238
  return np_array
244
239
 
@@ -252,7 +247,7 @@ class ImageDraw:
252
247
  virtual_walls = None
253
248
 
254
249
  if virtual_walls:
255
- _LOGGER.info("%s: Got virtual walls.", self.file_name)
250
+ LOGGER.info("%s: Got virtual walls.", self.file_name)
256
251
  np_array = await self.draw.draw_virtual_walls(
257
252
  np_array, virtual_walls, color_no_go
258
253
  )
@@ -280,7 +275,7 @@ class ImageDraw:
280
275
  self.data.rrm_valetudo_path_array(path_pixel["points"]), 2
281
276
  )
282
277
  except KeyError as e:
283
- _LOGGER.warning(
278
+ LOGGER.warning(
284
279
  "%s: Error extracting paths data: %s", self.file_name, str(e)
285
280
  )
286
281
  finally:
@@ -297,7 +292,7 @@ class ImageDraw:
297
292
  except (ValueError, KeyError):
298
293
  entity_dict = None
299
294
  else:
300
- _LOGGER.info("%s: Got the points in the json.", self.file_name)
295
+ LOGGER.info("%s: Got the points in the json.", self.file_name)
301
296
  return entity_dict
302
297
 
303
298
  async def async_get_robot_position(self, m_json: JsonType) -> tuple | None:
@@ -310,7 +305,7 @@ class ImageDraw:
310
305
  robot_pos = self.data.rrm_coordinates_to_valetudo(robot_pos_data)
311
306
  angle = self.data.get_rrm_robot_angle(m_json)
312
307
  except (ValueError, KeyError):
313
- _LOGGER.warning("%s No robot position found.", self.file_name)
308
+ LOGGER.warning("%s No robot position found.", self.file_name)
314
309
  return None, None, None
315
310
  finally:
316
311
  robot_position_angle = round(angle[0], 0)