valetudo-map-parser 0.1.9b56__py3-none-any.whl → 0.1.9b57__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 +6 -2
- valetudo_map_parser/config/auto_crop.py +150 -20
- valetudo_map_parser/config/shared.py +47 -1
- valetudo_map_parser/config/types.py +2 -1
- valetudo_map_parser/config/utils.py +91 -2
- valetudo_map_parser/hypfer_draw.py +104 -49
- valetudo_map_parser/hypfer_handler.py +69 -19
- valetudo_map_parser/map_data.py +26 -2
- valetudo_map_parser/{rand25_handler.py → rand256_handler.py} +152 -33
- valetudo_map_parser/rooms_handler.py +6 -2
- {valetudo_map_parser-0.1.9b56.dist-info → valetudo_map_parser-0.1.9b57.dist-info}/METADATA +1 -1
- valetudo_map_parser-0.1.9b57.dist-info/RECORD +26 -0
- valetudo_map_parser/config/room_outline.py +0 -148
- valetudo_map_parser-0.1.9b56.dist-info/RECORD +0 -27
- {valetudo_map_parser-0.1.9b56.dist-info → valetudo_map_parser-0.1.9b57.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.9b56.dist-info → valetudo_map_parser-0.1.9b57.dist-info}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.9b56.dist-info → valetudo_map_parser-0.1.9b57.dist-info}/WHEEL +0 -0
@@ -21,11 +21,13 @@ from .config.types import (
|
|
21
21
|
Colors,
|
22
22
|
RoomsProperties,
|
23
23
|
RoomStore,
|
24
|
+
WebPBytes,
|
24
25
|
)
|
25
26
|
from .config.utils import (
|
26
27
|
BaseHandler,
|
27
28
|
initialize_drawing_config,
|
28
29
|
manage_drawable_elements,
|
30
|
+
numpy_to_webp_bytes,
|
29
31
|
prepare_resize_params,
|
30
32
|
)
|
31
33
|
from .hypfer_draw import ImageDraw as ImDraw
|
@@ -81,7 +83,11 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
81
83
|
self.rooms_pos = []
|
82
84
|
for room_id, room_data in room_properties.items():
|
83
85
|
self.rooms_pos.append(
|
84
|
-
{
|
86
|
+
{
|
87
|
+
"id": room_id,
|
88
|
+
"name": room_data["name"],
|
89
|
+
"outline": room_data["outline"],
|
90
|
+
}
|
85
91
|
)
|
86
92
|
else:
|
87
93
|
LOGGER.debug("%s: Rooms data not available!", self.file_name)
|
@@ -92,12 +98,14 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
92
98
|
async def async_get_image_from_json(
|
93
99
|
self,
|
94
100
|
m_json: json | None,
|
95
|
-
|
101
|
+
return_webp: bool = False,
|
102
|
+
) -> WebPBytes | Image.Image | None:
|
96
103
|
"""Get the image from the JSON data.
|
97
104
|
It uses the ImageDraw class to draw some of the elements of the image.
|
98
105
|
The robot itself will be drawn in this function as per some of the values are needed for other tasks.
|
99
106
|
@param m_json: The JSON data to use to draw the image.
|
100
|
-
@
|
107
|
+
@param return_webp: If True, return WebP bytes; if False, return PIL Image (default).
|
108
|
+
@return WebPBytes | Image.Image: WebP bytes or PIL Image depending on return_webp parameter.
|
101
109
|
"""
|
102
110
|
# Initialize the colors.
|
103
111
|
colors: Colors = {
|
@@ -131,6 +139,8 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
131
139
|
# Get the pixels size and layers from the JSON data
|
132
140
|
pixel_size = int(m_json["pixelSize"])
|
133
141
|
layers, active = self.data.find_layers(m_json["layers"], {}, [])
|
142
|
+
# Populate active_zones from the JSON data
|
143
|
+
self.active_zones = active
|
134
144
|
new_frame_hash = await self.calculate_array_hash(layers, active)
|
135
145
|
if self.frame_number == 0:
|
136
146
|
self.img_hash = new_frame_hash
|
@@ -240,20 +250,30 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
240
250
|
|
241
251
|
# Draw obstacles if enabled
|
242
252
|
if self.drawing_config.is_enabled(DrawableElement.OBSTACLE):
|
243
|
-
|
244
|
-
|
245
|
-
|
253
|
+
self.shared.obstacles_pos = self.data.get_obstacles(entity_dict)
|
254
|
+
if self.shared.obstacles_pos:
|
255
|
+
img_np_array = await self.imd.async_draw_obstacle(
|
256
|
+
img_np_array, self.shared.obstacles_pos, colors["no_go"]
|
257
|
+
)
|
246
258
|
# Robot and rooms position
|
247
259
|
if (room_id > 0) and not self.room_propriety:
|
248
260
|
self.room_propriety = await self.async_extract_room_properties(
|
249
261
|
self.json_data
|
250
262
|
)
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
263
|
+
|
264
|
+
# Ensure room data is available for robot room detection (even if not extracted above)
|
265
|
+
if not self.rooms_pos and not self.room_propriety:
|
266
|
+
self.room_propriety = await self.async_extract_room_properties(
|
267
|
+
self.json_data
|
268
|
+
)
|
269
|
+
|
270
|
+
# Always check robot position for zooming (moved outside the condition)
|
271
|
+
if self.rooms_pos and robot_position and robot_position_angle:
|
272
|
+
self.robot_pos = await self.imd.async_get_robot_in_room(
|
273
|
+
robot_x=(robot_position[0]),
|
274
|
+
robot_y=(robot_position[1]),
|
275
|
+
angle=robot_position_angle,
|
276
|
+
)
|
257
277
|
LOGGER.info("%s: Completed base Layers", self.file_name)
|
258
278
|
# Copy the new array in base layer.
|
259
279
|
self.img_base_layer = await self.async_copy_array(img_np_array)
|
@@ -332,6 +352,9 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
332
352
|
robot_position,
|
333
353
|
DrawableElement.ROBOT,
|
334
354
|
)
|
355
|
+
# Synchronize zooming state from ImageDraw to handler before auto-crop
|
356
|
+
self.zooming = self.imd.img_h.zooming
|
357
|
+
|
335
358
|
# Resize the image
|
336
359
|
img_np_array = await self.async_auto_trim_and_zoom_image(
|
337
360
|
img_np_array,
|
@@ -345,16 +368,43 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
345
368
|
LOGGER.warning("%s: Image array is None.", self.file_name)
|
346
369
|
return None
|
347
370
|
|
348
|
-
#
|
349
|
-
pil_img = Image.fromarray(img_np_array, mode="RGBA")
|
350
|
-
del img_np_array
|
351
|
-
# reduce the image size if the zoomed image is bigger then the original.
|
371
|
+
# Handle resizing if needed, then return based on format preference
|
352
372
|
if self.check_zoom_and_aspect_ratio():
|
373
|
+
# Convert to PIL for resizing
|
374
|
+
pil_img = Image.fromarray(img_np_array, mode="RGBA")
|
375
|
+
del img_np_array
|
353
376
|
resize_params = prepare_resize_params(self, pil_img, False)
|
354
377
|
resized_image = await self.async_resize_images(resize_params)
|
355
|
-
|
356
|
-
|
357
|
-
|
378
|
+
|
379
|
+
# Return WebP bytes or PIL Image based on parameter
|
380
|
+
if return_webp:
|
381
|
+
from .config.utils import pil_to_webp_bytes
|
382
|
+
webp_bytes = await pil_to_webp_bytes(
|
383
|
+
resized_image,
|
384
|
+
quality=90,
|
385
|
+
lossless=False
|
386
|
+
)
|
387
|
+
return webp_bytes
|
388
|
+
else:
|
389
|
+
return resized_image
|
390
|
+
else:
|
391
|
+
# Return WebP bytes or PIL Image based on parameter
|
392
|
+
if return_webp:
|
393
|
+
# Convert directly from NumPy to WebP for better performance
|
394
|
+
webp_bytes = await numpy_to_webp_bytes(
|
395
|
+
img_np_array,
|
396
|
+
quality=90,
|
397
|
+
lossless=False
|
398
|
+
)
|
399
|
+
del img_np_array
|
400
|
+
LOGGER.debug("%s: Frame Completed.", self.file_name)
|
401
|
+
return webp_bytes
|
402
|
+
else:
|
403
|
+
# Convert to PIL Image (original behavior)
|
404
|
+
pil_img = Image.fromarray(img_np_array, mode="RGBA")
|
405
|
+
del img_np_array
|
406
|
+
LOGGER.debug("%s: Frame Completed.", self.file_name)
|
407
|
+
return pil_img
|
358
408
|
except (RuntimeError, RuntimeWarning) as e:
|
359
409
|
LOGGER.warning(
|
360
410
|
"%s: Error %s during image creation.",
|
valetudo_map_parser/map_data.py
CHANGED
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
10
10
|
|
11
11
|
import numpy as np
|
12
12
|
|
13
|
-
from .config.types import
|
13
|
+
from .config.types import ImageSize, JsonType
|
14
14
|
|
15
15
|
|
16
16
|
class ImageData:
|
@@ -34,6 +34,30 @@ class ImageData:
|
|
34
34
|
# list the specific Layers, Paths, Zones and Pints in the
|
35
35
|
# Vacuums Json in parallel.
|
36
36
|
|
37
|
+
@staticmethod
|
38
|
+
def get_obstacles(entity_dict: dict) -> list:
|
39
|
+
"""Get the obstacles positions from the entity data."""
|
40
|
+
try:
|
41
|
+
obstacle_data = entity_dict.get("obstacle")
|
42
|
+
except KeyError:
|
43
|
+
return []
|
44
|
+
obstacle_positions = []
|
45
|
+
if obstacle_data:
|
46
|
+
for obstacle in obstacle_data:
|
47
|
+
label = obstacle.get("metaData", {}).get("label")
|
48
|
+
points = obstacle.get("points", [])
|
49
|
+
image_id = obstacle.get("metaData", {}).get("id")
|
50
|
+
|
51
|
+
if label and points:
|
52
|
+
obstacle_pos = {
|
53
|
+
"label": label,
|
54
|
+
"points": {"x": points[0], "y": points[1]},
|
55
|
+
"id": image_id,
|
56
|
+
}
|
57
|
+
obstacle_positions.append(obstacle_pos)
|
58
|
+
return obstacle_positions
|
59
|
+
return []
|
60
|
+
|
37
61
|
@staticmethod
|
38
62
|
def find_layers(
|
39
63
|
json_obj: JsonType, layer_dict: dict, active_list: list
|
@@ -284,7 +308,7 @@ class RandImageData:
|
|
284
308
|
Return the calculated angle and original angle.
|
285
309
|
"""
|
286
310
|
angle_c = round(json_data.get("robot_angle", 0))
|
287
|
-
angle = (360 - angle_c +
|
311
|
+
angle = (360 - angle_c + 95) if angle_c < 0 else (180 - angle_c - 85)
|
288
312
|
return angle % 360, json_data.get("robot_angle", 0)
|
289
313
|
|
290
314
|
@staticmethod
|
@@ -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: 0.1.9.
|
5
|
+
Version: 0.1.9.a6
|
6
6
|
"""
|
7
7
|
|
8
8
|
from __future__ import annotations
|
@@ -26,11 +26,13 @@ from .config.types import (
|
|
26
26
|
RobotPosition,
|
27
27
|
RoomsProperties,
|
28
28
|
RoomStore,
|
29
|
+
WebPBytes,
|
29
30
|
)
|
30
31
|
from .config.utils import (
|
31
32
|
BaseHandler,
|
32
33
|
initialize_drawing_config,
|
33
34
|
manage_drawable_elements,
|
35
|
+
numpy_to_webp_bytes,
|
34
36
|
prepare_resize_params,
|
35
37
|
)
|
36
38
|
from .map_data import RandImageData
|
@@ -68,7 +70,9 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
68
70
|
self.active_zones = None # Active zones
|
69
71
|
self.file_name = self.shared.file_name # File name
|
70
72
|
self.imd = ImageDraw(self) # Image Draw
|
71
|
-
self.rooms_handler = RandRoomsHandler(
|
73
|
+
self.rooms_handler = RandRoomsHandler(
|
74
|
+
self.file_name, self.drawing_config
|
75
|
+
) # Room data handler
|
72
76
|
|
73
77
|
async def extract_room_properties(
|
74
78
|
self, json_data: JsonType, destinations: JsonType
|
@@ -97,10 +101,17 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
97
101
|
|
98
102
|
# Update self.rooms_pos from room_properties for compatibility with other methods
|
99
103
|
self.rooms_pos = []
|
104
|
+
room_ids = [] # Collect room IDs for shared.map_rooms
|
100
105
|
for room_id, room_data in room_properties.items():
|
101
106
|
self.rooms_pos.append(
|
102
107
|
{"name": room_data["name"], "outline": room_data["outline"]}
|
103
108
|
)
|
109
|
+
# Store the room number (segment ID) for MQTT active zone mapping
|
110
|
+
room_ids.append(room_data["number"])
|
111
|
+
|
112
|
+
# Update shared.map_rooms with the room IDs for MQTT active zone mapping
|
113
|
+
self.shared.map_rooms = room_ids
|
114
|
+
_LOGGER.debug("Updated shared.map_rooms with room IDs: %s", room_ids)
|
104
115
|
|
105
116
|
# get the zones and points data
|
106
117
|
zone_properties = await self.async_zone_propriety(zones_data)
|
@@ -116,9 +127,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
116
127
|
_LOGGER.debug("Extracted data: %s", extracted_data)
|
117
128
|
else:
|
118
129
|
self.rooms_pos = None
|
119
|
-
_LOGGER.debug(
|
120
|
-
"%s: Rooms and Zones data not available!", self.file_name
|
121
|
-
)
|
130
|
+
_LOGGER.debug("%s: Rooms and Zones data not available!", self.file_name)
|
122
131
|
|
123
132
|
rooms = RoomStore(self.file_name, room_properties)
|
124
133
|
_LOGGER.debug("Rooms Data: %s", rooms.get_rooms())
|
@@ -135,8 +144,14 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
135
144
|
self,
|
136
145
|
m_json: JsonType, # json data
|
137
146
|
destinations: None = None, # MQTT destinations for labels
|
138
|
-
|
139
|
-
|
147
|
+
return_webp: bool = False,
|
148
|
+
) -> WebPBytes | Image.Image | None:
|
149
|
+
"""Generate Images from the json data.
|
150
|
+
@param m_json: The JSON data to use to draw the image.
|
151
|
+
@param destinations: MQTT destinations for labels (unused).
|
152
|
+
@param return_webp: If True, return WebP bytes; if False, return PIL Image (default).
|
153
|
+
@return WebPBytes | Image.Image: WebP bytes or PIL Image depending on return_webp parameter.
|
154
|
+
"""
|
140
155
|
colors: Colors = {
|
141
156
|
name: self.shared.user_colors[idx] for idx, name in enumerate(COLORS)
|
142
157
|
}
|
@@ -173,11 +188,21 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
173
188
|
img_np_array, m_json, colors, robot_position, robot_position_angle
|
174
189
|
)
|
175
190
|
|
176
|
-
#
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
191
|
+
# Return WebP bytes or PIL Image based on parameter
|
192
|
+
if return_webp:
|
193
|
+
# Convert directly to WebP bytes for better performance
|
194
|
+
webp_bytes = await numpy_to_webp_bytes(
|
195
|
+
img_np_array,
|
196
|
+
quality=90, # High quality for vacuum maps
|
197
|
+
lossless=False # Use lossy compression for smaller size
|
198
|
+
)
|
199
|
+
del img_np_array # free memory
|
200
|
+
return webp_bytes
|
201
|
+
else:
|
202
|
+
# Convert to PIL Image (original behavior)
|
203
|
+
pil_img = Image.fromarray(img_np_array, mode="RGBA")
|
204
|
+
del img_np_array # free memory
|
205
|
+
return await self._finalize_image(pil_img)
|
181
206
|
|
182
207
|
except (RuntimeError, RuntimeWarning) as e:
|
183
208
|
_LOGGER.warning(
|
@@ -226,12 +251,18 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
226
251
|
|
227
252
|
if room_id > 0 and not self.room_propriety:
|
228
253
|
self.room_propriety = await self.get_rooms_attributes(destinations)
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
254
|
+
|
255
|
+
# Ensure room data is available for robot room detection (even if not extracted above)
|
256
|
+
if not self.rooms_pos and not self.room_propriety:
|
257
|
+
self.room_propriety = await self.get_rooms_attributes(destinations)
|
258
|
+
|
259
|
+
# Always check robot position for zooming (fallback)
|
260
|
+
if self.rooms_pos and robot_position and not hasattr(self, "robot_pos"):
|
261
|
+
self.robot_pos = await self.async_get_robot_in_room(
|
262
|
+
(robot_position[0] * 10),
|
263
|
+
(robot_position[1] * 10),
|
264
|
+
robot_position_angle,
|
265
|
+
)
|
235
266
|
self.img_base_layer = await self.async_copy_array(img_np_array)
|
236
267
|
else:
|
237
268
|
# If floor is disabled, create an empty image
|
@@ -242,6 +273,60 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
242
273
|
size_x, size_y, background_color
|
243
274
|
)
|
244
275
|
self.img_base_layer = await self.async_copy_array(img_np_array)
|
276
|
+
|
277
|
+
# Check active zones BEFORE auto-crop to enable proper zoom functionality
|
278
|
+
# This needs to run on every frame, not just frame 0
|
279
|
+
if (
|
280
|
+
self.shared.image_auto_zoom
|
281
|
+
and self.shared.vacuum_state == "cleaning"
|
282
|
+
and robot_position
|
283
|
+
and destinations # Check if we have destinations data for room extraction
|
284
|
+
):
|
285
|
+
# Extract room data early if we have destinations
|
286
|
+
try:
|
287
|
+
temp_room_properties = (
|
288
|
+
await self.rooms_handler.async_extract_room_properties(
|
289
|
+
m_json, destinations
|
290
|
+
)
|
291
|
+
)
|
292
|
+
if temp_room_properties:
|
293
|
+
# Create temporary rooms_pos for robot room detection
|
294
|
+
temp_rooms_pos = []
|
295
|
+
for room_id, room_data in temp_room_properties.items():
|
296
|
+
temp_rooms_pos.append(
|
297
|
+
{"name": room_data["name"], "outline": room_data["outline"]}
|
298
|
+
)
|
299
|
+
|
300
|
+
# Store original rooms_pos and temporarily use the new one
|
301
|
+
original_rooms_pos = self.rooms_pos
|
302
|
+
self.rooms_pos = temp_rooms_pos
|
303
|
+
|
304
|
+
# Perform robot room detection to check active zones
|
305
|
+
robot_room_result = await self.async_get_robot_in_room(
|
306
|
+
robot_position[0], robot_position[1], robot_position_angle
|
307
|
+
)
|
308
|
+
|
309
|
+
# Restore original rooms_pos
|
310
|
+
self.rooms_pos = original_rooms_pos
|
311
|
+
|
312
|
+
except Exception as e:
|
313
|
+
_LOGGER.debug(
|
314
|
+
"%s: Early room extraction failed: %s, falling back to robot-position zoom",
|
315
|
+
self.file_name,
|
316
|
+
e,
|
317
|
+
)
|
318
|
+
# Fallback to robot-position-based zoom if room extraction fails
|
319
|
+
if (
|
320
|
+
self.shared.image_auto_zoom
|
321
|
+
and self.shared.vacuum_state == "cleaning"
|
322
|
+
and robot_position
|
323
|
+
):
|
324
|
+
self.zooming = True
|
325
|
+
_LOGGER.debug(
|
326
|
+
"%s: Enabling fallback robot-position-based zoom",
|
327
|
+
self.file_name,
|
328
|
+
)
|
329
|
+
|
245
330
|
return self.img_base_layer, robot_position, robot_position_angle
|
246
331
|
|
247
332
|
async def _draw_map_elements(
|
@@ -288,6 +373,33 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
288
373
|
img_np_array, robot_position, robot_position_angle, robot_color
|
289
374
|
)
|
290
375
|
|
376
|
+
# Store robot position for potential zoom function use
|
377
|
+
if robot_position:
|
378
|
+
self.robot_position = robot_position
|
379
|
+
|
380
|
+
# Check if Zoom should be enabled based on active zones
|
381
|
+
if (
|
382
|
+
self.shared.image_auto_zoom
|
383
|
+
and self.shared.vacuum_state == "cleaning"
|
384
|
+
and robot_position
|
385
|
+
):
|
386
|
+
# For Rand256, we need to check active zones differently since room data is not available yet
|
387
|
+
# Use a simplified approach: enable zoom if any active zones are set
|
388
|
+
active_zones = self.shared.rand256_active_zone
|
389
|
+
if active_zones and any(zone for zone in active_zones):
|
390
|
+
self.zooming = True
|
391
|
+
_LOGGER.debug(
|
392
|
+
"%s: Enabling zoom for Rand256 - active zones detected: %s",
|
393
|
+
self.file_name,
|
394
|
+
active_zones,
|
395
|
+
)
|
396
|
+
else:
|
397
|
+
self.zooming = False
|
398
|
+
_LOGGER.debug(
|
399
|
+
"%s: Zoom disabled for Rand256 - no active zones set",
|
400
|
+
self.file_name,
|
401
|
+
)
|
402
|
+
|
291
403
|
img_np_array = await self.async_auto_trim_and_zoom_image(
|
292
404
|
img_np_array,
|
293
405
|
detect_colour=colors["background"],
|
@@ -390,22 +502,22 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
390
502
|
self.active_zones = self.shared.rand256_active_zone
|
391
503
|
self.zooming = False
|
392
504
|
if self.active_zones and (
|
393
|
-
self.robot_in_room["id"]
|
394
|
-
in range(len(self.active_zones))
|
505
|
+
self.robot_in_room["id"] in range(len(self.active_zones))
|
395
506
|
):
|
396
|
-
self.zooming = bool(
|
397
|
-
self.active_zones[self.robot_in_room["id"]]
|
398
|
-
)
|
507
|
+
self.zooming = bool(self.active_zones[self.robot_in_room["id"]])
|
399
508
|
else:
|
400
509
|
self.zooming = False
|
401
510
|
return temp
|
402
511
|
# Fallback to bounding box check if no outline data
|
403
|
-
elif all(
|
404
|
-
k in self.robot_in_room for k in ["left", "right", "up", "down"]
|
405
|
-
):
|
512
|
+
elif all(k in self.robot_in_room for k in ["left", "right", "up", "down"]):
|
406
513
|
if (
|
407
|
-
|
408
|
-
|
514
|
+
self.robot_in_room["right"]
|
515
|
+
<= int(robot_x)
|
516
|
+
<= self.robot_in_room["left"]
|
517
|
+
) and (
|
518
|
+
self.robot_in_room["up"]
|
519
|
+
<= int(robot_y)
|
520
|
+
<= self.robot_in_room["down"]
|
409
521
|
):
|
410
522
|
temp = {
|
411
523
|
"x": robot_x,
|
@@ -417,12 +529,9 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
417
529
|
self.active_zones = self.shared.rand256_active_zone
|
418
530
|
self.zooming = False
|
419
531
|
if self.active_zones and (
|
420
|
-
self.robot_in_room["id"]
|
421
|
-
in range(len(self.active_zones))
|
532
|
+
self.robot_in_room["id"] in range(len(self.active_zones))
|
422
533
|
):
|
423
|
-
self.zooming = bool(
|
424
|
-
self.active_zones[self.robot_in_room["id"]]
|
425
|
-
)
|
534
|
+
self.zooming = bool(self.active_zones[self.robot_in_room["id"]])
|
426
535
|
else:
|
427
536
|
self.zooming = False
|
428
537
|
return temp
|
@@ -488,6 +597,16 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
488
597
|
"angle": angle,
|
489
598
|
"in_room": self.robot_in_room["room"],
|
490
599
|
}
|
600
|
+
|
601
|
+
# Handle active zones - Set zooming based on active zones
|
602
|
+
self.active_zones = self.shared.rand256_active_zone
|
603
|
+
if self.active_zones and (
|
604
|
+
self.robot_in_room["id"] in range(len(self.active_zones))
|
605
|
+
):
|
606
|
+
self.zooming = bool(self.active_zones[self.robot_in_room["id"]])
|
607
|
+
else:
|
608
|
+
self.zooming = False
|
609
|
+
|
491
610
|
_LOGGER.debug(
|
492
611
|
"%s is in %s room (polygon detection).",
|
493
612
|
self.file_name,
|
@@ -19,6 +19,7 @@ from .config.types import LOGGER, RoomsProperties
|
|
19
19
|
|
20
20
|
from .map_data import RandImageData, ImageData
|
21
21
|
|
22
|
+
|
22
23
|
class RoomsHandler:
|
23
24
|
"""
|
24
25
|
Handler for extracting and managing room data from Hipfer vacuum maps.
|
@@ -225,6 +226,7 @@ class RoomsHandler:
|
|
225
226
|
LOGGER.debug("Room extraction Total time: %.3fs", total_time)
|
226
227
|
return room_properties
|
227
228
|
|
229
|
+
|
228
230
|
class RandRoomsHandler:
|
229
231
|
"""
|
230
232
|
Handler for extracting and managing room data from Rand25 vacuum maps.
|
@@ -247,7 +249,9 @@ class RandRoomsHandler:
|
|
247
249
|
"""
|
248
250
|
self.vacuum_id = vacuum_id
|
249
251
|
self.drawing_config = drawing_config
|
250
|
-
self.current_json_data =
|
252
|
+
self.current_json_data = (
|
253
|
+
None # Will store the current JSON data being processed
|
254
|
+
)
|
251
255
|
self.segment_data = None # Segment data
|
252
256
|
self.outlines = None # Outlines data
|
253
257
|
|
@@ -467,4 +471,4 @@ class RandRoomsHandler:
|
|
467
471
|
total_time = time.time() - start_total
|
468
472
|
LOGGER.debug("Room extraction Total time: %.3fs", total_time)
|
469
473
|
|
470
|
-
return room_properties
|
474
|
+
return room_properties
|
@@ -0,0 +1,26 @@
|
|
1
|
+
valetudo_map_parser/__init__.py,sha256=XO_eJwFDyU7hXJ4tAa2zY-n-SM2_kmIGMWDKY3GcauY,1163
|
2
|
+
valetudo_map_parser/config/__init__.py,sha256=DQ9plV3ZF_K25Dp5ZQHPDoG-40dQoJNdNi-dfNeR3Zc,48
|
3
|
+
valetudo_map_parser/config/auto_crop.py,sha256=1TGjUSbVHV15_sx1iFsEBWwD5BnWHPjgGIuPAJB6aiY,19142
|
4
|
+
valetudo_map_parser/config/color_utils.py,sha256=nXD6WeNmdFdoMxPDW-JFpjnxJSaZR1jX-ouNfrx6zvE,4502
|
5
|
+
valetudo_map_parser/config/colors.py,sha256=DG-oPQoN5gsnwDbEsuFr8a0hRCxmbFHObWa4_5pr-70,29910
|
6
|
+
valetudo_map_parser/config/drawable.py,sha256=2MeVHXqZuVuJk3eerMJYGwo25rVetHx3xB_vxecEFOQ,34168
|
7
|
+
valetudo_map_parser/config/drawable_elements.py,sha256=o-5oiXmfqPwNQLzKIhkEcZD_A47rIU9E0CqKgWipxgc,11516
|
8
|
+
valetudo_map_parser/config/enhanced_drawable.py,sha256=QlGxlUMVgECUXPtFwIslyjubWxQuhIixsRymWV3lEvk,12586
|
9
|
+
valetudo_map_parser/config/optimized_element_map.py,sha256=52BCnkvVv9bre52LeVIfT8nhnEIpc0TuWTv1xcNu0Rk,15744
|
10
|
+
valetudo_map_parser/config/rand25_parser.py,sha256=kIayyqVZBfQfAMkiArzqrrj9vqZB3pkgT0Y5ufrQmGA,16448
|
11
|
+
valetudo_map_parser/config/shared.py,sha256=ogXR5qC2HuLJ3KgYc9KDozXzDQptd8nhvNc-CepN6S0,12301
|
12
|
+
valetudo_map_parser/config/types.py,sha256=HO5fowAjbGmS2rEOFbFe7eFljvpfBr0fsvhcVRTByhI,17540
|
13
|
+
valetudo_map_parser/config/utils.py,sha256=w8r53KcCgYNq7CoIziQ3ktJu8ESFit5TYza-7g8ndhE,31203
|
14
|
+
valetudo_map_parser/hypfer_draw.py,sha256=Bi03FiYdxw2Kp8BwkggAkdKABNoNf-j7v7J-rER8tnQ,28953
|
15
|
+
valetudo_map_parser/hypfer_handler.py,sha256=-tMYd1lMH6_l8ufQH1A95uAgbt2P-1YYTfNkl9NXAc8,22269
|
16
|
+
valetudo_map_parser/hypfer_rooms_handler.py,sha256=NkpOA6Gdq-2D3lLAxvtNuuWMvPXHxeMY2TO5RZLSHlU,22652
|
17
|
+
valetudo_map_parser/map_data.py,sha256=5DDT5ABJCMSaWd8YrMY9SG4uhD3Rga_F0DEBNNNPipc,18618
|
18
|
+
valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
valetudo_map_parser/rand256_handler.py,sha256=kLurqSQvmrweCrOpLT9oIuVKkQ_SmCXcRuSL4dDddO8,27893
|
20
|
+
valetudo_map_parser/reimg_draw.py,sha256=1q8LkNTPHEA9Tsapc_JnVw51kpPYNhaBU-KmHkefCQY,12507
|
21
|
+
valetudo_map_parser/rooms_handler.py,sha256=ovqQtAjauAqwUNPR0aX27P2zhheQmqfaFhDE3_AwYWk,17821
|
22
|
+
valetudo_map_parser-0.1.9b57.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
|
23
|
+
valetudo_map_parser-0.1.9b57.dist-info/METADATA,sha256=f2DJy0uFpMdGp1e0gsdG2OdpGzkB1A429ZKf2c49MOE,3321
|
24
|
+
valetudo_map_parser-0.1.9b57.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
|
25
|
+
valetudo_map_parser-0.1.9b57.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
26
|
+
valetudo_map_parser-0.1.9b57.dist-info/RECORD,,
|