valetudo-map-parser 0.1.9b32__py3-none-any.whl → 0.1.9b34__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/config/auto_crop.py +9 -3
- valetudo_map_parser/config/shared.py +11 -3
- valetudo_map_parser/config/types.py +40 -32
- valetudo_map_parser/config/utils.py +6 -2
- valetudo_map_parser/hypfer_handler.py +3 -2
- valetudo_map_parser/rand25_handler.py +3 -0
- {valetudo_map_parser-0.1.9b32.dist-info → valetudo_map_parser-0.1.9b34.dist-info}/METADATA +1 -1
- {valetudo_map_parser-0.1.9b32.dist-info → valetudo_map_parser-0.1.9b34.dist-info}/RECORD +11 -11
- {valetudo_map_parser-0.1.9b32.dist-info → valetudo_map_parser-0.1.9b34.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.9b32.dist-info → valetudo_map_parser-0.1.9b34.dist-info}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.9b32.dist-info → valetudo_map_parser-0.1.9b34.dist-info}/WHEEL +0 -0
@@ -90,6 +90,7 @@ class AutoCrop:
|
|
90
90
|
|
91
91
|
async def _async_auto_crop_data(self, tdata: TrimsData): # , tdata=None
|
92
92
|
"""Load the auto crop data from the Camera config."""
|
93
|
+
_LOGGER.debug("Auto Crop data: %s, %s", str(tdata), str(self.auto_crop))
|
93
94
|
if not self.auto_crop:
|
94
95
|
trims_data = TrimCropData.from_dict(dict(tdata.to_dict())).to_list()
|
95
96
|
(
|
@@ -98,9 +99,12 @@ class AutoCrop:
|
|
98
99
|
self.trim_right,
|
99
100
|
self.trim_down,
|
100
101
|
) = trims_data
|
101
|
-
|
102
|
+
_LOGGER.debug("Auto Crop trims data: %s", trims_data)
|
103
|
+
if trims_data != [0, 0, 0, 0]:
|
104
|
+
self._calculate_trimmed_dimensions()
|
105
|
+
else:
|
106
|
+
trims_data = None
|
102
107
|
return trims_data
|
103
|
-
_LOGGER.debug("No Crop data found in the Camera config.")
|
104
108
|
return None
|
105
109
|
|
106
110
|
def auto_crop_offset(self):
|
@@ -113,7 +117,9 @@ class AutoCrop:
|
|
113
117
|
|
114
118
|
async def _init_auto_crop(self):
|
115
119
|
"""Initialize the auto crop data."""
|
116
|
-
|
120
|
+
_LOGGER.debug("Auto Crop Init data: %s", str(self.auto_crop))
|
121
|
+
_LOGGER.debug("Auto Crop Init trims data: %s", self.handler.shared.trims.to_dict())
|
122
|
+
if not self.auto_crop: # and self.handler.shared.vacuum_state == "docked":
|
117
123
|
self.auto_crop = await self._async_auto_crop_data(self.handler.shared.trims)
|
118
124
|
if self.auto_crop:
|
119
125
|
self.auto_crop_offset()
|
@@ -123,6 +123,10 @@ class CameraShared:
|
|
123
123
|
"""Get the rooms colors."""
|
124
124
|
return self.rooms_colors
|
125
125
|
|
126
|
+
def reset_trims(self) -> dict:
|
127
|
+
"""Reset the trims."""
|
128
|
+
return self.trims.clear()
|
129
|
+
|
126
130
|
async def batch_update(self, **kwargs):
|
127
131
|
"""Batch update multiple attributes."""
|
128
132
|
for key, value in kwargs.items():
|
@@ -172,6 +176,7 @@ class CameraSharedManager:
|
|
172
176
|
self._lock = asyncio.Lock()
|
173
177
|
self.file_name = file_name
|
174
178
|
self.device_info = device_info
|
179
|
+
self.update_shared_data(device_info)
|
175
180
|
|
176
181
|
# Automatically initialize shared data for the instance
|
177
182
|
# self._init_shared_data(device_info)
|
@@ -227,9 +232,12 @@ class CameraSharedManager:
|
|
227
232
|
instance.enable_snapshots = device_info.get(
|
228
233
|
CONF_SNAPSHOTS_ENABLE, DEFAULT_VALUES["enable_www_snapshots"]
|
229
234
|
)
|
230
|
-
|
231
|
-
|
232
|
-
)
|
235
|
+
# Ensure trims are updated correctly
|
236
|
+
trim_data = device_info.get("trims_data", DEFAULT_VALUES["trims_data"])
|
237
|
+
_LOGGER.debug("Updating shared trims with: %s", trim_data)
|
238
|
+
instance.trims = TrimsData.from_dict(trim_data)
|
239
|
+
|
240
|
+
_LOGGER.debug("Shared trims successfully updated: %s", instance.trims.to_dict())
|
233
241
|
|
234
242
|
except TypeError as ex:
|
235
243
|
_LOGGER.error("Shared data can't be initialized due to a TypeError! %s", ex)
|
@@ -7,7 +7,7 @@ import asyncio
|
|
7
7
|
import json
|
8
8
|
import logging
|
9
9
|
from dataclasses import asdict, dataclass
|
10
|
-
from typing import Any, Dict, Tuple, Union
|
10
|
+
from typing import Any, Dict, Tuple, Union, Optional
|
11
11
|
|
12
12
|
import numpy as np
|
13
13
|
from PIL import Image
|
@@ -74,43 +74,43 @@ class TrimCropData:
|
|
74
74
|
)
|
75
75
|
|
76
76
|
|
77
|
-
# pylint: disable=no-member
|
78
77
|
class RoomStore:
|
79
|
-
"""
|
78
|
+
"""Singleton RoomStore to store room data per vacuum."""
|
80
79
|
|
81
|
-
|
82
|
-
_lock = asyncio.Lock()
|
80
|
+
_instances: Dict[str, "RoomStore"] = {} # Stores instances by vacuum ID
|
81
|
+
_lock = asyncio.Lock() # Ensures thread-safe access
|
83
82
|
|
84
|
-
def
|
85
|
-
|
83
|
+
def __new__(cls, vacuum_id: str, rooms_data: Optional[dict] = None) -> "RoomStore":
|
84
|
+
"""Create a new instance or return an existing one."""
|
85
|
+
if vacuum_id not in cls._instances:
|
86
|
+
instance = super().__new__(cls)
|
87
|
+
instance.vacuum_id = vacuum_id
|
88
|
+
instance.vacuums_data = rooms_data or {} # Store room data
|
89
|
+
cls._instances[vacuum_id] = instance # Store the instance
|
90
|
+
return cls._instances[vacuum_id]
|
86
91
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
return cls._instance
|
92
|
+
def __init__(self, vacuum_id: str, rooms_data: Optional[dict] = None):
|
93
|
+
"""Initialize the instance."""
|
94
|
+
self.vacuum_id = vacuum_id
|
95
|
+
self.vacuums_data = rooms_data or {}
|
92
96
|
|
93
|
-
|
94
|
-
"""
|
95
|
-
|
96
|
-
|
97
|
+
def get_rooms(self) -> dict:
|
98
|
+
"""Return the stored rooms data."""
|
99
|
+
return self.vacuums_data
|
100
|
+
|
101
|
+
def set_rooms(self, rooms_data: dict) -> None:
|
102
|
+
"""Update the rooms data."""
|
103
|
+
self.vacuums_data = rooms_data
|
104
|
+
|
105
|
+
def get_rooms_count(self) -> int:
|
106
|
+
"""Return the number of rooms stored for this vacuum."""
|
107
|
+
return len(self.vacuums_data)
|
108
|
+
|
109
|
+
@classmethod
|
110
|
+
def get_all_instances(cls) -> Dict[str, "RoomStore"]:
|
111
|
+
"""Return all active instances (for debugging)."""
|
112
|
+
return cls._instances
|
97
113
|
|
98
|
-
async def async_get_rooms_data(self, vacuum_id: str) -> dict:
|
99
|
-
"""Get the room data for a vacuum."""
|
100
|
-
async with self._lock:
|
101
|
-
data = self.vacuums_data.get(vacuum_id, {})
|
102
|
-
if isinstance(data, str):
|
103
|
-
json_data = json.loads(data)
|
104
|
-
return json_data
|
105
|
-
return data
|
106
|
-
|
107
|
-
async def async_get_rooms_count(self, vacuum_id: str) -> int:
|
108
|
-
"""Count the number of rooms for a vacuum."""
|
109
|
-
async with self._lock:
|
110
|
-
count = len(self.vacuums_data.get(vacuum_id, {}))
|
111
|
-
if count == 0:
|
112
|
-
return DEFAULT_ROOMS
|
113
|
-
return count
|
114
114
|
|
115
115
|
|
116
116
|
# pylint: disable=no-member
|
@@ -624,3 +624,11 @@ class TrimsData:
|
|
624
624
|
def to_dict(self) -> dict:
|
625
625
|
"""Convert TrimData to a dictionary."""
|
626
626
|
return asdict(self)
|
627
|
+
|
628
|
+
def clear(self)-> dict:
|
629
|
+
"""Clear all the trims."""
|
630
|
+
self.trim_left = 0
|
631
|
+
self.trim_up = 0
|
632
|
+
self.trim_right = 0
|
633
|
+
self.trim_down = 0
|
634
|
+
return asdict(self)
|
@@ -58,7 +58,7 @@ class BaseHandler:
|
|
58
58
|
self.crop_img_size = [0, 0]
|
59
59
|
self.offset_x = 0
|
60
60
|
self.offset_y = 0
|
61
|
-
self.crop_area =
|
61
|
+
self.crop_area = None
|
62
62
|
self.zooming = False
|
63
63
|
self.async_resize_images = async_resize_image
|
64
64
|
|
@@ -495,7 +495,10 @@ async def async_resize_image(params: ResizeParams):
|
|
495
495
|
hsf,
|
496
496
|
)
|
497
497
|
return params.pil_img # Return original image if invalid
|
498
|
-
|
498
|
+
if params.width == 0:
|
499
|
+
params.width = params.pil_img.width
|
500
|
+
if params.height == 0:
|
501
|
+
params.height = params.pil_img.height
|
499
502
|
new_aspect_ratio = wsf / hsf
|
500
503
|
if params.width / params.height > new_aspect_ratio:
|
501
504
|
new_width = int(params.pil_img.height * new_aspect_ratio)
|
@@ -505,6 +508,7 @@ async def async_resize_image(params: ResizeParams):
|
|
505
508
|
new_height = int(params.pil_img.width / new_aspect_ratio)
|
506
509
|
|
507
510
|
_LOGGER.debug("Resizing image to aspect ratio: %s, %s", wsf, hsf)
|
511
|
+
_LOGGER.debug("New image size: %s x %s", new_width, new_height)
|
508
512
|
|
509
513
|
if (params.crop_size is not None) and (params.offset_func is not None):
|
510
514
|
offset = OffsetParams(wsf, hsf, new_width, new_height, params.is_rand)
|
@@ -15,7 +15,7 @@ from PIL import Image
|
|
15
15
|
from .config.auto_crop import AutoCrop
|
16
16
|
from .config.drawable import Drawable
|
17
17
|
from .config.shared import CameraShared
|
18
|
-
from .config.types import COLORS, CalibrationPoints, Colors, RoomsProperties
|
18
|
+
from .config.types import COLORS, CalibrationPoints, Colors, RoomsProperties, RoomStore
|
19
19
|
from .config.utils import BaseHandler, prepare_resize_params
|
20
20
|
from .hypfer_draw import ImageDraw as ImDraw
|
21
21
|
from .map_data import ImageData
|
@@ -83,7 +83,8 @@ class HypferMapImageHandler(BaseHandler, AutoCrop):
|
|
83
83
|
"y": ((y_min + y_max) // 2),
|
84
84
|
}
|
85
85
|
if room_properties:
|
86
|
-
|
86
|
+
rooms = RoomStore(self.file_name, room_properties)
|
87
|
+
_LOGGER.debug("%s: Rooms data extracted! %s", self.file_name, rooms.get_rooms())
|
87
88
|
else:
|
88
89
|
_LOGGER.debug("%s: Rooms data not available!", self.file_name)
|
89
90
|
self.rooms_pos = None
|
@@ -27,6 +27,7 @@ from .config.types import (
|
|
27
27
|
from .config.utils import BaseHandler, prepare_resize_params
|
28
28
|
from .map_data import RandImageData
|
29
29
|
from .reimg_draw import ImageDraw
|
30
|
+
from .config.types import RoomStore
|
30
31
|
|
31
32
|
|
32
33
|
_LOGGER = logging.getLogger(__name__)
|
@@ -120,6 +121,8 @@ class ReImageHandler(BaseHandler, AutoCrop):
|
|
120
121
|
_LOGGER.debug(
|
121
122
|
"%s: Rooms and Zones data not available!", self.file_name
|
122
123
|
)
|
124
|
+
rooms = RoomStore(self.file_name, room_properties)
|
125
|
+
_LOGGER.debug("Rooms Data: %s", rooms.get_rooms())
|
123
126
|
return room_properties, zone_properties, point_properties
|
124
127
|
except RuntimeError as e:
|
125
128
|
_LOGGER.debug(
|
@@ -1,21 +1,21 @@
|
|
1
1
|
valetudo_map_parser/__init__.py,sha256=Wmd20bdI1btzMq-0x8NxGYWskTjdUmD-Fem9MTfziwU,810
|
2
2
|
valetudo_map_parser/config/__init__.py,sha256=DQ9plV3ZF_K25Dp5ZQHPDoG-40dQoJNdNi-dfNeR3Zc,48
|
3
|
-
valetudo_map_parser/config/auto_crop.py,sha256=
|
3
|
+
valetudo_map_parser/config/auto_crop.py,sha256=Og2rpK4izwh0aHlyZjw-tgDsQ2wXaIJGYLq1U43SSwc,12472
|
4
4
|
valetudo_map_parser/config/colors.py,sha256=IzTT9JvF12YGGJxaTiEJRuwUdCCsFCLzsR9seCDfYWs,6515
|
5
5
|
valetudo_map_parser/config/colors_man.py,sha256=9b5c6XmpMzhEiunwfIjVkOk1lDyV-UFoasACdkGXfbo,7833
|
6
6
|
valetudo_map_parser/config/drawable.py,sha256=hsrEJCMVOrjs5sJfr26SeqJD0VNlYWwxcVkkHeaxx7U,20356
|
7
7
|
valetudo_map_parser/config/rand25_parser.py,sha256=kIayyqVZBfQfAMkiArzqrrj9vqZB3pkgT0Y5ufrQmGA,16448
|
8
|
-
valetudo_map_parser/config/shared.py,sha256=
|
9
|
-
valetudo_map_parser/config/types.py,sha256=
|
10
|
-
valetudo_map_parser/config/utils.py,sha256=
|
8
|
+
valetudo_map_parser/config/shared.py,sha256=LunTeR-qAip0VzGNMtBw665rR6-MrH3rC7U8OExY3bA,10119
|
9
|
+
valetudo_map_parser/config/types.py,sha256=ZUXza0nWICBUS7xbSw7jz6McrbNGRvU1GdcJjOxD0yM,17525
|
10
|
+
valetudo_map_parser/config/utils.py,sha256=yPutV-FEQlDB2z3LhOOFznoprHCApF-zrQMiOtkcO-k,19198
|
11
11
|
valetudo_map_parser/hypfer_draw.py,sha256=1trtil-CQcDSiAMBWPBmuP5L9MWHGTp5OlY7MX8FgDg,14932
|
12
|
-
valetudo_map_parser/hypfer_handler.py,sha256=
|
12
|
+
valetudo_map_parser/hypfer_handler.py,sha256=WIWoHUtBoML9E5dHGwMiCwf0RUrV9EvBz9qapCfs0Cs,12971
|
13
13
|
valetudo_map_parser/map_data.py,sha256=6FbQfgxFB6E4kcOWokReJOVSekVaE1kStyhTQhAhiOg,19469
|
14
14
|
valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
valetudo_map_parser/rand25_handler.py,sha256=
|
15
|
+
valetudo_map_parser/rand25_handler.py,sha256=_etitjAnt2EBjopRgFYynJwWFwNF6M6-SlVhfCwWaN4,15256
|
16
16
|
valetudo_map_parser/reimg_draw.py,sha256=V0JUASavKVnEtAhv7nOV4pjsRxZrNsjIUtctbKO8wvk,12507
|
17
|
-
valetudo_map_parser-0.1.
|
18
|
-
valetudo_map_parser-0.1.
|
19
|
-
valetudo_map_parser-0.1.
|
20
|
-
valetudo_map_parser-0.1.
|
21
|
-
valetudo_map_parser-0.1.
|
17
|
+
valetudo_map_parser-0.1.9b34.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
|
18
|
+
valetudo_map_parser-0.1.9b34.dist-info/METADATA,sha256=pgeNzSLgXBYp6K2IWxLwLrxd3BrZRYhpzDo70i4Iaes,1029
|
19
|
+
valetudo_map_parser-0.1.9b34.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
|
20
|
+
valetudo_map_parser-0.1.9b34.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
21
|
+
valetudo_map_parser-0.1.9b34.dist-info/RECORD,,
|
File without changes
|
{valetudo_map_parser-0.1.9b32.dist-info → valetudo_map_parser-0.1.9b34.dist-info}/NOTICE.txt
RENAMED
File without changes
|
File without changes
|