valetudo-map-parser 0.1.9b67__tar.gz → 0.1.9b68__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.9b67 → valetudo_map_parser-0.1.9b68}/PKG-INFO +1 -1
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/drawable.py +6 -87
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/shared.py +11 -8
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/utils.py +62 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/hypfer_handler.py +9 -25
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/rand256_handler.py +4 -39
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/pyproject.toml +1 -1
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/LICENSE +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/README.md +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/__init__.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/__init__.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/async_utils.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/auto_crop.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/color_utils.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/colors.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/drawable_elements.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/enhanced_drawable.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/optimized_element_map.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/rand256_parser.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/config/types.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/hypfer_draw.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/hypfer_rooms_handler.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/map_data.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/py.typed +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/reimg_draw.py +0 -0
- {valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/rooms_handler.py +0 -0
@@ -14,7 +14,6 @@ import logging
|
|
14
14
|
import math
|
15
15
|
import asyncio
|
16
16
|
import inspect
|
17
|
-
import threading
|
18
17
|
|
19
18
|
import numpy as np
|
20
19
|
from PIL import ImageDraw, ImageFont
|
@@ -27,72 +26,6 @@ from .types import Color, NumpyArray, PilPNG, Point, Tuple, Union
|
|
27
26
|
_LOGGER = logging.getLogger(__name__)
|
28
27
|
|
29
28
|
|
30
|
-
class ImageArrayPool:
|
31
|
-
"""Thread-safe memory pool for reusing image arrays to reduce allocation overhead."""
|
32
|
-
|
33
|
-
def __init__(self, max_arrays_per_size: int = 3):
|
34
|
-
self._pools = {} # {(width, height): [array1, array2, ...]}
|
35
|
-
self._lock = threading.Lock()
|
36
|
-
self._max_arrays_per_size = max_arrays_per_size
|
37
|
-
|
38
|
-
def get_array(self, width: int, height: int, background_color: Color) -> NumpyArray:
|
39
|
-
"""Get a reusable array or create a new one if none available."""
|
40
|
-
key = (width, height)
|
41
|
-
|
42
|
-
with self._lock:
|
43
|
-
if key in self._pools and self._pools[key]:
|
44
|
-
# Reuse existing array
|
45
|
-
array = self._pools[key].pop()
|
46
|
-
_LOGGER.debug("Reused array from pool for size %dx%d", width, height)
|
47
|
-
else:
|
48
|
-
# Create new array
|
49
|
-
array = np.empty((height, width, 4), dtype=np.uint8)
|
50
|
-
_LOGGER.debug("Created new array for size %dx%d", width, height)
|
51
|
-
|
52
|
-
# Fill with background color (outside lock for better performance)
|
53
|
-
array[:] = background_color
|
54
|
-
return array
|
55
|
-
|
56
|
-
def return_array(self, array: NumpyArray) -> None:
|
57
|
-
"""Return an array to the pool for reuse."""
|
58
|
-
if array is None:
|
59
|
-
return
|
60
|
-
|
61
|
-
height, width = array.shape[:2]
|
62
|
-
key = (width, height)
|
63
|
-
|
64
|
-
with self._lock:
|
65
|
-
if key not in self._pools:
|
66
|
-
self._pools[key] = []
|
67
|
-
|
68
|
-
# Only keep up to max_arrays_per_size arrays per size
|
69
|
-
if len(self._pools[key]) < self._max_arrays_per_size:
|
70
|
-
self._pools[key].append(array)
|
71
|
-
_LOGGER.debug("Returned array to pool for size %dx%d (pool size: %d)",
|
72
|
-
width, height, len(self._pools[key]))
|
73
|
-
else:
|
74
|
-
_LOGGER.debug("Pool full for size %dx%d, discarding array", width, height)
|
75
|
-
|
76
|
-
def clear_pool(self) -> None:
|
77
|
-
"""Clear all arrays from the pool."""
|
78
|
-
with self._lock:
|
79
|
-
total_arrays = sum(len(arrays) for arrays in self._pools.values())
|
80
|
-
self._pools.clear()
|
81
|
-
_LOGGER.debug("Cleared image array pool (%d arrays freed)", total_arrays)
|
82
|
-
|
83
|
-
def get_pool_stats(self) -> dict:
|
84
|
-
"""Get statistics about the current pool state."""
|
85
|
-
with self._lock:
|
86
|
-
stats = {}
|
87
|
-
for (width, height), arrays in self._pools.items():
|
88
|
-
stats[f"{width}x{height}"] = len(arrays)
|
89
|
-
return stats
|
90
|
-
|
91
|
-
|
92
|
-
# Global shared pool instance for both Hypfer and Rand256 handlers
|
93
|
-
_image_pool = ImageArrayPool()
|
94
|
-
|
95
|
-
|
96
29
|
class Drawable:
|
97
30
|
"""
|
98
31
|
Collection of drawing utility functions for the image handlers.
|
@@ -112,27 +45,13 @@ class Drawable:
|
|
112
45
|
async def create_empty_image(
|
113
46
|
width: int, height: int, background_color: Color
|
114
47
|
) -> NumpyArray:
|
115
|
-
"""Create the empty background image NumPy array
|
48
|
+
"""Create the empty background image NumPy array.
|
116
49
|
Background color is specified as an RGBA tuple.
|
117
|
-
Optimized: Uses
|
118
|
-
#
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
def return_image_to_pool(image_array: NumpyArray) -> None:
|
123
|
-
"""Return an image array to the memory pool for reuse.
|
124
|
-
Call this when you're done with an image array to enable memory reuse."""
|
125
|
-
_image_pool.return_array(image_array)
|
126
|
-
|
127
|
-
@staticmethod
|
128
|
-
def get_pool_stats() -> dict:
|
129
|
-
"""Get statistics about the current memory pool state."""
|
130
|
-
return _image_pool.get_pool_stats()
|
131
|
-
|
132
|
-
@staticmethod
|
133
|
-
def clear_image_pool() -> None:
|
134
|
-
"""Clear all arrays from the memory pool."""
|
135
|
-
_image_pool.clear_pool()
|
50
|
+
Optimized: Uses np.empty + broadcast instead of np.full for better performance."""
|
51
|
+
# Use np.empty + broadcast instead of np.full (avoids double initialization)
|
52
|
+
img_array = np.empty((height, width, 4), dtype=np.uint8)
|
53
|
+
img_array[:] = background_color # Broadcast color to all pixels efficiently
|
54
|
+
return img_array
|
136
55
|
|
137
56
|
@staticmethod
|
138
57
|
async def from_json_to_image(
|
@@ -39,6 +39,7 @@ from .types import (
|
|
39
39
|
CameraModes,
|
40
40
|
Colors,
|
41
41
|
TrimsData,
|
42
|
+
PilPNG,
|
42
43
|
)
|
43
44
|
|
44
45
|
|
@@ -58,9 +59,10 @@ class CameraShared:
|
|
58
59
|
self.rand256_active_zone: list = [] # Active zone for rand256
|
59
60
|
self.is_rand: bool = False # MQTT rand data
|
60
61
|
self._new_mqtt_message = False # New MQTT message
|
61
|
-
self.last_image = None # Last image received
|
62
|
-
self.
|
63
|
-
self.binary_image = None # Current image in binary format
|
62
|
+
self.last_image = PilPNG | None # Last image received
|
63
|
+
self.new_image: PilPNG | None = None # New image received
|
64
|
+
self.binary_image: bytes | None = None # Current image in binary format
|
65
|
+
self.image_last_updated: float = 0.0 # Last image update time
|
64
66
|
self.image_format = "image/pil" # Image format
|
65
67
|
self.image_size = None # Image size
|
66
68
|
self.image_auto_zoom: bool = False # Auto zoom image
|
@@ -115,7 +117,7 @@ class CameraShared:
|
|
115
117
|
|
116
118
|
|
117
119
|
|
118
|
-
def
|
120
|
+
def vacuum_bat_charged(self) -> bool:
|
119
121
|
"""Check if the vacuum is charging."""
|
120
122
|
return (self.vacuum_state == "docked") and (int(self.vacuum_battery) < 100)
|
121
123
|
|
@@ -193,7 +195,7 @@ class CameraShared:
|
|
193
195
|
attrs = {
|
194
196
|
ATTR_CAMERA_MODE: self.camera_mode,
|
195
197
|
ATTR_VACUUM_BATTERY: f"{self.vacuum_battery}%",
|
196
|
-
ATTR_VACUUM_CHARGING: self.
|
198
|
+
ATTR_VACUUM_CHARGING: self.vacuum_bat_charged,
|
197
199
|
ATTR_VACUUM_POSITION: self.current_room,
|
198
200
|
ATTR_VACUUM_STATUS: self.vacuum_state,
|
199
201
|
ATTR_VACUUM_JSON_ID: self.vac_json_id,
|
@@ -228,12 +230,13 @@ class CameraShared:
|
|
228
230
|
class CameraSharedManager:
|
229
231
|
"""Camera Shared Manager class."""
|
230
232
|
|
231
|
-
def __init__(self, file_name, device_info):
|
233
|
+
def __init__(self, file_name: str, device_info: dict = None):
|
232
234
|
self._instances = {}
|
233
235
|
self._lock = asyncio.Lock()
|
234
236
|
self.file_name = file_name
|
235
|
-
|
236
|
-
|
237
|
+
if device_info:
|
238
|
+
self.device_info = device_info
|
239
|
+
self.update_shared_data(device_info)
|
237
240
|
|
238
241
|
# Automatically initialize shared data for the instance
|
239
242
|
# self._init_shared_data(device_info)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
"""Utility code for the valetudo map parser."""
|
2
2
|
|
3
|
+
import datetime
|
3
4
|
import hashlib
|
4
5
|
import json
|
5
6
|
from dataclasses import dataclass
|
@@ -79,6 +80,67 @@ class BaseHandler:
|
|
79
80
|
"""Return the robot position."""
|
80
81
|
return self.robot_pos
|
81
82
|
|
83
|
+
async def async_get_pil_image(
|
84
|
+
self,
|
85
|
+
m_json: dict | None,
|
86
|
+
destinations: list | None = None,
|
87
|
+
) -> PilPNG | None:
|
88
|
+
"""
|
89
|
+
Unified async function to get PIL image from JSON data for both Hypfer and Rand256 handlers.
|
90
|
+
|
91
|
+
This function:
|
92
|
+
1. Calls the appropriate async_get_image_from_json method
|
93
|
+
2. Stores the processed data in shared.new_image
|
94
|
+
3. Backs up previous data to shared.last_image
|
95
|
+
4. Updates shared.image_last_updated with current datetime
|
96
|
+
|
97
|
+
@param m_json: The JSON data to use to draw the image
|
98
|
+
@param destinations: MQTT destinations for labels (used by Rand256)
|
99
|
+
@return: PIL Image or None
|
100
|
+
"""
|
101
|
+
try:
|
102
|
+
# Backup current image to last_image before processing new one
|
103
|
+
if hasattr(self.shared, 'new_image') and self.shared.new_image is not None:
|
104
|
+
self.shared.last_image = self.shared.new_image
|
105
|
+
|
106
|
+
# Call the appropriate handler method based on handler type
|
107
|
+
if hasattr(self, 'get_image_from_rrm'):
|
108
|
+
# This is a Rand256 handler
|
109
|
+
new_image = await self.get_image_from_rrm(
|
110
|
+
m_json=m_json,
|
111
|
+
destinations=destinations,
|
112
|
+
return_webp=False # Always return PIL Image
|
113
|
+
)
|
114
|
+
elif hasattr(self, 'async_get_image_from_json'):
|
115
|
+
# This is a Hypfer handler
|
116
|
+
new_image = await self.async_get_image_from_json(
|
117
|
+
m_json=m_json,
|
118
|
+
return_webp=False # Always return PIL Image
|
119
|
+
)
|
120
|
+
else:
|
121
|
+
LOGGER.warning("%s: Handler type not recognized for async_get_pil_image", self.file_name)
|
122
|
+
return None
|
123
|
+
|
124
|
+
# Store the new image in shared data
|
125
|
+
if new_image is not None:
|
126
|
+
self.shared.new_image = new_image
|
127
|
+
# Update the timestamp with current datetime
|
128
|
+
self.shared.image_last_updated = datetime.datetime.now().timestamp()
|
129
|
+
LOGGER.debug("%s: Image processed and stored in shared data", self.file_name)
|
130
|
+
else:
|
131
|
+
LOGGER.warning("%s: Failed to generate image from JSON data", self.file_name)
|
132
|
+
|
133
|
+
return new_image
|
134
|
+
|
135
|
+
except Exception as e:
|
136
|
+
LOGGER.error(
|
137
|
+
"%s: Error in async_get_pil_image: %s",
|
138
|
+
self.file_name,
|
139
|
+
str(e),
|
140
|
+
exc_info=True
|
141
|
+
)
|
142
|
+
return None
|
143
|
+
|
82
144
|
def get_charger_position(self) -> ChargerPosition | None:
|
83
145
|
"""Return the charger position."""
|
84
146
|
return self.charger_pos
|
@@ -8,11 +8,10 @@ Version: 0.1.9
|
|
8
8
|
from __future__ import annotations
|
9
9
|
|
10
10
|
import asyncio
|
11
|
-
import json
|
12
11
|
|
13
12
|
from PIL import Image
|
14
13
|
|
15
|
-
from .config.async_utils import AsyncNumPy, AsyncPIL
|
14
|
+
from .config.async_utils import AsyncNumPy, AsyncPIL
|
16
15
|
from .config.auto_crop import AutoCrop
|
17
16
|
from .config.drawable_elements import DrawableElement
|
18
17
|
from .config.shared import CameraShared
|
@@ -25,6 +24,7 @@ from .config.types import (
|
|
25
24
|
RoomsProperties,
|
26
25
|
RoomStore,
|
27
26
|
WebPBytes,
|
27
|
+
JsonType,
|
28
28
|
)
|
29
29
|
from .config.utils import (
|
30
30
|
BaseHandler,
|
@@ -100,7 +100,7 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
100
100
|
# noinspection PyUnresolvedReferences,PyUnboundLocalVariable
|
101
101
|
async def async_get_image_from_json(
|
102
102
|
self,
|
103
|
-
m_json:
|
103
|
+
m_json: JsonType | None,
|
104
104
|
return_webp: bool = False,
|
105
105
|
) -> WebPBytes | Image.Image | None:
|
106
106
|
"""Get the image from the JSON data.
|
@@ -232,13 +232,6 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
232
232
|
disabled_rooms if layer_type == "wall" else None,
|
233
233
|
)
|
234
234
|
|
235
|
-
# Update element map for this layer
|
236
|
-
if is_room_layer and 0 < room_id <= 15:
|
237
|
-
# Mark the room in the element map
|
238
|
-
room_element = getattr(
|
239
|
-
DrawableElement, f"ROOM_{room_id}", None
|
240
|
-
)
|
241
|
-
|
242
235
|
# Draw the virtual walls if enabled
|
243
236
|
if self.drawing_config.is_enabled(DrawableElement.VIRTUAL_WALL):
|
244
237
|
img_np_array = await self.imd.async_draw_virtual_walls(
|
@@ -313,10 +306,6 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
313
306
|
LOGGER.info("%s: Drawing path", self.file_name)
|
314
307
|
data_tasks.append(self._prepare_path_data(m_json))
|
315
308
|
|
316
|
-
# Execute data preparation in parallel if we have tasks
|
317
|
-
if data_tasks:
|
318
|
-
prepared_data = await AsyncParallel.parallel_data_preparation(*data_tasks)
|
319
|
-
|
320
309
|
# Process drawing operations sequentially (since they modify the same array)
|
321
310
|
# Draw zones if enabled
|
322
311
|
if self.drawing_config.is_enabled(DrawableElement.RESTRICTED_AREA):
|
@@ -390,9 +379,7 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
390
379
|
if self.check_zoom_and_aspect_ratio():
|
391
380
|
# Convert to PIL for resizing
|
392
381
|
pil_img = await AsyncPIL.async_fromarray(img_np_array, mode="RGBA")
|
393
|
-
|
394
|
-
from .config.drawable import Drawable
|
395
|
-
Drawable.return_image_to_pool(img_np_array)
|
382
|
+
del img_np_array
|
396
383
|
resize_params = prepare_resize_params(self, pil_img, False)
|
397
384
|
resized_image = await self.async_resize_images(resize_params)
|
398
385
|
|
@@ -407,17 +394,13 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
407
394
|
if return_webp:
|
408
395
|
# Convert directly from NumPy to WebP for better performance
|
409
396
|
webp_bytes = await numpy_to_webp_bytes(img_np_array)
|
410
|
-
|
411
|
-
from .config.drawable import Drawable
|
412
|
-
Drawable.return_image_to_pool(img_np_array)
|
397
|
+
del img_np_array
|
413
398
|
LOGGER.debug("%s: Frame Completed.", self.file_name)
|
414
399
|
return webp_bytes
|
415
400
|
else:
|
416
401
|
# Convert to PIL Image (original behavior)
|
417
402
|
pil_img = await AsyncPIL.async_fromarray(img_np_array, mode="RGBA")
|
418
|
-
|
419
|
-
from .config.drawable import Drawable
|
420
|
-
Drawable.return_image_to_pool(img_np_array)
|
403
|
+
del img_np_array
|
421
404
|
LOGGER.debug("%s: Frame Completed.", self.file_name)
|
422
405
|
return pil_img
|
423
406
|
except (RuntimeError, RuntimeWarning) as e:
|
@@ -506,7 +489,8 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
506
489
|
except (ValueError, KeyError):
|
507
490
|
return None
|
508
491
|
|
509
|
-
|
492
|
+
@staticmethod
|
493
|
+
async def _prepare_goto_data(entity_dict):
|
510
494
|
"""Prepare go-to flag data for parallel processing."""
|
511
495
|
await asyncio.sleep(0) # Yield control
|
512
496
|
# Extract go-to target data from entity_dict
|
@@ -516,6 +500,6 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
516
500
|
"""Prepare path data for parallel processing."""
|
517
501
|
await asyncio.sleep(0) # Yield control
|
518
502
|
try:
|
519
|
-
return self.data.
|
503
|
+
return self.data.find_paths_entities(m_json)
|
520
504
|
except (ValueError, KeyError):
|
521
505
|
return None
|
@@ -7,15 +7,13 @@ Version: 0.1.9.a6
|
|
7
7
|
|
8
8
|
from __future__ import annotations
|
9
9
|
|
10
|
-
import asyncio
|
11
10
|
import logging
|
12
11
|
import uuid
|
13
12
|
from typing import Any
|
14
13
|
|
15
14
|
import numpy as np
|
16
|
-
from PIL import Image
|
17
15
|
|
18
|
-
from .config.async_utils import AsyncNumPy, AsyncPIL
|
16
|
+
from .config.async_utils import AsyncNumPy, AsyncPIL
|
19
17
|
from .config.auto_crop import AutoCrop
|
20
18
|
from .config.drawable_elements import DrawableElement
|
21
19
|
from .config.types import (
|
@@ -147,7 +145,7 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
147
145
|
m_json: JsonType, # json data
|
148
146
|
destinations: None = None, # MQTT destinations for labels
|
149
147
|
return_webp: bool = False,
|
150
|
-
) -> WebPBytes |
|
148
|
+
) -> WebPBytes | PilPNG | None:
|
151
149
|
"""Generate Images from the json data.
|
152
150
|
@param m_json: The JSON data to use to draw the image.
|
153
151
|
@param destinations: MQTT destinations for labels (unused).
|
@@ -168,14 +166,6 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
168
166
|
self.json_id = str(uuid.uuid4()) # image id
|
169
167
|
_LOGGER.info("Vacuum Data ID: %s", self.json_id)
|
170
168
|
|
171
|
-
# Prepare parallel data extraction tasks
|
172
|
-
data_tasks = []
|
173
|
-
data_tasks.append(self._prepare_zone_data(m_json))
|
174
|
-
data_tasks.append(self._prepare_path_data(m_json))
|
175
|
-
|
176
|
-
# Execute data preparation tasks in parallel
|
177
|
-
zone_data, path_data = await asyncio.gather(*data_tasks, return_exceptions=True)
|
178
|
-
|
179
169
|
(
|
180
170
|
img_np_array,
|
181
171
|
robot_position,
|
@@ -202,16 +192,12 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
202
192
|
if return_webp:
|
203
193
|
# Convert directly to WebP bytes for better performance
|
204
194
|
webp_bytes = await numpy_to_webp_bytes(img_np_array)
|
205
|
-
#
|
206
|
-
from .config.drawable import Drawable
|
207
|
-
Drawable.return_image_to_pool(img_np_array)
|
195
|
+
del img_np_array # free memory
|
208
196
|
return webp_bytes
|
209
197
|
else:
|
210
198
|
# Convert to PIL Image using async utilities
|
211
199
|
pil_img = await AsyncPIL.async_fromarray(img_np_array, mode="RGBA")
|
212
|
-
#
|
213
|
-
from .config.drawable import Drawable
|
214
|
-
Drawable.return_image_to_pool(img_np_array)
|
200
|
+
del img_np_array # free memory
|
215
201
|
return await self._finalize_image(pil_img)
|
216
202
|
|
217
203
|
except (RuntimeError, RuntimeWarning) as e:
|
@@ -311,11 +297,6 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
311
297
|
original_rooms_pos = self.rooms_pos
|
312
298
|
self.rooms_pos = temp_rooms_pos
|
313
299
|
|
314
|
-
# Perform robot room detection to check active zones
|
315
|
-
robot_room_result = await self.async_get_robot_in_room(
|
316
|
-
robot_position[0], robot_position[1], robot_position_angle
|
317
|
-
)
|
318
|
-
|
319
300
|
# Restore original rooms_pos
|
320
301
|
self.rooms_pos = original_rooms_pos
|
321
302
|
|
@@ -692,20 +673,4 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
692
673
|
"""Copy the array using async utilities."""
|
693
674
|
return await AsyncNumPy.async_copy(original_array)
|
694
675
|
|
695
|
-
async def _prepare_zone_data(self, m_json):
|
696
|
-
"""Prepare zone data for parallel processing."""
|
697
|
-
await asyncio.sleep(0) # Yield control
|
698
|
-
try:
|
699
|
-
return self.data.find_zone_entities(m_json)
|
700
|
-
except (ValueError, KeyError):
|
701
|
-
return None
|
702
|
-
|
703
|
-
async def _prepare_path_data(self, m_json):
|
704
|
-
"""Prepare path data for parallel processing."""
|
705
|
-
await asyncio.sleep(0) # Yield control
|
706
|
-
try:
|
707
|
-
return self.data.find_path_entities(m_json)
|
708
|
-
except (ValueError, KeyError):
|
709
|
-
return None
|
710
|
-
|
711
676
|
|
File without changes
|
File without changes
|
File without changes
|
{valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/hypfer_draw.py
RENAMED
File without changes
|
File without changes
|
{valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/map_data.py
RENAMED
File without changes
|
{valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/py.typed
RENAMED
File without changes
|
{valetudo_map_parser-0.1.9b67 → valetudo_map_parser-0.1.9b68}/SCR/valetudo_map_parser/reimg_draw.py
RENAMED
File without changes
|
File without changes
|