valetudo-map-parser 0.1.7__py3-none-any.whl → 0.1.9a1__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.
- valetudo_map_parser/__init__.py +19 -12
- valetudo_map_parser/config/auto_crop.py +174 -116
- valetudo_map_parser/config/color_utils.py +105 -0
- valetudo_map_parser/config/colors.py +662 -13
- valetudo_map_parser/config/drawable.py +624 -279
- valetudo_map_parser/config/drawable_elements.py +292 -0
- valetudo_map_parser/config/enhanced_drawable.py +324 -0
- valetudo_map_parser/config/optimized_element_map.py +406 -0
- valetudo_map_parser/config/rand25_parser.py +42 -28
- valetudo_map_parser/config/room_outline.py +148 -0
- valetudo_map_parser/config/shared.py +29 -5
- valetudo_map_parser/config/types.py +102 -51
- valetudo_map_parser/config/utils.py +841 -0
- valetudo_map_parser/hypfer_draw.py +398 -132
- valetudo_map_parser/hypfer_handler.py +259 -241
- valetudo_map_parser/hypfer_rooms_handler.py +599 -0
- valetudo_map_parser/map_data.py +45 -64
- valetudo_map_parser/rand25_handler.py +429 -310
- valetudo_map_parser/reimg_draw.py +55 -74
- valetudo_map_parser/rooms_handler.py +470 -0
- valetudo_map_parser-0.1.9a1.dist-info/METADATA +93 -0
- valetudo_map_parser-0.1.9a1.dist-info/RECORD +27 -0
- {valetudo_map_parser-0.1.7.dist-info → valetudo_map_parser-0.1.9a1.dist-info}/WHEEL +1 -1
- valetudo_map_parser/images_utils.py +0 -398
- valetudo_map_parser-0.1.7.dist-info/METADATA +0 -23
- valetudo_map_parser-0.1.7.dist-info/RECORD +0 -20
- {valetudo_map_parser-0.1.7.dist-info → valetudo_map_parser-0.1.9a1.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.7.dist-info → valetudo_map_parser-0.1.9a1.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:
|
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
|
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 =
|
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
|
-
|
51
|
-
|
52
|
-
return np_array
|
53
|
-
except Exception as e:
|
48
|
+
return np_array
|
49
|
+
except KeyError as e:
|
54
50
|
_LOGGER.warning(
|
55
|
-
|
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(
|
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(
|
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(
|
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(
|
148
|
+
_LOGGER.info("%s: No segments data found.", self.file_name)
|
150
149
|
return room_id, img_np_array
|
151
150
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
room_color
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
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
|
213
|
-
_LOGGER.warning(
|
210
|
+
except KeyError as e:
|
211
|
+
_LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
|
214
212
|
else:
|
215
|
-
_LOGGER.debug("
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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(
|
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.
|
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(
|
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(
|
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
|
-
|
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 = {
|