valetudo-map-parser 0.1.9b45__py3-none-any.whl → 0.1.9b47__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 +2 -2
- valetudo_map_parser/config/colors.py +597 -24
- valetudo_map_parser/config/drawable.py +80 -18
- valetudo_map_parser/config/drawable_elements.py +166 -70
- valetudo_map_parser/config/optimized_element_map.py +133 -90
- valetudo_map_parser/config/room_outline.py +27 -27
- valetudo_map_parser/hypfer_handler.py +34 -14
- valetudo_map_parser/map_data.py +1 -1
- valetudo_map_parser/rand25_handler.py +61 -85
- valetudo_map_parser/utils/color_utils.py +8 -8
- {valetudo_map_parser-0.1.9b45.dist-info → valetudo_map_parser-0.1.9b47.dist-info}/METADATA +1 -1
- valetudo_map_parser-0.1.9b47.dist-info/RECORD +26 -0
- valetudo_map_parser/config/colors_man.py +0 -249
- valetudo_map_parser-0.1.9b45.dist-info/RECORD +0 -27
- {valetudo_map_parser-0.1.9b45.dist-info → valetudo_map_parser-0.1.9b47.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.9b45.dist-info → valetudo_map_parser-0.1.9b47.dist-info}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.9b45.dist-info → valetudo_map_parser-0.1.9b47.dist-info}/WHEEL +0 -0
@@ -63,15 +63,15 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
63
63
|
self.imd = ImDraw(self) # Image Draw class.
|
64
64
|
self.color_grey = (128, 128, 128, 255)
|
65
65
|
self.file_name = self.shared.file_name # file name of the vacuum.
|
66
|
-
self.element_map_manager = OptimizedElementMapGenerator(
|
67
|
-
|
66
|
+
self.element_map_manager = OptimizedElementMapGenerator(
|
67
|
+
self.drawing_config, self.shared
|
68
|
+
) # Map of element codes
|
68
69
|
|
69
70
|
@staticmethod
|
70
71
|
def get_corners(x_max, x_min, y_max, y_min):
|
71
72
|
"""Get the corners of the room."""
|
72
73
|
return [(x_min, y_min), (x_max, y_min), (x_max, y_max), (x_min, y_max)]
|
73
74
|
|
74
|
-
|
75
75
|
async def extract_room_outline_from_map(self, room_id_int, pixels, pixel_size):
|
76
76
|
"""Extract the outline of a room using the pixel data and element map.
|
77
77
|
|
@@ -232,7 +232,6 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
232
232
|
size_x, size_y, colors["background"]
|
233
233
|
)
|
234
234
|
|
235
|
-
|
236
235
|
LOGGER.info("%s: Drawing map with color blending", self.file_name)
|
237
236
|
|
238
237
|
# Draw layers and segments if enabled
|
@@ -451,9 +450,14 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
451
450
|
)
|
452
451
|
|
453
452
|
# Update element map for robot position
|
454
|
-
if
|
453
|
+
if (
|
454
|
+
hasattr(self.shared, "element_map")
|
455
|
+
and self.shared.element_map is not None
|
456
|
+
):
|
455
457
|
update_element_map_with_robot(
|
456
|
-
self.shared.element_map,
|
458
|
+
self.shared.element_map,
|
459
|
+
robot_position,
|
460
|
+
DrawableElement.ROBOT,
|
457
461
|
)
|
458
462
|
# Resize the image
|
459
463
|
img_np_array = await self.async_auto_trim_and_zoom_image(
|
@@ -468,21 +472,35 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
468
472
|
LOGGER.warning("%s: Image array is None.", self.file_name)
|
469
473
|
return None
|
470
474
|
# Debug logging for element map creation
|
471
|
-
LOGGER.info(
|
472
|
-
|
475
|
+
LOGGER.info(
|
476
|
+
"%s: Frame number: %d, has element_map: %s",
|
477
|
+
self.file_name,
|
478
|
+
self.frame_number,
|
479
|
+
hasattr(self.shared, "element_map"),
|
480
|
+
)
|
473
481
|
|
474
482
|
if (self.shared.element_map is None) and (self.frame_number == 1):
|
475
483
|
# Create element map for tracking what's drawn where
|
476
|
-
LOGGER.info(
|
477
|
-
|
484
|
+
LOGGER.info(
|
485
|
+
"%s: Creating element map with shape: %s",
|
486
|
+
self.file_name,
|
487
|
+
img_np_array.shape,
|
488
|
+
)
|
478
489
|
|
479
490
|
# Generate the element map directly from JSON data
|
480
491
|
# This will create a cropped element map containing only the non-zero elements
|
481
492
|
LOGGER.info("%s: Generating element map from JSON data", self.file_name)
|
482
|
-
self.shared.element_map =
|
493
|
+
self.shared.element_map = (
|
494
|
+
await self.element_map_manager.async_generate_from_json(m_json)
|
495
|
+
)
|
483
496
|
|
484
|
-
LOGGER.info(
|
485
|
-
|
497
|
+
LOGGER.info(
|
498
|
+
"%s: Element map created with shape: %s",
|
499
|
+
self.file_name,
|
500
|
+
self.shared.element_map.shape
|
501
|
+
if self.shared.element_map is not None
|
502
|
+
else None,
|
503
|
+
)
|
486
504
|
# Convert the numpy array to a PIL image
|
487
505
|
pil_img = Image.fromarray(img_np_array, mode="RGBA")
|
488
506
|
del img_np_array
|
@@ -573,7 +591,9 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
573
591
|
|
574
592
|
def get_room_at_position(self, x: int, y: int) -> int | None:
|
575
593
|
"""Get the room ID at a specific position, or None if not a room."""
|
576
|
-
return get_room_at_position(
|
594
|
+
return get_room_at_position(
|
595
|
+
self.shared.element_map, x, y, DrawableElement.ROOM_1
|
596
|
+
)
|
577
597
|
|
578
598
|
@staticmethod
|
579
599
|
async def async_copy_array(original_array):
|
valetudo_map_parser/map_data.py
CHANGED
@@ -31,7 +31,6 @@ from .config.utils import (
|
|
31
31
|
BaseHandler,
|
32
32
|
get_element_at_position,
|
33
33
|
get_room_at_position,
|
34
|
-
handle_room_outline_error,
|
35
34
|
initialize_drawing_config,
|
36
35
|
manage_drawable_elements,
|
37
36
|
prepare_resize_params,
|
@@ -130,7 +129,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
130
129
|
|
131
130
|
async def extract_room_properties(
|
132
131
|
self, json_data: JsonType, destinations: JsonType
|
133
|
-
) ->
|
132
|
+
) -> RoomsProperties:
|
134
133
|
"""Extract the room properties."""
|
135
134
|
unsorted_id = RandImageData.get_rrm_segments_ids(json_data)
|
136
135
|
size_x, size_y = RandImageData.get_rrm_image_size(json_data)
|
@@ -150,88 +149,62 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
150
149
|
room_id_to_data = {room["id"]: room for room in room_data}
|
151
150
|
self.rooms_pos = []
|
152
151
|
room_properties = {}
|
153
|
-
if
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
# Try to extract a more accurate room outline from the element map
|
173
|
-
try:
|
174
|
-
# Extract the room outline using the element map
|
175
|
-
outline = await self.extract_room_outline_from_map(
|
176
|
-
room_id, self.segment_data[id_x]
|
152
|
+
if self.outlines:
|
153
|
+
for id_x, room_id in enumerate(unsorted_id):
|
154
|
+
if room_id in room_id_to_data:
|
155
|
+
room_info = room_id_to_data[room_id]
|
156
|
+
name = room_info.get("name")
|
157
|
+
# Calculate x and y min/max from outlines
|
158
|
+
x_min = self.outlines[id_x][0][0]
|
159
|
+
x_max = self.outlines[id_x][1][0]
|
160
|
+
y_min = self.outlines[id_x][0][1]
|
161
|
+
y_max = self.outlines[id_x][1][1]
|
162
|
+
corners = self.get_corners(x_max, x_min, y_max, y_min)
|
163
|
+
# rand256 vacuums accept int(room_id) or str(name)
|
164
|
+
# the card will soon support int(room_id) but the camera will send name
|
165
|
+
# this avoids the manual change of the values in the card.
|
166
|
+
self.rooms_pos.append(
|
167
|
+
{
|
168
|
+
"name": name,
|
169
|
+
"corners": corners,
|
170
|
+
}
|
177
171
|
)
|
178
|
-
|
179
|
-
"
|
180
|
-
|
181
|
-
room_id,
|
182
|
-
len(outline),
|
183
|
-
)
|
184
|
-
except (
|
185
|
-
ValueError,
|
186
|
-
IndexError,
|
187
|
-
TypeError,
|
188
|
-
ArithmeticError,
|
189
|
-
) as e:
|
190
|
-
handle_room_outline_error(self.file_name, room_id, e)
|
191
|
-
outline = corners
|
192
|
-
|
193
|
-
# rand256 vacuums accept int(room_id) or str(name)
|
194
|
-
# the card will soon support int(room_id) but the camera will send name
|
195
|
-
# this avoids the manual change of the values in the card.
|
196
|
-
self.rooms_pos.append(
|
197
|
-
{
|
172
|
+
room_properties[int(room_id)] = {
|
173
|
+
"number": int(room_id),
|
174
|
+
"outline": corners,
|
198
175
|
"name": name,
|
199
|
-
"
|
176
|
+
"x": (x_min + x_max) // 2,
|
177
|
+
"y": (y_min + y_max) // 2,
|
200
178
|
}
|
179
|
+
# get the zones and points data
|
180
|
+
zone_properties = await self.async_zone_propriety(zones_data)
|
181
|
+
# get the points data
|
182
|
+
point_properties = await self.async_points_propriety(points_data)
|
183
|
+
if room_properties or zone_properties:
|
184
|
+
extracted_data = [
|
185
|
+
f"{len(room_properties)} Rooms" if room_properties else None,
|
186
|
+
f"{len(zone_properties)} Zones" if zone_properties else None,
|
187
|
+
]
|
188
|
+
extracted_data = ", ".join(filter(None, extracted_data))
|
189
|
+
_LOGGER.debug("Extracted data: %s", extracted_data)
|
190
|
+
else:
|
191
|
+
self.rooms_pos = None
|
192
|
+
_LOGGER.debug(
|
193
|
+
"%s: Rooms and Zones data not available!", self.file_name
|
201
194
|
)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
"name": name,
|
206
|
-
"x": (x_min + x_max) // 2,
|
207
|
-
"y": (y_min + y_max) // 2,
|
208
|
-
}
|
209
|
-
# get the zones and points data
|
210
|
-
zone_properties = await self.async_zone_propriety(zones_data)
|
211
|
-
# get the points data
|
212
|
-
point_properties = await self.async_points_propriety(points_data)
|
213
|
-
if room_properties or zone_properties:
|
214
|
-
extracted_data = [
|
215
|
-
f"{len(room_properties)} Rooms" if room_properties else None,
|
216
|
-
f"{len(zone_properties)} Zones" if zone_properties else None,
|
217
|
-
]
|
218
|
-
extracted_data = ", ".join(filter(None, extracted_data))
|
219
|
-
_LOGGER.debug("Extracted data: %s", extracted_data)
|
195
|
+
rooms = RoomStore(self.file_name, room_properties)
|
196
|
+
_LOGGER.debug("Rooms Data: %s", rooms.get_rooms())
|
197
|
+
return room_properties, zone_properties, point_properties
|
220
198
|
else:
|
221
|
-
|
222
|
-
|
223
|
-
"%s: Rooms and Zones data not available!", self.file_name
|
224
|
-
)
|
225
|
-
rooms = RoomStore(self.file_name, room_properties)
|
226
|
-
_LOGGER.debug("Rooms Data: %s", rooms.get_rooms())
|
227
|
-
return room_properties, zone_properties, point_properties
|
199
|
+
_LOGGER.debug("%s: No outlines available", self.file_name)
|
200
|
+
return None, None, None
|
228
201
|
except (RuntimeError, ValueError) as e:
|
229
202
|
_LOGGER.debug(
|
230
203
|
"No rooms Data or Error in extract_room_properties: %s",
|
231
204
|
e,
|
232
205
|
exc_info=True,
|
233
206
|
)
|
234
|
-
return None, None, None
|
207
|
+
return None, None, None
|
235
208
|
|
236
209
|
async def get_image_from_rrm(
|
237
210
|
self,
|
@@ -475,12 +448,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
475
448
|
# If no rooms data is available, return a default position
|
476
449
|
if not self.rooms_pos:
|
477
450
|
_LOGGER.debug("%s: No rooms data available", self.file_name)
|
478
|
-
return {
|
479
|
-
"x": robot_x,
|
480
|
-
"y": robot_y,
|
481
|
-
"angle": angle,
|
482
|
-
"in_room": "unknown"
|
483
|
-
}
|
451
|
+
return {"x": robot_x, "y": robot_y, "angle": angle, "in_room": "unknown"}
|
484
452
|
|
485
453
|
# If rooms data is available, search for the room
|
486
454
|
if self.robot_in_room:
|
@@ -504,9 +472,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
504
472
|
"angle": angle,
|
505
473
|
"in_room": self.robot_in_room["room"],
|
506
474
|
}
|
507
|
-
_LOGGER.debug(
|
508
|
-
"%s is in %s", self.file_name, self.robot_in_room["room"]
|
509
|
-
)
|
475
|
+
_LOGGER.debug("%s is in %s", self.file_name, self.robot_in_room["room"])
|
510
476
|
del room, corners, robot_x, robot_y # free memory.
|
511
477
|
return temp
|
512
478
|
# After checking all rooms and not finding a match
|
@@ -586,8 +552,16 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
586
552
|
|
587
553
|
charger_radius = 15
|
588
554
|
# Handle both dictionary format {'x': x, 'y': y} and list format [x, y]
|
589
|
-
charger_x =
|
590
|
-
|
555
|
+
charger_x = (
|
556
|
+
self.charger_pos.get("x")
|
557
|
+
if isinstance(self.charger_pos, dict)
|
558
|
+
else self.charger_pos[0]
|
559
|
+
)
|
560
|
+
charger_y = (
|
561
|
+
self.charger_pos.get("y")
|
562
|
+
if isinstance(self.charger_pos, dict)
|
563
|
+
else self.charger_pos[1]
|
564
|
+
)
|
591
565
|
|
592
566
|
for dy in range(-charger_radius, charger_radius + 1):
|
593
567
|
for dx in range(-charger_radius, charger_radius + 1):
|
@@ -595,5 +569,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
595
569
|
if dx * dx + dy * dy <= charger_radius * charger_radius:
|
596
570
|
cx, cy = int(charger_x + dx), int(charger_y + dy)
|
597
571
|
# Check if the coordinates are within the element map bounds
|
598
|
-
if (0 <= cy < self.element_map.shape[0] and
|
572
|
+
if (0 <= cy < self.element_map.shape[0]) and (
|
573
|
+
0 <= cx < self.element_map.shape[1]
|
574
|
+
):
|
599
575
|
self.element_map[cy, cx] = DrawableElement.CHARGER
|
@@ -12,16 +12,16 @@ def get_blended_color(
|
|
12
12
|
x: int,
|
13
13
|
y: int,
|
14
14
|
new_element: DrawableElement,
|
15
|
-
new_color: Tuple[int, int, int, int]
|
15
|
+
new_color: Tuple[int, int, int, int],
|
16
16
|
) -> Tuple[int, int, int, int]:
|
17
17
|
"""
|
18
18
|
Get a blended color for a pixel based on the current element map and the new element to draw.
|
19
|
-
|
19
|
+
|
20
20
|
This function:
|
21
21
|
1. Gets the current element at position (x,y) from the element map
|
22
22
|
2. Gets the color for that element from the colors manager
|
23
23
|
3. Blends the new color with the existing color based on alpha values
|
24
|
-
|
24
|
+
|
25
25
|
Args:
|
26
26
|
element_map_generator: The element map generator containing the current element map
|
27
27
|
colors_manager: The colors manager to get colors for elements
|
@@ -29,20 +29,20 @@ def get_blended_color(
|
|
29
29
|
y: Y coordinate in the element map
|
30
30
|
new_element: The new element to draw at this position
|
31
31
|
new_color: The RGBA color of the new element
|
32
|
-
|
32
|
+
|
33
33
|
Returns:
|
34
34
|
Blended RGBA color to use for drawing
|
35
35
|
"""
|
36
36
|
# Get current element at this position
|
37
37
|
current_element = element_map_generator.get_element_at_position(x, y)
|
38
|
-
|
38
|
+
|
39
39
|
# If no current element or it's the same as the new element, just return the new color
|
40
40
|
if current_element is None or current_element == new_element:
|
41
41
|
return new_color
|
42
|
-
|
42
|
+
|
43
43
|
# Get color for the current element
|
44
44
|
current_color = None
|
45
|
-
|
45
|
+
|
46
46
|
# Handle different element types
|
47
47
|
if current_element == DrawableElement.FLOOR:
|
48
48
|
# Floor is the background color
|
@@ -57,6 +57,6 @@ def get_blended_color(
|
|
57
57
|
else:
|
58
58
|
# Default for unknown elements
|
59
59
|
current_color = (100, 100, 100, 255)
|
60
|
-
|
60
|
+
|
61
61
|
# Blend the colors
|
62
62
|
return colors_manager.blend_colors(current_color, new_color)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
valetudo_map_parser/__init__.py,sha256=SOxmq7LkS7eMa2N4atW7ZBbqhGEL7fpj6MsyXZpCMsk,958
|
2
|
+
valetudo_map_parser/config/__init__.py,sha256=DQ9plV3ZF_K25Dp5ZQHPDoG-40dQoJNdNi-dfNeR3Zc,48
|
3
|
+
valetudo_map_parser/config/auto_crop.py,sha256=6OvRsWzXMXBaSEvgwpaaisNdozDKiDyTmPjknFxoUMc,12624
|
4
|
+
valetudo_map_parser/config/colors.py,sha256=zF-6CGe6XA9wtnrWY8hBmqsMNOcL1x5tZY1G6evniQ0,30278
|
5
|
+
valetudo_map_parser/config/drawable.py,sha256=dZ6FZVch9GVIpT4k52I5iXWtSH9oD9KJArcK48p-OaA,23667
|
6
|
+
valetudo_map_parser/config/drawable_elements.py,sha256=Ulfgf8B4LuLCfx-FfmC7LrP8o9ll_Sncg9mR774_3KE,43140
|
7
|
+
valetudo_map_parser/config/enhanced_drawable.py,sha256=xNgFUNccstP245VgLFEA9gjB3-VvlSAJSjRgSZ3YFL0,16641
|
8
|
+
valetudo_map_parser/config/optimized_element_map.py,sha256=52BCnkvVv9bre52LeVIfT8nhnEIpc0TuWTv1xcNu0Rk,15744
|
9
|
+
valetudo_map_parser/config/rand25_parser.py,sha256=kIayyqVZBfQfAMkiArzqrrj9vqZB3pkgT0Y5ufrQmGA,16448
|
10
|
+
valetudo_map_parser/config/room_outline.py,sha256=D20D-yeyKnlmVbW9lI7bsPtQGn2XkcWow6YNOEPnWVg,4800
|
11
|
+
valetudo_map_parser/config/shared.py,sha256=WSl5rYSiTqE6YGAiwi9RILMZIQdFZRzVS8DwqzTZBbw,11309
|
12
|
+
valetudo_map_parser/config/types.py,sha256=uEJY-yYHHJWW3EZjg7hERSFrC2XuKzzRGT3C0z31Aw0,18359
|
13
|
+
valetudo_map_parser/config/utils.py,sha256=MP5_s9VFSdDERymujvDuGB8nYCXVuJcqg5tR5H9HCgY,33167
|
14
|
+
valetudo_map_parser/hypfer_draw.py,sha256=oL_RbX0LEcPvOlMrfBA38qpJkMqqVwR-oAEbZeHqLWM,19898
|
15
|
+
valetudo_map_parser/hypfer_handler.py,sha256=-nwGlfd-fqmNAHEeQFgCarr1t5v8gJTvb2ngDz_8PbM,27616
|
16
|
+
valetudo_map_parser/map_data.py,sha256=lSKD-CG-RENOcNUDnUIIpqh74DuGnLmrH46IF1_EjwQ,19117
|
17
|
+
valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
+
valetudo_map_parser/rand25_handler.py,sha256=F9o1J6JZRV3CZTS4CG3AHNHZweKRM0nzd4HLmdPZe4w,23617
|
19
|
+
valetudo_map_parser/reimg_draw.py,sha256=1q8LkNTPHEA9Tsapc_JnVw51kpPYNhaBU-KmHkefCQY,12507
|
20
|
+
valetudo_map_parser/utils/__init__.py,sha256=r-GKKSPqBkMDd2K-vWe7kAix8OBrGN5HXC1RS2tbDwo,130
|
21
|
+
valetudo_map_parser/utils/color_utils.py,sha256=VogvNcITQHvtMUrVkzKcimvKtwSw0fjH72_RWtNoULA,2394
|
22
|
+
valetudo_map_parser-0.1.9b47.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
|
23
|
+
valetudo_map_parser-0.1.9b47.dist-info/METADATA,sha256=g31rBswTXn4z29eDmjywfBptpTAohQis8e6VKI8xQXA,3321
|
24
|
+
valetudo_map_parser-0.1.9b47.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
|
25
|
+
valetudo_map_parser-0.1.9b47.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
26
|
+
valetudo_map_parser-0.1.9b47.dist-info/RECORD,,
|
@@ -1,249 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Colors RGBA
|
3
|
-
Version: v2025.02.0
|
4
|
-
"""
|
5
|
-
|
6
|
-
import logging
|
7
|
-
|
8
|
-
from .types import (
|
9
|
-
ALPHA_BACKGROUND,
|
10
|
-
ALPHA_CHARGER,
|
11
|
-
ALPHA_GO_TO,
|
12
|
-
ALPHA_MOVE,
|
13
|
-
ALPHA_NO_GO,
|
14
|
-
ALPHA_ROBOT,
|
15
|
-
ALPHA_ROOM_0,
|
16
|
-
ALPHA_ROOM_1,
|
17
|
-
ALPHA_ROOM_2,
|
18
|
-
ALPHA_ROOM_3,
|
19
|
-
ALPHA_ROOM_4,
|
20
|
-
ALPHA_ROOM_5,
|
21
|
-
ALPHA_ROOM_6,
|
22
|
-
ALPHA_ROOM_7,
|
23
|
-
ALPHA_ROOM_8,
|
24
|
-
ALPHA_ROOM_9,
|
25
|
-
ALPHA_ROOM_10,
|
26
|
-
ALPHA_ROOM_11,
|
27
|
-
ALPHA_ROOM_12,
|
28
|
-
ALPHA_ROOM_13,
|
29
|
-
ALPHA_ROOM_14,
|
30
|
-
ALPHA_ROOM_15,
|
31
|
-
ALPHA_TEXT,
|
32
|
-
ALPHA_WALL,
|
33
|
-
ALPHA_ZONE_CLEAN,
|
34
|
-
COLOR_BACKGROUND,
|
35
|
-
COLOR_CHARGER,
|
36
|
-
COLOR_GO_TO,
|
37
|
-
COLOR_MOVE,
|
38
|
-
COLOR_NO_GO,
|
39
|
-
COLOR_ROBOT,
|
40
|
-
COLOR_ROOM_0,
|
41
|
-
COLOR_ROOM_1,
|
42
|
-
COLOR_ROOM_2,
|
43
|
-
COLOR_ROOM_3,
|
44
|
-
COLOR_ROOM_4,
|
45
|
-
COLOR_ROOM_5,
|
46
|
-
COLOR_ROOM_6,
|
47
|
-
COLOR_ROOM_7,
|
48
|
-
COLOR_ROOM_8,
|
49
|
-
COLOR_ROOM_9,
|
50
|
-
COLOR_ROOM_10,
|
51
|
-
COLOR_ROOM_11,
|
52
|
-
COLOR_ROOM_12,
|
53
|
-
COLOR_ROOM_13,
|
54
|
-
COLOR_ROOM_14,
|
55
|
-
COLOR_ROOM_15,
|
56
|
-
COLOR_TEXT,
|
57
|
-
COLOR_WALL,
|
58
|
-
COLOR_ZONE_CLEAN,
|
59
|
-
)
|
60
|
-
|
61
|
-
|
62
|
-
color_transparent = (0, 0, 0, 0)
|
63
|
-
color_charger = (0, 128, 0, 255)
|
64
|
-
color_move = (238, 247, 255, 255)
|
65
|
-
color_robot = (255, 255, 204, 255)
|
66
|
-
color_no_go = (255, 0, 0, 255)
|
67
|
-
color_go_to = (0, 255, 0, 255)
|
68
|
-
color_background = (0, 125, 255, 255)
|
69
|
-
color_zone_clean = (255, 255, 255, 25)
|
70
|
-
color_wall = (255, 255, 0, 255)
|
71
|
-
color_text = (255, 255, 255, 255)
|
72
|
-
color_grey = (125, 125, 125, 255)
|
73
|
-
color_black = (0, 0, 0, 255)
|
74
|
-
color_room_0 = (135, 206, 250, 255)
|
75
|
-
color_room_1 = (176, 226, 255, 255)
|
76
|
-
color_room_2 = (164, 211, 238, 255)
|
77
|
-
color_room_3 = (141, 182, 205, 255)
|
78
|
-
color_room_4 = (96, 123, 139, 255)
|
79
|
-
color_room_5 = (224, 255, 255, 255)
|
80
|
-
color_room_6 = (209, 238, 238, 255)
|
81
|
-
color_room_7 = (180, 205, 205, 255)
|
82
|
-
color_room_8 = (122, 139, 139, 255)
|
83
|
-
color_room_9 = (175, 238, 238, 255)
|
84
|
-
color_room_10 = (84, 153, 199, 255)
|
85
|
-
color_room_11 = (133, 193, 233, 255)
|
86
|
-
color_room_12 = (245, 176, 65, 255)
|
87
|
-
color_room_13 = (82, 190, 128, 255)
|
88
|
-
color_room_14 = (72, 201, 176, 255)
|
89
|
-
color_room_15 = (165, 105, 18, 255)
|
90
|
-
|
91
|
-
rooms_color = [
|
92
|
-
color_room_0,
|
93
|
-
color_room_1,
|
94
|
-
color_room_2,
|
95
|
-
color_room_3,
|
96
|
-
color_room_4,
|
97
|
-
color_room_5,
|
98
|
-
color_room_6,
|
99
|
-
color_room_7,
|
100
|
-
color_room_8,
|
101
|
-
color_room_9,
|
102
|
-
color_room_10,
|
103
|
-
color_room_11,
|
104
|
-
color_room_12,
|
105
|
-
color_room_13,
|
106
|
-
color_room_14,
|
107
|
-
color_room_15,
|
108
|
-
]
|
109
|
-
|
110
|
-
base_colors_array = [
|
111
|
-
color_wall,
|
112
|
-
color_zone_clean,
|
113
|
-
color_robot,
|
114
|
-
color_background,
|
115
|
-
color_move,
|
116
|
-
color_charger,
|
117
|
-
color_no_go,
|
118
|
-
color_go_to,
|
119
|
-
color_text,
|
120
|
-
]
|
121
|
-
|
122
|
-
color_array = [
|
123
|
-
base_colors_array[0], # color_wall
|
124
|
-
base_colors_array[6], # color_no_go
|
125
|
-
base_colors_array[7], # color_go_to
|
126
|
-
color_black,
|
127
|
-
base_colors_array[2], # color_robot
|
128
|
-
base_colors_array[5], # color_charger
|
129
|
-
color_text,
|
130
|
-
base_colors_array[4], # color_move
|
131
|
-
base_colors_array[3], # color_background
|
132
|
-
base_colors_array[1], # color_zone_clean
|
133
|
-
color_transparent,
|
134
|
-
rooms_color,
|
135
|
-
]
|
136
|
-
|
137
|
-
_LOGGER = logging.getLogger(__name__)
|
138
|
-
|
139
|
-
|
140
|
-
class ColorsManagment:
|
141
|
-
"""Class to manage the colors.
|
142
|
-
Imports and updates the colors from the user configuration."""
|
143
|
-
|
144
|
-
def __init__(self, shared_var):
|
145
|
-
self.shared_var = shared_var
|
146
|
-
|
147
|
-
@staticmethod
|
148
|
-
def add_alpha_to_rgb(alpha_channels, rgb_colors):
|
149
|
-
"""
|
150
|
-
Add alpha channel to RGB colors using corresponding alpha channels.
|
151
|
-
|
152
|
-
Args:
|
153
|
-
alpha_channels (List[Optional[float]]): List of alpha channel values (0.0-255.0).
|
154
|
-
rgb_colors (List[Tuple[int, int, int]]): List of RGB colors.
|
155
|
-
|
156
|
-
Returns:
|
157
|
-
List[Tuple[int, int, int, int]]: List of RGBA colors with alpha channel added.
|
158
|
-
"""
|
159
|
-
if len(alpha_channels) != len(rgb_colors):
|
160
|
-
_LOGGER.error("Input lists must have the same length.")
|
161
|
-
return []
|
162
|
-
|
163
|
-
result = []
|
164
|
-
for alpha, rgb in zip(alpha_channels, rgb_colors):
|
165
|
-
try:
|
166
|
-
alpha_int = int(alpha)
|
167
|
-
if alpha_int < 0:
|
168
|
-
alpha_int = 0
|
169
|
-
elif alpha_int > 255:
|
170
|
-
alpha_int = 255
|
171
|
-
|
172
|
-
if rgb is None:
|
173
|
-
result.append((0, 0, 0, alpha_int))
|
174
|
-
else:
|
175
|
-
result.append((rgb[0], rgb[1], rgb[2], alpha_int))
|
176
|
-
except (ValueError, TypeError):
|
177
|
-
result.append(None)
|
178
|
-
|
179
|
-
return result
|
180
|
-
|
181
|
-
def set_initial_colours(self, device_info: dict) -> None:
|
182
|
-
"""Set the initial colours for the map."""
|
183
|
-
try:
|
184
|
-
user_colors = [
|
185
|
-
device_info.get(COLOR_WALL, color_wall),
|
186
|
-
device_info.get(COLOR_ZONE_CLEAN, color_zone_clean),
|
187
|
-
device_info.get(COLOR_ROBOT, color_robot),
|
188
|
-
device_info.get(COLOR_BACKGROUND, color_background),
|
189
|
-
device_info.get(COLOR_MOVE, color_move),
|
190
|
-
device_info.get(COLOR_CHARGER, color_charger),
|
191
|
-
device_info.get(COLOR_NO_GO, color_no_go),
|
192
|
-
device_info.get(COLOR_GO_TO, color_go_to),
|
193
|
-
device_info.get(COLOR_TEXT, color_text),
|
194
|
-
]
|
195
|
-
user_alpha = [
|
196
|
-
device_info.get(ALPHA_WALL, 255),
|
197
|
-
device_info.get(ALPHA_ZONE_CLEAN, 255),
|
198
|
-
device_info.get(ALPHA_ROBOT, 255),
|
199
|
-
device_info.get(ALPHA_BACKGROUND, 255),
|
200
|
-
device_info.get(ALPHA_MOVE, 255),
|
201
|
-
device_info.get(ALPHA_CHARGER, 255),
|
202
|
-
device_info.get(ALPHA_NO_GO, 255),
|
203
|
-
device_info.get(ALPHA_GO_TO, 255),
|
204
|
-
device_info.get(ALPHA_TEXT, 255),
|
205
|
-
]
|
206
|
-
rooms_colors = [
|
207
|
-
device_info.get(COLOR_ROOM_0, color_room_0),
|
208
|
-
device_info.get(COLOR_ROOM_1, color_room_1),
|
209
|
-
device_info.get(COLOR_ROOM_2, color_room_2),
|
210
|
-
device_info.get(COLOR_ROOM_3, color_room_3),
|
211
|
-
device_info.get(COLOR_ROOM_4, color_room_4),
|
212
|
-
device_info.get(COLOR_ROOM_5, color_room_5),
|
213
|
-
device_info.get(COLOR_ROOM_6, color_room_6),
|
214
|
-
device_info.get(COLOR_ROOM_7, color_room_7),
|
215
|
-
device_info.get(COLOR_ROOM_8, color_room_8),
|
216
|
-
device_info.get(COLOR_ROOM_9, color_room_9),
|
217
|
-
device_info.get(COLOR_ROOM_10, color_room_10),
|
218
|
-
device_info.get(COLOR_ROOM_11, color_room_11),
|
219
|
-
device_info.get(COLOR_ROOM_12, color_room_12),
|
220
|
-
device_info.get(COLOR_ROOM_13, color_room_13),
|
221
|
-
device_info.get(COLOR_ROOM_14, color_room_14),
|
222
|
-
device_info.get(COLOR_ROOM_15, color_room_15),
|
223
|
-
]
|
224
|
-
rooms_alpha = [
|
225
|
-
device_info.get(ALPHA_ROOM_0, 255),
|
226
|
-
device_info.get(ALPHA_ROOM_1, 255),
|
227
|
-
device_info.get(ALPHA_ROOM_2, 255),
|
228
|
-
device_info.get(ALPHA_ROOM_3, 255),
|
229
|
-
device_info.get(ALPHA_ROOM_4, 255),
|
230
|
-
device_info.get(ALPHA_ROOM_5, 255),
|
231
|
-
device_info.get(ALPHA_ROOM_6, 255),
|
232
|
-
device_info.get(ALPHA_ROOM_7, 255),
|
233
|
-
device_info.get(ALPHA_ROOM_8, 255),
|
234
|
-
device_info.get(ALPHA_ROOM_9, 255),
|
235
|
-
device_info.get(ALPHA_ROOM_10, 255),
|
236
|
-
device_info.get(ALPHA_ROOM_11, 255),
|
237
|
-
device_info.get(ALPHA_ROOM_12, 255),
|
238
|
-
device_info.get(ALPHA_ROOM_13, 255),
|
239
|
-
device_info.get(ALPHA_ROOM_14, 255),
|
240
|
-
device_info.get(ALPHA_ROOM_15, 255),
|
241
|
-
]
|
242
|
-
self.shared_var.update_user_colors(
|
243
|
-
self.add_alpha_to_rgb(user_alpha, user_colors)
|
244
|
-
)
|
245
|
-
self.shared_var.update_rooms_colors(
|
246
|
-
self.add_alpha_to_rgb(rooms_alpha, rooms_colors)
|
247
|
-
)
|
248
|
-
except (ValueError, IndexError, UnboundLocalError) as e:
|
249
|
-
_LOGGER.error("Error while populating colors: %s", e)
|