valetudo-map-parser 0.1.8__tar.gz → 0.1.9b1__tar.gz
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-0.1.8 → valetudo_map_parser-0.1.9b1}/PKG-INFO +1 -1
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/auto_crop.py +1 -1
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/rand25_parser.py +36 -28
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/hypfer_handler.py +1 -1
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/map_data.py +17 -16
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/rand25_handler.py +162 -152
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/reimg_draw.py +52 -50
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/pyproject.toml +1 -1
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/LICENSE +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/README.md +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/__init__.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/__init__.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/colors.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/drawable.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/shared.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/types.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/hypfer_draw.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/images_utils.py +0 -0
- {valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/py.typed +0 -0
@@ -70,7 +70,7 @@ class AutoCrop:
|
|
70
70
|
)
|
71
71
|
return trimmed_width, trimmed_height
|
72
72
|
|
73
|
-
async def _async_auto_crop_data(self
|
73
|
+
async def _async_auto_crop_data(self): #, tdata=None
|
74
74
|
"""Load the auto crop data from the Camera config."""
|
75
75
|
# todo: implement this method but from config data
|
76
76
|
# if not self.imh.auto_crop:
|
@@ -162,7 +162,7 @@ class RRMapParser:
|
|
162
162
|
)
|
163
163
|
if segment_type == 0:
|
164
164
|
continue
|
165
|
-
|
165
|
+
if segment_type == 1 and pixels:
|
166
166
|
parameters["pixels"]["walls"].append(i)
|
167
167
|
else:
|
168
168
|
s = (
|
@@ -257,7 +257,7 @@ class RRMapParser:
|
|
257
257
|
|
258
258
|
@callback
|
259
259
|
def parse_rrm_data(
|
260
|
-
|
260
|
+
self, map_buf: bytes, pixels: bool = False
|
261
261
|
) -> Optional[Dict[str, Any]]:
|
262
262
|
"""Parse the complete map data."""
|
263
263
|
if not self.parse(map_buf).get("map_index"):
|
@@ -266,6 +266,18 @@ class RRMapParser:
|
|
266
266
|
parsed_map_data = {}
|
267
267
|
blocks = self.parse_block(map_buf, 0x14, None, pixels)
|
268
268
|
|
269
|
+
self._parse_image_data(parsed_map_data, blocks)
|
270
|
+
self._parse_charger_data(parsed_map_data, blocks)
|
271
|
+
self._parse_robot_data(parsed_map_data, blocks)
|
272
|
+
self._parse_zones_data(parsed_map_data, blocks)
|
273
|
+
self._parse_virtual_walls_data(parsed_map_data, blocks)
|
274
|
+
self._parse_misc_data(parsed_map_data, blocks)
|
275
|
+
|
276
|
+
return parsed_map_data
|
277
|
+
|
278
|
+
@staticmethod
|
279
|
+
def _parse_image_data(parsed_map_data: Dict[str, Any], blocks: Dict[int, Any]):
|
280
|
+
"""Parse image-related data."""
|
269
281
|
if RRMapParser.Types.IMAGE.value in blocks:
|
270
282
|
parsed_map_data["image"] = blocks[RRMapParser.Types.IMAGE.value]
|
271
283
|
for item in [
|
@@ -290,28 +302,27 @@ class RRMapParser:
|
|
290
302
|
- parsed_map_data[item["path"]]["points"][-2][0],
|
291
303
|
)
|
292
304
|
)
|
305
|
+
|
306
|
+
@staticmethod
|
307
|
+
def _parse_charger_data(parsed_map_data: Dict[str, Any], blocks: Dict[int, Any]):
|
308
|
+
"""Parse charger location data."""
|
293
309
|
if RRMapParser.Types.CHARGER_LOCATION.value in blocks:
|
294
310
|
charger = blocks[RRMapParser.Types.CHARGER_LOCATION.value]["position"]
|
295
|
-
# Assume no transformation needed here
|
296
311
|
parsed_map_data["charger"] = charger
|
297
312
|
|
313
|
+
@staticmethod
|
314
|
+
def _parse_robot_data(parsed_map_data: Dict[str, Any], blocks: Dict[int, Any]):
|
315
|
+
"""Parse robot position data."""
|
298
316
|
if RRMapParser.Types.ROBOT_POSITION.value in blocks:
|
299
317
|
robot = blocks[RRMapParser.Types.ROBOT_POSITION.value]["position"]
|
300
318
|
rob_angle = blocks[RRMapParser.Types.ROBOT_POSITION.value]["angle"]
|
301
|
-
# Assume no transformation needed here
|
302
319
|
parsed_map_data["robot"] = robot
|
303
320
|
parsed_map_data["robot_angle"] = rob_angle
|
304
321
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
]["position"]
|
309
|
-
# Assume no transformation needed here
|
310
|
-
|
322
|
+
@staticmethod
|
323
|
+
def _parse_zones_data(parsed_map_data: Dict[str, Any], blocks: Dict[int, Any]):
|
324
|
+
"""Parse zones and forbidden zones data."""
|
311
325
|
if RRMapParser.Types.CURRENTLY_CLEANED_ZONES.value in blocks:
|
312
|
-
parsed_map_data["currently_cleaned_zones"] = blocks[
|
313
|
-
RRMapParser.Types.CURRENTLY_CLEANED_ZONES.value
|
314
|
-
]
|
315
326
|
parsed_map_data["currently_cleaned_zones"] = [
|
316
327
|
[
|
317
328
|
zone[0],
|
@@ -319,13 +330,10 @@ class RRMapParser:
|
|
319
330
|
zone[2],
|
320
331
|
RRMapParser.Tools.DIMENSION_MM - zone[3],
|
321
332
|
]
|
322
|
-
for zone in
|
333
|
+
for zone in blocks[RRMapParser.Types.CURRENTLY_CLEANED_ZONES.value]
|
323
334
|
]
|
324
335
|
|
325
336
|
if RRMapParser.Types.FORBIDDEN_ZONES.value in blocks:
|
326
|
-
parsed_map_data["forbidden_zones"] = blocks[
|
327
|
-
RRMapParser.Types.FORBIDDEN_ZONES.value
|
328
|
-
]
|
329
337
|
parsed_map_data["forbidden_zones"] = [
|
330
338
|
[
|
331
339
|
zone[0],
|
@@ -337,13 +345,15 @@ class RRMapParser:
|
|
337
345
|
zone[6],
|
338
346
|
RRMapParser.Tools.DIMENSION_MM - zone[7],
|
339
347
|
]
|
340
|
-
for zone in
|
348
|
+
for zone in blocks[RRMapParser.Types.FORBIDDEN_ZONES.value]
|
341
349
|
]
|
342
350
|
|
351
|
+
@staticmethod
|
352
|
+
def _parse_virtual_walls_data(
|
353
|
+
parsed_map_data: Dict[str, Any], blocks: Dict[int, Any]
|
354
|
+
):
|
355
|
+
"""Parse virtual walls data."""
|
343
356
|
if RRMapParser.Types.VIRTUAL_WALLS.value in blocks:
|
344
|
-
parsed_map_data["virtual_walls"] = blocks[
|
345
|
-
RRMapParser.Types.VIRTUAL_WALLS.value
|
346
|
-
]
|
347
357
|
parsed_map_data["virtual_walls"] = [
|
348
358
|
[
|
349
359
|
wall[0],
|
@@ -351,18 +361,18 @@ class RRMapParser:
|
|
351
361
|
wall[2],
|
352
362
|
RRMapParser.Tools.DIMENSION_MM - wall[3],
|
353
363
|
]
|
354
|
-
for wall in
|
364
|
+
for wall in blocks[RRMapParser.Types.VIRTUAL_WALLS.value]
|
355
365
|
]
|
356
366
|
|
367
|
+
@staticmethod
|
368
|
+
def _parse_misc_data(parsed_map_data: Dict[str, Any], blocks: Dict[int, Any]):
|
369
|
+
"""Parse miscellaneous data like cleaned blocks and mop zones."""
|
357
370
|
if RRMapParser.Types.CURRENTLY_CLEANED_BLOCKS.value in blocks:
|
358
371
|
parsed_map_data["currently_cleaned_blocks"] = blocks[
|
359
372
|
RRMapParser.Types.CURRENTLY_CLEANED_BLOCKS.value
|
360
373
|
]
|
361
374
|
|
362
375
|
if RRMapParser.Types.FORBIDDEN_MOP_ZONES.value in blocks:
|
363
|
-
parsed_map_data["forbidden_mop_zones"] = blocks[
|
364
|
-
RRMapParser.Types.FORBIDDEN_MOP_ZONES.value
|
365
|
-
]
|
366
376
|
parsed_map_data["forbidden_mop_zones"] = [
|
367
377
|
[
|
368
378
|
zone[0],
|
@@ -374,11 +384,9 @@ class RRMapParser:
|
|
374
384
|
zone[6],
|
375
385
|
RRMapParser.Tools.DIMENSION_MM - zone[7],
|
376
386
|
]
|
377
|
-
for zone in
|
387
|
+
for zone in blocks[RRMapParser.Types.FORBIDDEN_MOP_ZONES.value]
|
378
388
|
]
|
379
389
|
|
380
|
-
return parsed_map_data
|
381
|
-
|
382
390
|
def parse_data(
|
383
391
|
self, payload: Optional[bytes] = None, pixels: bool = False
|
384
392
|
) -> Optional[Dict[str, Any]]:
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/hypfer_handler.py
RENAMED
@@ -2,7 +2,7 @@
|
|
2
2
|
Hypfer Image Handler Class.
|
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:
|
5
|
+
Version: 0.1.9
|
6
6
|
"""
|
7
7
|
|
8
8
|
from __future__ import annotations
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/map_data.py
RENAMED
@@ -209,10 +209,11 @@ class ImageData:
|
|
209
209
|
max_y * pixel_size,
|
210
210
|
)
|
211
211
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
212
|
+
|
213
|
+
class RandImageData:
|
214
|
+
"""This functions read directly the data from the json created
|
215
|
+
from the parser for Valetudo Re. They allow to use the
|
216
|
+
functions to draw the image without changes on the drawing class."""
|
216
217
|
|
217
218
|
@staticmethod
|
218
219
|
def from_rrm_to_compressed_pixels(
|
@@ -297,7 +298,7 @@ class ImageData:
|
|
297
298
|
except KeyError:
|
298
299
|
return None
|
299
300
|
predicted_path = ImageData.sublist_join(
|
300
|
-
|
301
|
+
RandImageData.rrm_valetudo_path_array(points), 2
|
301
302
|
)
|
302
303
|
return predicted_path
|
303
304
|
|
@@ -330,7 +331,7 @@ class ImageData:
|
|
330
331
|
return None
|
331
332
|
|
332
333
|
if path_data and path_data != []:
|
333
|
-
path_data =
|
334
|
+
path_data = RandImageData.rrm_coordinates_to_valetudo(path_data)
|
334
335
|
return path_data
|
335
336
|
return None
|
336
337
|
|
@@ -338,14 +339,14 @@ class ImageData:
|
|
338
339
|
def get_rrm_currently_cleaned_zones(json_data: JsonType) -> dict:
|
339
340
|
"""Get the currently cleaned zones from the json."""
|
340
341
|
re_zones = json_data.get("currently_cleaned_zones", [])
|
341
|
-
formatted_zones =
|
342
|
+
formatted_zones = RandImageData.rrm_valetudo_format_zone(re_zones)
|
342
343
|
return formatted_zones
|
343
344
|
|
344
345
|
@staticmethod
|
345
346
|
def get_rrm_forbidden_zones(json_data: JsonType) -> dict:
|
346
347
|
"""Get the forbidden zones from the json."""
|
347
348
|
re_zones = json_data.get("forbidden_zones", [])
|
348
|
-
formatted_zones =
|
349
|
+
formatted_zones = RandImageData.rrm_valetudo_format_zone(re_zones)
|
349
350
|
return formatted_zones
|
350
351
|
|
351
352
|
@staticmethod
|
@@ -406,7 +407,7 @@ class ImageData:
|
|
406
407
|
tmp_data = json_data.get("virtual_walls", [])
|
407
408
|
except KeyError:
|
408
409
|
return None
|
409
|
-
virtual_walls =
|
410
|
+
virtual_walls = RandImageData.rrm_valetudo_lines(tmp_data)
|
410
411
|
return virtual_walls
|
411
412
|
|
412
413
|
@staticmethod
|
@@ -424,7 +425,7 @@ class ImageData:
|
|
424
425
|
"""Get the image size from the json."""
|
425
426
|
if isinstance(json_data, tuple):
|
426
427
|
return 0, 0
|
427
|
-
image =
|
428
|
+
image = RandImageData.get_rrm_image(json_data)
|
428
429
|
if image == {}:
|
429
430
|
return 0, 0
|
430
431
|
dimensions = image.get("dimensions", {})
|
@@ -433,20 +434,20 @@ class ImageData:
|
|
433
434
|
@staticmethod
|
434
435
|
def get_rrm_image_position(json_data: JsonType) -> tuple:
|
435
436
|
"""Get the image position from the json."""
|
436
|
-
image =
|
437
|
+
image = RandImageData.get_rrm_image(json_data)
|
437
438
|
position = image.get("position", {})
|
438
439
|
return position.get("top", 0), position.get("left", 0)
|
439
440
|
|
440
441
|
@staticmethod
|
441
442
|
def get_rrm_floor(json_data: JsonType) -> list:
|
442
443
|
"""Get the floor data from the json."""
|
443
|
-
img =
|
444
|
+
img = RandImageData.get_rrm_image(json_data)
|
444
445
|
return img.get("pixels", {}).get("floor", [])
|
445
446
|
|
446
447
|
@staticmethod
|
447
448
|
def get_rrm_walls(json_data: JsonType) -> list:
|
448
449
|
"""Get the walls data from the json."""
|
449
|
-
img =
|
450
|
+
img = RandImageData.get_rrm_image(json_data)
|
450
451
|
return img.get("pixels", {}).get("walls", [])
|
451
452
|
|
452
453
|
@staticmethod
|
@@ -460,7 +461,7 @@ class ImageData:
|
|
460
461
|
) -> tuple or list:
|
461
462
|
"""Get the segments data from the json."""
|
462
463
|
|
463
|
-
img =
|
464
|
+
img = RandImageData.get_rrm_image(json_data)
|
464
465
|
seg_data = img.get("segments", {})
|
465
466
|
seg_ids = seg_data.get("id")
|
466
467
|
segments = []
|
@@ -469,7 +470,7 @@ class ImageData:
|
|
469
470
|
for id_seg in seg_ids:
|
470
471
|
tmp_data = seg_data.get("pixels_seg_" + str(id_seg))
|
471
472
|
segments.append(
|
472
|
-
|
473
|
+
RandImageData.from_rrm_to_compressed_pixels(
|
473
474
|
tmp_data,
|
474
475
|
image_width=size_x,
|
475
476
|
image_height=size_y,
|
@@ -493,7 +494,7 @@ class ImageData:
|
|
493
494
|
def get_rrm_segments_ids(json_data: JsonType) -> list or None:
|
494
495
|
"""Get the segments ids from the json."""
|
495
496
|
try:
|
496
|
-
img =
|
497
|
+
img = RandImageData.get_rrm_image(json_data)
|
497
498
|
seg_ids = img.get("segments", {}).get("id", [])
|
498
499
|
except KeyError:
|
499
500
|
return None
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/rand25_handler.py
RENAMED
@@ -2,7 +2,7 @@
|
|
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:
|
5
|
+
Version: 0.1.9
|
6
6
|
"""
|
7
7
|
|
8
8
|
from __future__ import annotations
|
@@ -11,19 +11,19 @@ import logging
|
|
11
11
|
import uuid
|
12
12
|
|
13
13
|
from PIL import Image, ImageOps
|
14
|
-
|
14
|
+
from typing import Any
|
15
15
|
from .config.types import COLORS, DEFAULT_IMAGE_SIZE, DEFAULT_PIXEL_SIZE
|
16
16
|
from .config.types import Colors, JsonType, PilPNG, RobotPosition, RoomsProperties
|
17
17
|
from .config.auto_crop import AutoCrop
|
18
18
|
from .images_utils import ImageUtils as ImUtils
|
19
|
-
from .map_data import
|
19
|
+
from .map_data import RandImageData
|
20
20
|
from .reimg_draw import ImageDraw
|
21
21
|
|
22
22
|
_LOGGER = logging.getLogger(__name__)
|
23
23
|
|
24
24
|
|
25
25
|
# noinspection PyTypeChecker
|
26
|
-
class ReImageHandler
|
26
|
+
class ReImageHandler:
|
27
27
|
"""
|
28
28
|
Image Handler for Valetudo Re Vacuums.
|
29
29
|
"""
|
@@ -35,8 +35,8 @@ class ReImageHandler(object):
|
|
35
35
|
self.calibration_data = None # Calibration data
|
36
36
|
self.charger_pos = None # Charger position
|
37
37
|
self.crop_area = None # Crop area
|
38
|
-
self.crop_img_size =
|
39
|
-
self.data =
|
38
|
+
self.crop_img_size = [] # Crop image size
|
39
|
+
self.data = RandImageData # Image Data
|
40
40
|
self.frame_number = 0 # Image Frame number
|
41
41
|
self.max_frames = 1024
|
42
42
|
self.go_to = None # Go to position data
|
@@ -72,15 +72,15 @@ class ReImageHandler(object):
|
|
72
72
|
self, json_data: JsonType, destinations: JsonType
|
73
73
|
) -> RoomsProperties:
|
74
74
|
"""Extract the room properties."""
|
75
|
-
unsorted_id =
|
76
|
-
size_x, size_y =
|
77
|
-
top, left =
|
75
|
+
unsorted_id = RandImageData.get_rrm_segments_ids(json_data)
|
76
|
+
size_x, size_y = RandImageData.get_rrm_image_size(json_data)
|
77
|
+
top, left = RandImageData.get_rrm_image_position(json_data)
|
78
78
|
try:
|
79
79
|
if not self.segment_data or not self.outlines:
|
80
80
|
(
|
81
81
|
self.segment_data,
|
82
82
|
self.outlines,
|
83
|
-
) = await
|
83
|
+
) = await RandImageData.async_get_rrm_segments(
|
84
84
|
json_data, size_x, size_y, top, left, True
|
85
85
|
)
|
86
86
|
dest_json = destinations
|
@@ -126,23 +126,23 @@ class ReImageHandler(object):
|
|
126
126
|
zone_properties = await self.imu.async_zone_propriety(zones_data)
|
127
127
|
# get the points data
|
128
128
|
point_properties = await self.imu.async_points_propriety(points_data)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
_LOGGER.debug("Zones, data extracted!")
|
129
|
+
if room_properties or zone_properties:
|
130
|
+
extracted_data = [
|
131
|
+
f"{len(room_properties)} Rooms" if room_properties else None,
|
132
|
+
f"{len(zone_properties)} Zones" if zone_properties else None,
|
133
|
+
]
|
134
|
+
extracted_data = ", ".join(filter(None, extracted_data))
|
135
|
+
_LOGGER.debug("Extracted data: %s", extracted_data)
|
137
136
|
else:
|
138
137
|
self.rooms_pos = None
|
139
138
|
_LOGGER.debug(
|
140
|
-
|
139
|
+
"%s: Rooms and Zones data not available!", self.file_name
|
141
140
|
)
|
142
141
|
return room_properties, zone_properties, point_properties
|
143
|
-
except
|
142
|
+
except RuntimeError as e:
|
144
143
|
_LOGGER.debug(
|
145
|
-
|
144
|
+
"No rooms Data or Error in extract_room_properties: %s",
|
145
|
+
e,
|
146
146
|
exc_info=True,
|
147
147
|
)
|
148
148
|
return None, None, None
|
@@ -160,154 +160,164 @@ class ReImageHandler(object):
|
|
160
160
|
|
161
161
|
try:
|
162
162
|
if (m_json is not None) and (not isinstance(m_json, tuple)):
|
163
|
-
_LOGGER.info(
|
164
|
-
# buffer json data
|
163
|
+
_LOGGER.info("%s: Composing the image for the camera.", self.file_name)
|
165
164
|
self.json_data = m_json
|
166
|
-
# get the image size
|
167
165
|
size_x, size_y = self.data.get_rrm_image_size(m_json)
|
168
|
-
##########################
|
169
166
|
self.img_size = DEFAULT_IMAGE_SIZE
|
170
|
-
###########################
|
171
167
|
self.json_id = str(uuid.uuid4()) # image id
|
172
|
-
_LOGGER.info(
|
173
|
-
|
168
|
+
_LOGGER.info("Vacuum Data ID: %s", self.json_id)
|
169
|
+
|
174
170
|
(
|
175
|
-
|
171
|
+
img_np_array,
|
176
172
|
robot_position,
|
177
173
|
robot_position_angle,
|
178
|
-
) = await self.
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
size_y,
|
184
|
-
colors["wall"],
|
185
|
-
colors["zone_clean"],
|
186
|
-
colors["background"],
|
187
|
-
DEFAULT_PIXEL_SIZE,
|
188
|
-
)
|
189
|
-
_LOGGER.info(f"{self.file_name}: Completed base Layers")
|
190
|
-
if (room_id > 0) and not self.room_propriety:
|
191
|
-
self.room_propriety = await self.get_rooms_attributes(
|
192
|
-
destinations
|
193
|
-
)
|
194
|
-
if self.rooms_pos:
|
195
|
-
self.robot_pos = await self.async_get_robot_in_room(
|
196
|
-
(robot_position[0] * 10),
|
197
|
-
(robot_position[1] * 10),
|
198
|
-
robot_position_angle,
|
199
|
-
)
|
200
|
-
self.img_base_layer = await self.imd.async_copy_array(img_np_array)
|
201
|
-
|
202
|
-
# If there is a zone clean we draw it now.
|
174
|
+
) = await self._setup_robot_and_image(
|
175
|
+
m_json, size_x, size_y, colors, destinations
|
176
|
+
)
|
177
|
+
|
178
|
+
# Increment frame number
|
203
179
|
self.frame_number += 1
|
204
180
|
img_np_array = await self.imd.async_copy_array(self.img_base_layer)
|
205
|
-
_LOGGER.debug(f"{self.file_name}: Frame number {self.frame_number}")
|
206
|
-
if self.frame_number > 5:
|
207
|
-
self.frame_number = 0
|
208
|
-
# All below will be drawn each time
|
209
|
-
# charger
|
210
|
-
img_np_array, self.charger_pos = await self.imd.async_draw_charger(
|
211
|
-
img_np_array, m_json, colors["charger"]
|
212
|
-
)
|
213
|
-
# zone clean
|
214
|
-
img_np_array = await self.imd.async_draw_zones(
|
215
|
-
m_json, img_np_array, colors["zone_clean"]
|
216
|
-
)
|
217
|
-
# virtual walls
|
218
|
-
img_np_array = await self.imd.async_draw_virtual_restrictions(
|
219
|
-
m_json, img_np_array, colors["no_go"]
|
220
|
-
)
|
221
|
-
# draw path
|
222
|
-
img_np_array = await self.imd.async_draw_path(
|
223
|
-
img_np_array, m_json, colors["move"]
|
224
|
-
)
|
225
|
-
# go to flag and predicted path
|
226
|
-
await self.imd.async_draw_go_to_flag(
|
227
|
-
img_np_array, m_json, colors["go_to"]
|
228
|
-
)
|
229
|
-
# draw the robot
|
230
|
-
img_np_array = await self.imd.async_draw_robot_on_map(
|
231
|
-
img_np_array, robot_position, robot_position_angle, colors["robot"]
|
232
|
-
)
|
233
181
|
_LOGGER.debug(
|
234
|
-
|
235
|
-
f" Auto cropping the image with rotation {int(self.shared.image_rotate)}"
|
182
|
+
"%s: Frame number %s", self.file_name, str(self.frame_number)
|
236
183
|
)
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
rand256=True,
|
184
|
+
if self.frame_number > 5:
|
185
|
+
self.frame_number = 0
|
186
|
+
|
187
|
+
# Draw map elements
|
188
|
+
img_np_array = await self._draw_map_elements(
|
189
|
+
img_np_array, m_json, colors, robot_position, robot_position_angle
|
244
190
|
)
|
191
|
+
|
192
|
+
# Final adjustments
|
245
193
|
pil_img = Image.fromarray(img_np_array, mode="RGBA")
|
246
194
|
del img_np_array # free memory
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
and self.shared.vacuum_state == "cleaning"
|
251
|
-
and self.zooming
|
252
|
-
and self.shared.image_zoom_lock_ratio
|
253
|
-
or self.shared.image_aspect_ratio != "None"
|
254
|
-
):
|
255
|
-
width = self.shared.image_ref_width
|
256
|
-
height = self.shared.image_ref_height
|
257
|
-
if self.shared.image_aspect_ratio != "None":
|
258
|
-
wsf, hsf = [
|
259
|
-
int(x) for x in self.shared.image_aspect_ratio.split(",")
|
260
|
-
]
|
261
|
-
_LOGGER.debug(f"Aspect Ratio: {wsf}, {hsf}")
|
262
|
-
if wsf == 0 or hsf == 0:
|
263
|
-
return pil_img
|
264
|
-
new_aspect_ratio = wsf / hsf
|
265
|
-
aspect_ratio = width / height
|
266
|
-
if aspect_ratio > new_aspect_ratio:
|
267
|
-
new_width = int(pil_img.height * new_aspect_ratio)
|
268
|
-
new_height = pil_img.height
|
269
|
-
else:
|
270
|
-
new_width = pil_img.width
|
271
|
-
new_height = int(pil_img.width / new_aspect_ratio)
|
272
|
-
|
273
|
-
resized = ImageOps.pad(pil_img, (new_width, new_height))
|
274
|
-
(
|
275
|
-
self.crop_img_size[0],
|
276
|
-
self.crop_img_size[1],
|
277
|
-
) = await self.async_map_coordinates_offset(
|
278
|
-
wsf, hsf, new_width, new_height
|
279
|
-
)
|
280
|
-
_LOGGER.debug(
|
281
|
-
f"{self.file_name}: Image Aspect Ratio ({wsf}, {hsf}): {new_width}x{new_height}"
|
282
|
-
)
|
283
|
-
_LOGGER.debug(f"{self.file_name}: Frame Completed.")
|
284
|
-
return resized
|
285
|
-
else:
|
286
|
-
_LOGGER.debug(f"{self.file_name}: Frame Completed.")
|
287
|
-
return ImageOps.pad(pil_img, (width, height))
|
288
|
-
else:
|
289
|
-
_LOGGER.debug(f"{self.file_name}: Frame Completed.")
|
290
|
-
return pil_img
|
195
|
+
|
196
|
+
return await self._finalize_image(pil_img)
|
197
|
+
|
291
198
|
except (RuntimeError, RuntimeWarning) as e:
|
292
199
|
_LOGGER.warning(
|
293
|
-
|
200
|
+
"%s: Runtime Error %s during image creation.",
|
201
|
+
self.file_name,
|
202
|
+
str(e),
|
294
203
|
exc_info=True,
|
295
204
|
)
|
296
205
|
return None
|
297
206
|
|
207
|
+
async def _setup_robot_and_image(
|
208
|
+
self, m_json, size_x, size_y, colors, destinations
|
209
|
+
):
|
210
|
+
_, robot_position, robot_position_angle = await self.imd.async_get_robot_position(
|
211
|
+
m_json
|
212
|
+
)
|
213
|
+
if self.frame_number == 0:
|
214
|
+
room_id, img_np_array = await self.imd.async_draw_base_layer(
|
215
|
+
m_json,
|
216
|
+
size_x,
|
217
|
+
size_y,
|
218
|
+
colors["wall"],
|
219
|
+
colors["zone_clean"],
|
220
|
+
colors["background"],
|
221
|
+
DEFAULT_PIXEL_SIZE,
|
222
|
+
)
|
223
|
+
_LOGGER.info("%s: Completed base Layers", self.file_name)
|
224
|
+
if (room_id > 0) and not self.room_propriety:
|
225
|
+
self.room_propriety = await self.get_rooms_attributes(destinations)
|
226
|
+
if self.rooms_pos:
|
227
|
+
self.robot_pos = await self.async_get_robot_in_room(
|
228
|
+
(robot_position[0] * 10),
|
229
|
+
(robot_position[1] * 10),
|
230
|
+
robot_position_angle,
|
231
|
+
)
|
232
|
+
self.img_base_layer = await self.imd.async_copy_array(img_np_array)
|
233
|
+
return self.img_base_layer, robot_position, robot_position_angle
|
234
|
+
|
235
|
+
async def _draw_map_elements(
|
236
|
+
self, img_np_array, m_json, colors, robot_position, robot_position_angle
|
237
|
+
):
|
238
|
+
img_np_array, self.charger_pos = await self.imd.async_draw_charger(
|
239
|
+
img_np_array, m_json, colors["charger"]
|
240
|
+
)
|
241
|
+
img_np_array = await self.imd.async_draw_zones(
|
242
|
+
m_json, img_np_array, colors["zone_clean"]
|
243
|
+
)
|
244
|
+
img_np_array = await self.imd.async_draw_virtual_restrictions(
|
245
|
+
m_json, img_np_array, colors["no_go"]
|
246
|
+
)
|
247
|
+
img_np_array = await self.imd.async_draw_path(
|
248
|
+
img_np_array, m_json, colors["move"]
|
249
|
+
)
|
250
|
+
await self.imd.async_draw_go_to_flag(img_np_array, m_json, colors["go_to"])
|
251
|
+
img_np_array = await self.imd.async_draw_robot_on_map(
|
252
|
+
img_np_array, robot_position, robot_position_angle, colors["robot"]
|
253
|
+
)
|
254
|
+
img_np_array = await self.ac.async_auto_trim_and_zoom_image(
|
255
|
+
img_np_array,
|
256
|
+
colors["background"],
|
257
|
+
int(self.shared.margins),
|
258
|
+
int(self.shared.image_rotate),
|
259
|
+
self.zooming,
|
260
|
+
rand256=True,
|
261
|
+
)
|
262
|
+
return img_np_array
|
263
|
+
|
264
|
+
async def _finalize_image(self, pil_img):
|
265
|
+
if (
|
266
|
+
self.shared.image_auto_zoom
|
267
|
+
and self.shared.vacuum_state == "cleaning"
|
268
|
+
and self.zooming
|
269
|
+
and self.shared.image_zoom_lock_ratio
|
270
|
+
or self.shared.image_aspect_ratio != "None"
|
271
|
+
):
|
272
|
+
width = self.shared.image_ref_width
|
273
|
+
height = self.shared.image_ref_height
|
274
|
+
if self.shared.image_aspect_ratio != "None":
|
275
|
+
wsf, hsf = [int(x) for x in self.shared.image_aspect_ratio.split(",")]
|
276
|
+
_LOGGER.debug("Aspect Ratio: %s, %s", str(wsf), str(hsf))
|
277
|
+
if wsf == 0 or hsf == 0:
|
278
|
+
return pil_img
|
279
|
+
new_aspect_ratio = wsf / hsf
|
280
|
+
aspect_ratio = width / height
|
281
|
+
if aspect_ratio > new_aspect_ratio:
|
282
|
+
new_width = int(pil_img.height * new_aspect_ratio)
|
283
|
+
new_height = pil_img.height
|
284
|
+
else:
|
285
|
+
new_width = pil_img.width
|
286
|
+
new_height = int(pil_img.width / new_aspect_ratio)
|
287
|
+
|
288
|
+
resized = ImageOps.pad(pil_img, (new_width, new_height))
|
289
|
+
(
|
290
|
+
self.crop_img_size[0],
|
291
|
+
self.crop_img_size[1],
|
292
|
+
) = await self.async_map_coordinates_offset(
|
293
|
+
wsf, hsf, new_width, new_height
|
294
|
+
)
|
295
|
+
_LOGGER.debug(
|
296
|
+
"%s: Image Aspect Ratio: %s, %s",
|
297
|
+
self.file_name,
|
298
|
+
str(wsf),
|
299
|
+
str(hsf),
|
300
|
+
)
|
301
|
+
_LOGGER.debug("%s: Resized Frame Completed.", self.file_name)
|
302
|
+
return resized
|
303
|
+
_LOGGER.debug("%s: Padded Frame Completed.", self.file_name)
|
304
|
+
return ImageOps.pad(pil_img, (width, height))
|
305
|
+
_LOGGER.debug("%s: Frame Completed.", self.file_name)
|
306
|
+
return pil_img
|
307
|
+
|
298
308
|
def get_frame_number(self) -> int:
|
299
309
|
"""Return the frame number."""
|
300
310
|
return self.frame_number
|
301
311
|
|
302
|
-
def get_robot_position(self) ->
|
312
|
+
def get_robot_position(self) -> Any:
|
303
313
|
"""Return the robot position."""
|
304
314
|
return self.robot_pos
|
305
315
|
|
306
|
-
def get_charger_position(self) ->
|
316
|
+
def get_charger_position(self) -> Any:
|
307
317
|
"""Return the charger position."""
|
308
318
|
return self.charger_pos
|
309
319
|
|
310
|
-
def get_img_size(self) ->
|
320
|
+
def get_img_size(self) -> Any:
|
311
321
|
"""Return the image size."""
|
312
322
|
return self.img_size
|
313
323
|
|
@@ -336,15 +346,13 @@ class ReImageHandler(object):
|
|
336
346
|
"""Get the robot position and return in what room is."""
|
337
347
|
|
338
348
|
def _check_robot_position(x: int, y: int) -> bool:
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
self.robot_in_room["down"] <= y
|
349
|
+
# Check if the robot coordinates are inside the room's corners
|
350
|
+
return (
|
351
|
+
self.robot_in_room["left"] >= x >= self.robot_in_room["right"]
|
352
|
+
and self.robot_in_room["up"] >= y >= self.robot_in_room["down"]
|
344
353
|
)
|
345
|
-
return x_in_room and y_in_room
|
346
354
|
|
347
|
-
#
|
355
|
+
# If the robot coordinates are inside the room's
|
348
356
|
if self.robot_in_room and _check_robot_position(robot_x, robot_y):
|
349
357
|
temp = {
|
350
358
|
"x": robot_x,
|
@@ -360,7 +368,7 @@ class ReImageHandler(object):
|
|
360
368
|
self.zooming = bool(self.active_zones[self.robot_in_room["id"]])
|
361
369
|
return temp
|
362
370
|
# else we need to search and use the async method
|
363
|
-
_LOGGER.debug(
|
371
|
+
_LOGGER.debug("%s Changed room.. searching..", self.file_name)
|
364
372
|
room_count = -1
|
365
373
|
last_room = None
|
366
374
|
if self.rooms_pos:
|
@@ -386,13 +394,13 @@ class ReImageHandler(object):
|
|
386
394
|
"in_room": self.robot_in_room["room"],
|
387
395
|
}
|
388
396
|
_LOGGER.debug(
|
389
|
-
|
397
|
+
"%s is in %s", self.file_name, self.robot_in_room["room"]
|
390
398
|
)
|
391
399
|
del room, corners, robot_x, robot_y # free memory.
|
392
400
|
return temp
|
393
401
|
del room, corners # free memory.
|
394
402
|
_LOGGER.debug(
|
395
|
-
|
403
|
+
"%s: Not located within Camera Rooms coordinates.", self.file_name
|
396
404
|
)
|
397
405
|
self.zooming = False
|
398
406
|
self.robot_in_room = last_room
|
@@ -404,12 +412,14 @@ class ReImageHandler(object):
|
|
404
412
|
}
|
405
413
|
return temp
|
406
414
|
|
407
|
-
def get_calibration_data(self, rotation_angle: int = 0) ->
|
415
|
+
def get_calibration_data(self, rotation_angle: int = 0) -> Any:
|
408
416
|
"""Return the map calibration data."""
|
409
|
-
if not self.calibration_data:
|
417
|
+
if not self.calibration_data and self.crop_img_size:
|
410
418
|
self.calibration_data = []
|
411
419
|
_LOGGER.info(
|
412
|
-
|
420
|
+
"%s: Getting Calibrations points %s",
|
421
|
+
self.file_name,
|
422
|
+
str(self.crop_area),
|
413
423
|
)
|
414
424
|
|
415
425
|
# Define the map points (fixed)
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/reimg_draw.py
RENAMED
@@ -12,6 +12,7 @@ import logging
|
|
12
12
|
|
13
13
|
from .config.types import Color, JsonType, NumpyArray
|
14
14
|
from .config.drawable import Drawable
|
15
|
+
from .map_data import RandImageData
|
15
16
|
from .map_data import ImageData
|
16
17
|
|
17
18
|
_LOGGER = logging.getLogger(__name__)
|
@@ -20,12 +21,11 @@ _LOGGER = logging.getLogger(__name__)
|
|
20
21
|
class ImageDraw:
|
21
22
|
"""Class to handle the image creation."""
|
22
23
|
|
23
|
-
"""It Draws each elements of the images, like the walls, zones, paths, etc."""
|
24
|
-
|
25
24
|
def __init__(self, image_handler):
|
26
25
|
self.img_h = image_handler
|
27
26
|
self.file_name = self.img_h.shared.file_name
|
28
|
-
self.data =
|
27
|
+
self.data = RandImageData
|
28
|
+
self.data_sup = ImageData
|
29
29
|
self.draw = Drawable
|
30
30
|
self.color_grey = (128, 128, 128, 255)
|
31
31
|
|
@@ -47,12 +47,13 @@ class ImageDraw:
|
|
47
47
|
np_array = await self.draw.lines(
|
48
48
|
np_array, predicted_path, 3, self.color_grey
|
49
49
|
)
|
50
|
-
|
51
|
-
|
52
|
-
return np_array
|
53
|
-
except Exception as e:
|
50
|
+
return np_array
|
51
|
+
except KeyError as e:
|
54
52
|
_LOGGER.warning(
|
55
|
-
|
53
|
+
"%s: Error in extraction of go-to target: %s",
|
54
|
+
self.file_name,
|
55
|
+
e,
|
56
|
+
exc_info=True,
|
56
57
|
)
|
57
58
|
return np_array
|
58
59
|
|
@@ -70,7 +71,7 @@ class ImageDraw:
|
|
70
71
|
)
|
71
72
|
except ValueError as e:
|
72
73
|
self.img_h.segment_data = None
|
73
|
-
_LOGGER.info(
|
74
|
+
_LOGGER.info("%s: No segments data found: %s", self.file_name, e)
|
74
75
|
|
75
76
|
async def async_draw_base_layer(
|
76
77
|
self,
|
@@ -87,13 +88,13 @@ class ImageDraw:
|
|
87
88
|
walls_data = self.data.get_rrm_walls(m_json)
|
88
89
|
floor_data = self.data.get_rrm_floor(m_json)
|
89
90
|
|
90
|
-
_LOGGER.info(
|
91
|
+
_LOGGER.info("%s: Empty image with background color", self.file_name)
|
91
92
|
img_np_array = await self.draw.create_empty_image(
|
92
93
|
self.img_h.img_size["x"], self.img_h.img_size["y"], color_background
|
93
94
|
)
|
94
95
|
room_id = 0
|
95
96
|
if self.img_h.frame_number == 0:
|
96
|
-
_LOGGER.info(
|
97
|
+
_LOGGER.info("%s: Overlapping Layers", self.file_name)
|
97
98
|
|
98
99
|
# checking if there are segments too (sorted pixels in the raw data).
|
99
100
|
await self.async_segment_data(m_json, size_x, size_y, pos_top, pos_left)
|
@@ -146,31 +147,30 @@ class ImageDraw:
|
|
146
147
|
room_id = 0
|
147
148
|
rooms_list = [color_wall]
|
148
149
|
if not segment_data:
|
149
|
-
_LOGGER.info(
|
150
|
+
_LOGGER.info("%s: No segments data found.", self.file_name)
|
150
151
|
return room_id, img_np_array
|
151
152
|
|
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
|
153
|
+
_LOGGER.info("%s: Drawing segments.", self.file_name)
|
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,
|
170
167
|
)
|
171
|
-
|
172
|
-
|
173
|
-
|
168
|
+
img_np_array = await self.draw.from_json_to_image(
|
169
|
+
img_np_array, pixels, pixel_size, room_color
|
170
|
+
)
|
171
|
+
room_id += 1
|
172
|
+
if room_id > 15:
|
173
|
+
room_id = 0
|
174
174
|
return room_id, img_np_array
|
175
175
|
|
176
176
|
async def _draw_walls(
|
@@ -209,10 +209,10 @@ class ImageDraw:
|
|
209
209
|
charger_pos = self.data.rrm_coordinates_to_valetudo(
|
210
210
|
self.data.get_rrm_charger_position(m_json)
|
211
211
|
)
|
212
|
-
except
|
213
|
-
_LOGGER.warning(
|
212
|
+
except KeyError as e:
|
213
|
+
_LOGGER.warning("%s: No charger position found: %s", self.file_name, e)
|
214
214
|
else:
|
215
|
-
_LOGGER.debug("
|
215
|
+
_LOGGER.debug("Charger position: %s", charger_pos)
|
216
216
|
if charger_pos:
|
217
217
|
charger_pos_dictionary = {
|
218
218
|
"x": (charger_pos[0] * 10),
|
@@ -223,8 +223,7 @@ class ImageDraw:
|
|
223
223
|
np_array, charger_pos[0], charger_pos[1], color_charger
|
224
224
|
)
|
225
225
|
return np_array, charger_pos_dictionary
|
226
|
-
|
227
|
-
return np_array, {}
|
226
|
+
return np_array, {}
|
228
227
|
|
229
228
|
async def async_draw_zones(
|
230
229
|
self,
|
@@ -237,12 +236,11 @@ class ImageDraw:
|
|
237
236
|
zone_clean = self.data.get_rrm_currently_cleaned_zones(m_json)
|
238
237
|
except (ValueError, KeyError):
|
239
238
|
zone_clean = None
|
240
|
-
|
241
|
-
_LOGGER.info(f"{self.file_name}: Got zones.")
|
239
|
+
|
242
240
|
if zone_clean:
|
241
|
+
_LOGGER.info("%s: Got zones.", self.file_name)
|
243
242
|
return await self.draw.zones(np_array, zone_clean, color_zone_clean)
|
244
|
-
|
245
|
-
return np_array
|
243
|
+
return np_array
|
246
244
|
|
247
245
|
async def async_draw_virtual_restrictions(
|
248
246
|
self, m_json: JsonType, np_array: NumpyArray, color_no_go: Color
|
@@ -252,9 +250,9 @@ class ImageDraw:
|
|
252
250
|
virtual_walls = self.data.get_rrm_virtual_walls(m_json)
|
253
251
|
except (ValueError, KeyError):
|
254
252
|
virtual_walls = None
|
255
|
-
|
256
|
-
_LOGGER.info(f"{self.file_name}: Got virtual walls.")
|
253
|
+
|
257
254
|
if virtual_walls:
|
255
|
+
_LOGGER.info("%s: Got virtual walls.", self.file_name)
|
258
256
|
np_array = await self.draw.draw_virtual_walls(
|
259
257
|
np_array, virtual_walls, color_no_go
|
260
258
|
)
|
@@ -278,11 +276,13 @@ class ImageDraw:
|
|
278
276
|
# Extract the paths data from the JSON data.
|
279
277
|
try:
|
280
278
|
path_pixel = self.data.get_rrm_path(m_json)
|
281
|
-
path_pixel_formatted = self.
|
279
|
+
path_pixel_formatted = self.data_sup.sublist_join(
|
282
280
|
self.data.rrm_valetudo_path_array(path_pixel["points"]), 2
|
283
281
|
)
|
284
282
|
except KeyError as e:
|
285
|
-
_LOGGER.warning(
|
283
|
+
_LOGGER.warning(
|
284
|
+
"%s: Error extracting paths data: %s", self.file_name, str(e)
|
285
|
+
)
|
286
286
|
finally:
|
287
287
|
if path_pixel_formatted:
|
288
288
|
np_array = await self.draw.lines(
|
@@ -293,11 +293,11 @@ class ImageDraw:
|
|
293
293
|
async def async_get_entity_data(self, m_json: JsonType) -> dict or None:
|
294
294
|
"""Get the entity data from the JSON data."""
|
295
295
|
try:
|
296
|
-
entity_dict = self.
|
296
|
+
entity_dict = self.data_sup.find_points_entities(m_json)
|
297
297
|
except (ValueError, KeyError):
|
298
298
|
entity_dict = None
|
299
299
|
else:
|
300
|
-
_LOGGER.info(
|
300
|
+
_LOGGER.info("%s: Got the points in the json.", self.file_name)
|
301
301
|
return entity_dict
|
302
302
|
|
303
303
|
@staticmethod
|
@@ -329,14 +329,16 @@ class ImageDraw:
|
|
329
329
|
robot_pos = self.data.rrm_coordinates_to_valetudo(robot_pos_data)
|
330
330
|
angle = self.data.get_rrm_robot_angle(m_json)
|
331
331
|
except (ValueError, KeyError):
|
332
|
-
_LOGGER.warning(
|
332
|
+
_LOGGER.warning("%s No robot position found.", self.file_name)
|
333
333
|
return None, None, None
|
334
334
|
finally:
|
335
335
|
robot_position_angle = round(angle[0], 0)
|
336
336
|
if robot_pos and robot_position_angle:
|
337
337
|
robot_position = robot_pos
|
338
338
|
_LOGGER.debug(
|
339
|
-
|
339
|
+
"robot position: %s, robot angle: %s",
|
340
|
+
str(robot_pos),
|
341
|
+
str(robot_position_angle),
|
340
342
|
)
|
341
343
|
if self.img_h.rooms_pos is None:
|
342
344
|
self.img_h.robot_pos = {
|
File without changes
|
File without changes
|
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/__init__.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/__init__.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/colors.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/drawable.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/shared.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/config/types.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/hypfer_draw.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.8 → valetudo_map_parser-0.1.9b1}/SCR/valetudo_map_parser/images_utils.py
RENAMED
File without changes
|
File without changes
|