valetudo-map-parser 0.1.8__py3-none-any.whl → 0.1.9__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 (30) hide show
  1. valetudo_map_parser/__init__.py +28 -13
  2. valetudo_map_parser/config/async_utils.py +93 -0
  3. valetudo_map_parser/config/auto_crop.py +312 -123
  4. valetudo_map_parser/config/color_utils.py +105 -0
  5. valetudo_map_parser/config/colors.py +662 -13
  6. valetudo_map_parser/config/drawable.py +613 -268
  7. valetudo_map_parser/config/drawable_elements.py +292 -0
  8. valetudo_map_parser/config/enhanced_drawable.py +324 -0
  9. valetudo_map_parser/config/optimized_element_map.py +406 -0
  10. valetudo_map_parser/config/rand256_parser.py +395 -0
  11. valetudo_map_parser/config/shared.py +94 -11
  12. valetudo_map_parser/config/types.py +105 -52
  13. valetudo_map_parser/config/utils.py +1025 -0
  14. valetudo_map_parser/hypfer_draw.py +464 -148
  15. valetudo_map_parser/hypfer_handler.py +366 -259
  16. valetudo_map_parser/hypfer_rooms_handler.py +599 -0
  17. valetudo_map_parser/map_data.py +56 -66
  18. valetudo_map_parser/rand256_handler.py +674 -0
  19. valetudo_map_parser/reimg_draw.py +68 -84
  20. valetudo_map_parser/rooms_handler.py +474 -0
  21. valetudo_map_parser-0.1.9.dist-info/METADATA +93 -0
  22. valetudo_map_parser-0.1.9.dist-info/RECORD +27 -0
  23. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9.dist-info}/WHEEL +1 -1
  24. valetudo_map_parser/config/rand25_parser.py +0 -398
  25. valetudo_map_parser/images_utils.py +0 -398
  26. valetudo_map_parser/rand25_handler.py +0 -455
  27. valetudo_map_parser-0.1.8.dist-info/METADATA +0 -23
  28. valetudo_map_parser-0.1.8.dist-info/RECORD +0 -20
  29. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9.dist-info}/LICENSE +0 -0
  30. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9.dist-info}/NOTICE.txt +0 -0
@@ -1,18 +1,18 @@
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.drawable_elements import DrawableElement
13
+ from .config.types import Color, JsonType, NumpyArray
14
+ from .map_data import ImageData, RandImageData
15
+
16
16
 
17
17
  _LOGGER = logging.getLogger(__name__)
18
18
 
@@ -20,12 +20,11 @@ _LOGGER = logging.getLogger(__name__)
20
20
  class ImageDraw:
21
21
  """Class to handle the image creation."""
22
22
 
23
- """It Draws each elements of the images, like the walls, zones, paths, etc."""
24
-
25
23
  def __init__(self, image_handler):
26
24
  self.img_h = image_handler
27
25
  self.file_name = self.img_h.shared.file_name
28
- self.data = ImageData
26
+ self.data = RandImageData
27
+ self.data_sup = ImageData
29
28
  self.draw = Drawable
30
29
  self.color_grey = (128, 128, 128, 255)
31
30
 
@@ -47,12 +46,13 @@ class ImageDraw:
47
46
  np_array = await self.draw.lines(
48
47
  np_array, predicted_path, 3, self.color_grey
49
48
  )
50
- return np_array
51
- else:
52
- return np_array
53
- except Exception as e:
49
+ return np_array
50
+ except KeyError as e:
54
51
  _LOGGER.warning(
55
- f"{self.file_name}: Error in extraction of go to. {e}", exc_info=True
52
+ "%s: Error in extraction of go-to target: %s",
53
+ self.file_name,
54
+ e,
55
+ exc_info=True,
56
56
  )
57
57
  return np_array
58
58
 
@@ -70,7 +70,7 @@ class ImageDraw:
70
70
  )
71
71
  except ValueError as e:
72
72
  self.img_h.segment_data = None
73
- _LOGGER.info(f"{self.file_name}: No segments data found. {e}")
73
+ _LOGGER.info("%s: No segments data found: %s", self.file_name, e)
74
74
 
75
75
  async def async_draw_base_layer(
76
76
  self,
@@ -87,13 +87,13 @@ class ImageDraw:
87
87
  walls_data = self.data.get_rrm_walls(m_json)
88
88
  floor_data = self.data.get_rrm_floor(m_json)
89
89
 
90
- _LOGGER.info(self.file_name + ": Empty image with background color")
90
+ _LOGGER.info("%s: Empty image with background color", self.file_name)
91
91
  img_np_array = await self.draw.create_empty_image(
92
92
  self.img_h.img_size["x"], self.img_h.img_size["y"], color_background
93
93
  )
94
94
  room_id = 0
95
95
  if self.img_h.frame_number == 0:
96
- _LOGGER.info(self.file_name + ": Overlapping Layers")
96
+ _LOGGER.info("%s: Overlapping Layers", self.file_name)
97
97
 
98
98
  # checking if there are segments too (sorted pixels in the raw data).
99
99
  await self.async_segment_data(m_json, size_x, size_y, pos_top, pos_left)
@@ -108,16 +108,18 @@ class ImageDraw:
108
108
  color_wall,
109
109
  color_zone_clean,
110
110
  )
111
- img_np_array = await self._draw_walls(
112
- img_np_array,
113
- walls_data,
114
- size_x,
115
- size_y,
116
- pos_top,
117
- pos_left,
118
- pixel_size,
119
- color_wall,
120
- )
111
+ # Draw walls only if enabled in drawing config
112
+ if self.img_h.drawing_config.is_enabled(DrawableElement.WALL):
113
+ img_np_array = await self._draw_walls(
114
+ img_np_array,
115
+ walls_data,
116
+ size_x,
117
+ size_y,
118
+ pos_top,
119
+ pos_left,
120
+ pixel_size,
121
+ color_wall,
122
+ )
121
123
  return room_id, img_np_array
122
124
 
123
125
  async def _draw_floor(
@@ -146,31 +148,30 @@ class ImageDraw:
146
148
  room_id = 0
147
149
  rooms_list = [color_wall]
148
150
  if not segment_data:
149
- _LOGGER.info(f"{self.file_name}: No segments data found.")
151
+ _LOGGER.info("%s: No segments data found.", self.file_name)
150
152
  return room_id, img_np_array
151
153
 
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
154
+ _LOGGER.info("%s: Drawing segments.", self.file_name)
155
+ for pixels in segment_data:
156
+ room_color = self.img_h.shared.rooms_colors[room_id]
157
+ rooms_list.append(room_color)
158
+ if (
159
+ self.img_h.active_zones
160
+ and len(self.img_h.active_zones) > room_id
161
+ and self.img_h.active_zones[room_id] == 1
162
+ ):
163
+ room_color = (
164
+ ((2 * room_color[0]) + color_zone_clean[0]) // 3,
165
+ ((2 * room_color[1]) + color_zone_clean[1]) // 3,
166
+ ((2 * room_color[2]) + color_zone_clean[2]) // 3,
167
+ ((2 * room_color[3]) + color_zone_clean[3]) // 3,
170
168
  )
171
- room_id += 1
172
- if room_id > 15:
173
- room_id = 0
169
+ img_np_array = await self.draw.from_json_to_image(
170
+ img_np_array, pixels, pixel_size, room_color
171
+ )
172
+ room_id += 1
173
+ if room_id > 15:
174
+ room_id = 0
174
175
  return room_id, img_np_array
175
176
 
176
177
  async def _draw_walls(
@@ -209,10 +210,10 @@ class ImageDraw:
209
210
  charger_pos = self.data.rrm_coordinates_to_valetudo(
210
211
  self.data.get_rrm_charger_position(m_json)
211
212
  )
212
- except Exception as e:
213
- _LOGGER.warning(f"{self.file_name}: No charger position found. {e}")
213
+ except KeyError as e:
214
+ _LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
214
215
  else:
215
- _LOGGER.debug("charger position: %s", charger_pos)
216
+ _LOGGER.debug("Charger position: %s", charger_pos)
216
217
  if charger_pos:
217
218
  charger_pos_dictionary = {
218
219
  "x": (charger_pos[0] * 10),
@@ -223,8 +224,7 @@ class ImageDraw:
223
224
  np_array, charger_pos[0], charger_pos[1], color_charger
224
225
  )
225
226
  return np_array, charger_pos_dictionary
226
- else:
227
- return np_array, {}
227
+ return np_array, {}
228
228
 
229
229
  async def async_draw_zones(
230
230
  self,
@@ -237,12 +237,11 @@ class ImageDraw:
237
237
  zone_clean = self.data.get_rrm_currently_cleaned_zones(m_json)
238
238
  except (ValueError, KeyError):
239
239
  zone_clean = None
240
- else:
241
- _LOGGER.info(f"{self.file_name}: Got zones.")
240
+
242
241
  if zone_clean:
242
+ _LOGGER.info("%s: Got zones.", self.file_name)
243
243
  return await self.draw.zones(np_array, zone_clean, color_zone_clean)
244
- else:
245
- return np_array
244
+ return np_array
246
245
 
247
246
  async def async_draw_virtual_restrictions(
248
247
  self, m_json: JsonType, np_array: NumpyArray, color_no_go: Color
@@ -252,9 +251,9 @@ class ImageDraw:
252
251
  virtual_walls = self.data.get_rrm_virtual_walls(m_json)
253
252
  except (ValueError, KeyError):
254
253
  virtual_walls = None
255
- else:
256
- _LOGGER.info(f"{self.file_name}: Got virtual walls.")
254
+
257
255
  if virtual_walls:
256
+ _LOGGER.info("%s: Got virtual walls.", self.file_name)
258
257
  np_array = await self.draw.draw_virtual_walls(
259
258
  np_array, virtual_walls, color_no_go
260
259
  )
@@ -278,11 +277,13 @@ class ImageDraw:
278
277
  # Extract the paths data from the JSON data.
279
278
  try:
280
279
  path_pixel = self.data.get_rrm_path(m_json)
281
- path_pixel_formatted = self.data.sublist_join(
280
+ path_pixel_formatted = self.data_sup.sublist_join(
282
281
  self.data.rrm_valetudo_path_array(path_pixel["points"]), 2
283
282
  )
284
283
  except KeyError as e:
285
- _LOGGER.warning(f"{self.file_name}: Error extracting paths data: {str(e)}")
284
+ _LOGGER.warning(
285
+ "%s: Error extracting paths data: %s", self.file_name, str(e)
286
+ )
286
287
  finally:
287
288
  if path_pixel_formatted:
288
289
  np_array = await self.draw.lines(
@@ -293,32 +294,13 @@ class ImageDraw:
293
294
  async def async_get_entity_data(self, m_json: JsonType) -> dict or None:
294
295
  """Get the entity data from the JSON data."""
295
296
  try:
296
- entity_dict = self.data.find_points_entities(m_json)
297
+ entity_dict = self.data_sup.find_points_entities(m_json)
297
298
  except (ValueError, KeyError):
298
299
  entity_dict = None
299
300
  else:
300
- _LOGGER.info(f"{self.file_name}: Got the points in the json.")
301
+ _LOGGER.info("%s: Got the points in the json.", self.file_name)
301
302
  return entity_dict
302
303
 
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
304
  async def async_get_robot_position(self, m_json: JsonType) -> tuple | None:
323
305
  """Get the robot position from the entity data."""
324
306
  robot_pos = None
@@ -329,14 +311,16 @@ class ImageDraw:
329
311
  robot_pos = self.data.rrm_coordinates_to_valetudo(robot_pos_data)
330
312
  angle = self.data.get_rrm_robot_angle(m_json)
331
313
  except (ValueError, KeyError):
332
- _LOGGER.warning(f"{self.file_name} No robot position found.")
314
+ _LOGGER.warning("%s No robot position found.", self.file_name)
333
315
  return None, None, None
334
316
  finally:
335
317
  robot_position_angle = round(angle[0], 0)
336
318
  if robot_pos and robot_position_angle:
337
319
  robot_position = robot_pos
338
320
  _LOGGER.debug(
339
- f"robot position: {robot_pos}, robot angle: {robot_position_angle}"
321
+ "robot position: %s, robot angle: %s",
322
+ str(robot_pos),
323
+ str(robot_position_angle),
340
324
  )
341
325
  if self.img_h.rooms_pos is None:
342
326
  self.img_h.robot_pos = {