valetudo-map-parser 0.1.8__py3-none-any.whl → 0.1.9a2__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.
Files changed (28) hide show
  1. valetudo_map_parser/__init__.py +19 -12
  2. valetudo_map_parser/config/auto_crop.py +174 -116
  3. valetudo_map_parser/config/color_utils.py +105 -0
  4. valetudo_map_parser/config/colors.py +662 -13
  5. valetudo_map_parser/config/drawable.py +624 -279
  6. valetudo_map_parser/config/drawable_elements.py +292 -0
  7. valetudo_map_parser/config/enhanced_drawable.py +324 -0
  8. valetudo_map_parser/config/optimized_element_map.py +406 -0
  9. valetudo_map_parser/config/rand25_parser.py +42 -28
  10. valetudo_map_parser/config/room_outline.py +148 -0
  11. valetudo_map_parser/config/shared.py +73 -6
  12. valetudo_map_parser/config/types.py +102 -51
  13. valetudo_map_parser/config/utils.py +841 -0
  14. valetudo_map_parser/hypfer_draw.py +398 -132
  15. valetudo_map_parser/hypfer_handler.py +259 -241
  16. valetudo_map_parser/hypfer_rooms_handler.py +599 -0
  17. valetudo_map_parser/map_data.py +45 -64
  18. valetudo_map_parser/rand25_handler.py +429 -310
  19. valetudo_map_parser/reimg_draw.py +55 -74
  20. valetudo_map_parser/rooms_handler.py +470 -0
  21. valetudo_map_parser-0.1.9a2.dist-info/METADATA +93 -0
  22. valetudo_map_parser-0.1.9a2.dist-info/RECORD +27 -0
  23. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a2.dist-info}/WHEEL +1 -1
  24. valetudo_map_parser/images_utils.py +0 -398
  25. valetudo_map_parser-0.1.8.dist-info/METADATA +0 -23
  26. valetudo_map_parser-0.1.8.dist-info/RECORD +0 -20
  27. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a2.dist-info}/LICENSE +0 -0
  28. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a2.dist-info}/NOTICE.txt +0 -0
@@ -1,18 +1,17 @@
1
1
  """
2
2
  Image Draw Class for Valetudo Rand256 Image Handling.
3
3
  This class is used to simplify the ImageHandler class.
4
- Version: 2024.12.0
4
+ Version: 0.1.9.b42
5
5
  """
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- import hashlib
10
- import json
11
9
  import logging
12
10
 
13
- from .config.types import Color, JsonType, NumpyArray
14
11
  from .config.drawable import Drawable
15
- from .map_data import ImageData
12
+ from .config.types import Color, JsonType, NumpyArray
13
+ from .map_data import ImageData, RandImageData
14
+
16
15
 
17
16
  _LOGGER = logging.getLogger(__name__)
18
17
 
@@ -20,12 +19,11 @@ _LOGGER = logging.getLogger(__name__)
20
19
  class ImageDraw:
21
20
  """Class to handle the image creation."""
22
21
 
23
- """It Draws each elements of the images, like the walls, zones, paths, etc."""
24
-
25
22
  def __init__(self, image_handler):
26
23
  self.img_h = image_handler
27
24
  self.file_name = self.img_h.shared.file_name
28
- self.data = ImageData
25
+ self.data = RandImageData
26
+ self.data_sup = ImageData
29
27
  self.draw = Drawable
30
28
  self.color_grey = (128, 128, 128, 255)
31
29
 
@@ -47,12 +45,13 @@ class ImageDraw:
47
45
  np_array = await self.draw.lines(
48
46
  np_array, predicted_path, 3, self.color_grey
49
47
  )
50
- return np_array
51
- else:
52
- return np_array
53
- except Exception as e:
48
+ return np_array
49
+ except KeyError as e:
54
50
  _LOGGER.warning(
55
- f"{self.file_name}: Error in extraction of go to. {e}", exc_info=True
51
+ "%s: Error in extraction of go-to target: %s",
52
+ self.file_name,
53
+ e,
54
+ exc_info=True,
56
55
  )
57
56
  return np_array
58
57
 
@@ -70,7 +69,7 @@ class ImageDraw:
70
69
  )
71
70
  except ValueError as e:
72
71
  self.img_h.segment_data = None
73
- _LOGGER.info(f"{self.file_name}: No segments data found. {e}")
72
+ _LOGGER.info("%s: No segments data found: %s", self.file_name, e)
74
73
 
75
74
  async def async_draw_base_layer(
76
75
  self,
@@ -87,13 +86,13 @@ class ImageDraw:
87
86
  walls_data = self.data.get_rrm_walls(m_json)
88
87
  floor_data = self.data.get_rrm_floor(m_json)
89
88
 
90
- _LOGGER.info(self.file_name + ": Empty image with background color")
89
+ _LOGGER.info("%s: Empty image with background color", self.file_name)
91
90
  img_np_array = await self.draw.create_empty_image(
92
91
  self.img_h.img_size["x"], self.img_h.img_size["y"], color_background
93
92
  )
94
93
  room_id = 0
95
94
  if self.img_h.frame_number == 0:
96
- _LOGGER.info(self.file_name + ": Overlapping Layers")
95
+ _LOGGER.info("%s: Overlapping Layers", self.file_name)
97
96
 
98
97
  # checking if there are segments too (sorted pixels in the raw data).
99
98
  await self.async_segment_data(m_json, size_x, size_y, pos_top, pos_left)
@@ -146,31 +145,30 @@ class ImageDraw:
146
145
  room_id = 0
147
146
  rooms_list = [color_wall]
148
147
  if not segment_data:
149
- _LOGGER.info(f"{self.file_name}: No segments data found.")
148
+ _LOGGER.info("%s: No segments data found.", self.file_name)
150
149
  return room_id, img_np_array
151
150
 
152
- if segment_data:
153
- _LOGGER.info(f"{self.file_name}: Drawing segments.")
154
- for pixels in segment_data:
155
- room_color = self.img_h.shared.rooms_colors[room_id]
156
- rooms_list.append(room_color)
157
- if (
158
- self.img_h.active_zones
159
- and len(self.img_h.active_zones) > room_id
160
- and self.img_h.active_zones[room_id] == 1
161
- ):
162
- room_color = (
163
- ((2 * room_color[0]) + color_zone_clean[0]) // 3,
164
- ((2 * room_color[1]) + color_zone_clean[1]) // 3,
165
- ((2 * room_color[2]) + color_zone_clean[2]) // 3,
166
- ((2 * room_color[3]) + color_zone_clean[3]) // 3,
167
- )
168
- img_np_array = await self.draw.from_json_to_image(
169
- img_np_array, pixels, pixel_size, room_color
151
+ _LOGGER.info("%s: Drawing segments.", self.file_name)
152
+ for pixels in segment_data:
153
+ room_color = self.img_h.shared.rooms_colors[room_id]
154
+ rooms_list.append(room_color)
155
+ if (
156
+ self.img_h.active_zones
157
+ and len(self.img_h.active_zones) > room_id
158
+ and self.img_h.active_zones[room_id] == 1
159
+ ):
160
+ room_color = (
161
+ ((2 * room_color[0]) + color_zone_clean[0]) // 3,
162
+ ((2 * room_color[1]) + color_zone_clean[1]) // 3,
163
+ ((2 * room_color[2]) + color_zone_clean[2]) // 3,
164
+ ((2 * room_color[3]) + color_zone_clean[3]) // 3,
170
165
  )
171
- room_id += 1
172
- if room_id > 15:
173
- room_id = 0
166
+ img_np_array = await self.draw.from_json_to_image(
167
+ img_np_array, pixels, pixel_size, room_color
168
+ )
169
+ room_id += 1
170
+ if room_id > 15:
171
+ room_id = 0
174
172
  return room_id, img_np_array
175
173
 
176
174
  async def _draw_walls(
@@ -209,10 +207,10 @@ class ImageDraw:
209
207
  charger_pos = self.data.rrm_coordinates_to_valetudo(
210
208
  self.data.get_rrm_charger_position(m_json)
211
209
  )
212
- except Exception as e:
213
- _LOGGER.warning(f"{self.file_name}: No charger position found. {e}")
210
+ except KeyError as e:
211
+ _LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
214
212
  else:
215
- _LOGGER.debug("charger position: %s", charger_pos)
213
+ _LOGGER.debug("Charger position: %s", charger_pos)
216
214
  if charger_pos:
217
215
  charger_pos_dictionary = {
218
216
  "x": (charger_pos[0] * 10),
@@ -223,8 +221,7 @@ class ImageDraw:
223
221
  np_array, charger_pos[0], charger_pos[1], color_charger
224
222
  )
225
223
  return np_array, charger_pos_dictionary
226
- else:
227
- return np_array, {}
224
+ return np_array, {}
228
225
 
229
226
  async def async_draw_zones(
230
227
  self,
@@ -237,12 +234,11 @@ class ImageDraw:
237
234
  zone_clean = self.data.get_rrm_currently_cleaned_zones(m_json)
238
235
  except (ValueError, KeyError):
239
236
  zone_clean = None
240
- else:
241
- _LOGGER.info(f"{self.file_name}: Got zones.")
237
+
242
238
  if zone_clean:
239
+ _LOGGER.info("%s: Got zones.", self.file_name)
243
240
  return await self.draw.zones(np_array, zone_clean, color_zone_clean)
244
- else:
245
- return np_array
241
+ return np_array
246
242
 
247
243
  async def async_draw_virtual_restrictions(
248
244
  self, m_json: JsonType, np_array: NumpyArray, color_no_go: Color
@@ -252,9 +248,9 @@ class ImageDraw:
252
248
  virtual_walls = self.data.get_rrm_virtual_walls(m_json)
253
249
  except (ValueError, KeyError):
254
250
  virtual_walls = None
255
- else:
256
- _LOGGER.info(f"{self.file_name}: Got virtual walls.")
251
+
257
252
  if virtual_walls:
253
+ _LOGGER.info("%s: Got virtual walls.", self.file_name)
258
254
  np_array = await self.draw.draw_virtual_walls(
259
255
  np_array, virtual_walls, color_no_go
260
256
  )
@@ -278,11 +274,13 @@ class ImageDraw:
278
274
  # Extract the paths data from the JSON data.
279
275
  try:
280
276
  path_pixel = self.data.get_rrm_path(m_json)
281
- path_pixel_formatted = self.data.sublist_join(
277
+ path_pixel_formatted = self.data_sup.sublist_join(
282
278
  self.data.rrm_valetudo_path_array(path_pixel["points"]), 2
283
279
  )
284
280
  except KeyError as e:
285
- _LOGGER.warning(f"{self.file_name}: Error extracting paths data: {str(e)}")
281
+ _LOGGER.warning(
282
+ "%s: Error extracting paths data: %s", self.file_name, str(e)
283
+ )
286
284
  finally:
287
285
  if path_pixel_formatted:
288
286
  np_array = await self.draw.lines(
@@ -293,32 +291,13 @@ class ImageDraw:
293
291
  async def async_get_entity_data(self, m_json: JsonType) -> dict or None:
294
292
  """Get the entity data from the JSON data."""
295
293
  try:
296
- entity_dict = self.data.find_points_entities(m_json)
294
+ entity_dict = self.data_sup.find_points_entities(m_json)
297
295
  except (ValueError, KeyError):
298
296
  entity_dict = None
299
297
  else:
300
- _LOGGER.info(f"{self.file_name}: Got the points in the json.")
298
+ _LOGGER.info("%s: Got the points in the json.", self.file_name)
301
299
  return entity_dict
302
300
 
303
- @staticmethod
304
- async def async_copy_array(original_array: NumpyArray) -> NumpyArray:
305
- """Copy the array."""
306
- return NumpyArray.copy(original_array)
307
-
308
- async def calculate_array_hash(self, layers: dict, active: list[int] = None) -> str:
309
- """Calculate the hash of the image based on the layers and active segments walls."""
310
- self.img_h.active_zones = active
311
- if layers and active:
312
- data_to_hash = {
313
- "layers": len(layers["wall"][0]),
314
- "active_segments": tuple(active),
315
- }
316
- data_json = json.dumps(data_to_hash, sort_keys=True)
317
- hash_value = hashlib.sha256(data_json.encode()).hexdigest()
318
- else:
319
- hash_value = None
320
- return hash_value
321
-
322
301
  async def async_get_robot_position(self, m_json: JsonType) -> tuple | None:
323
302
  """Get the robot position from the entity data."""
324
303
  robot_pos = None
@@ -329,14 +308,16 @@ class ImageDraw:
329
308
  robot_pos = self.data.rrm_coordinates_to_valetudo(robot_pos_data)
330
309
  angle = self.data.get_rrm_robot_angle(m_json)
331
310
  except (ValueError, KeyError):
332
- _LOGGER.warning(f"{self.file_name} No robot position found.")
311
+ _LOGGER.warning("%s No robot position found.", self.file_name)
333
312
  return None, None, None
334
313
  finally:
335
314
  robot_position_angle = round(angle[0], 0)
336
315
  if robot_pos and robot_position_angle:
337
316
  robot_position = robot_pos
338
317
  _LOGGER.debug(
339
- f"robot position: {robot_pos}, robot angle: {robot_position_angle}"
318
+ "robot position: %s, robot angle: %s",
319
+ str(robot_pos),
320
+ str(robot_position_angle),
340
321
  )
341
322
  if self.img_h.rooms_pos is None:
342
323
  self.img_h.robot_pos = {