valetudo-map-parser 0.1.9b22__tar.gz → 0.1.9b24__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.
Files changed (20) hide show
  1. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/PKG-INFO +1 -1
  2. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/__init__.py +1 -0
  3. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/auto_crop.py +13 -29
  4. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/colors.py +1 -0
  5. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/rand25_parser.py +1 -0
  6. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/shared.py +33 -2
  7. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/types.py +13 -0
  8. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/utils.py +21 -18
  9. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/hypfer_draw.py +1 -0
  10. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/hypfer_handler.py +14 -5
  11. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/rand25_handler.py +14 -4
  12. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/reimg_draw.py +1 -0
  13. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/pyproject.toml +4 -3
  14. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/LICENSE +0 -0
  15. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/NOTICE.txt +0 -0
  16. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/README.md +0 -0
  17. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/__init__.py +0 -0
  18. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/config/drawable.py +0 -0
  19. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/map_data.py +0 -0
  20. {valetudo_map_parser-0.1.9b22 → valetudo_map_parser-0.1.9b24}/SCR/valetudo_map_parser/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: valetudo-map-parser
3
- Version: 0.1.9b22
3
+ Version: 0.1.9b24
4
4
  Summary: A Python library to parse Valetudo map data returning a PIL Image object.
5
5
  License: Apache-2.0
6
6
  Author: Sandro Cantarella
@@ -16,6 +16,7 @@ from .config.types import (
16
16
  from .hypfer_handler import HypferMapImageHandler
17
17
  from .rand25_handler import ReImageHandler
18
18
 
19
+
19
20
  __all__ = [
20
21
  "HypferMapImageHandler",
21
22
  "ReImageHandler",
@@ -10,6 +10,7 @@ from numpy import rot90
10
10
 
11
11
  from .types import Color, NumpyArray, TrimCropData
12
12
 
13
+
13
14
  _LOGGER = logging.getLogger(__name__)
14
15
 
15
16
 
@@ -27,9 +28,6 @@ class AutoCrop:
27
28
  def __init__(self, image_handler):
28
29
  self.imh = image_handler
29
30
  self.file_name = self.imh.file_name
30
- # self.path_to_data = self.hass.config.path(
31
- # STORAGE_DIR, CAMERA_STORAGE, f"auto_crop_{self.file_name}.json"
32
- # )
33
31
 
34
32
  def check_trim(
35
33
  self, trimmed_height, trimmed_width, margin_size, image_array, file_name, rotate
@@ -70,19 +68,18 @@ class AutoCrop:
70
68
  )
71
69
  return trimmed_width, trimmed_height
72
70
 
73
- async def _async_auto_crop_data(self): # , tdata=None
71
+ async def _async_auto_crop_data(self, tdata=None): # , tdata=None
74
72
  """Load the auto crop data from the Camera config."""
75
- # todo: implement this method but from config data
76
- # if not self.imh.auto_crop:
77
- # trims_data = TrimCropData.from_dict(dict(tdata)).to_list()
78
- # (
79
- # self.imh.trim_left,
80
- # self.imh.trim_up,
81
- # self.imh.trim_right,
82
- # self.imh.trim_down,
83
- # ) = trims_data
84
- # self._calculate_trimmed_dimensions()
85
- # return trims_data
73
+ if not self.imh.auto_crop:
74
+ trims_data = TrimCropData.from_dict(dict(tdata)).to_list()
75
+ (
76
+ self.imh.trim_left,
77
+ self.imh.trim_up,
78
+ self.imh.trim_right,
79
+ self.imh.trim_down,
80
+ ) = trims_data
81
+ self._calculate_trimmed_dimensions()
82
+ return trims_data
86
83
  return None
87
84
 
88
85
  def auto_crop_offset(self):
@@ -96,26 +93,13 @@ class AutoCrop:
96
93
  async def _init_auto_crop(self):
97
94
  """Initialize the auto crop data."""
98
95
  if not self.imh.auto_crop and self.imh.shared.vacuum_state == "docked":
99
- self.imh.auto_crop = await self._async_auto_crop_data()
96
+ self.imh.auto_crop = await self._async_auto_crop_data(self.imh.shared.trims)
100
97
  if self.imh.auto_crop:
101
98
  self.auto_crop_offset()
102
99
  else:
103
100
  self.imh.max_frames = 5
104
101
  return self.imh.auto_crop
105
102
 
106
- # async def _async_save_auto_crop_data(self):
107
- # """Save the auto crop data to the disk."""
108
- # try:
109
- # if not os.path.exists(self.path_to_data):
110
- # data = TrimCropData(
111
- # self.imh.trim_left,
112
- # self.imh.trim_up,
113
- # self.imh.trim_right,
114
- # self.imh.trim_down,
115
- # ).to_dict()
116
- # except Exception as e:
117
- # _LOGGER.error(f"Failed to save trim data due to an error: {e}")
118
-
119
103
  async def async_image_margins(
120
104
  self, image_array: NumpyArray, detect_colour: Color
121
105
  ) -> tuple[int, int, int, int]:
@@ -6,6 +6,7 @@ import logging
6
6
  from enum import StrEnum
7
7
  from typing import Dict, List, Tuple
8
8
 
9
+
9
10
  _LOGGER = logging.getLogger(__name__)
10
11
 
11
12
  Color = Tuple[int, int, int, int] # RGBA color definition
@@ -10,6 +10,7 @@ import struct
10
10
  from enum import Enum
11
11
  from typing import Any, Callable, Dict, List, Optional, TypeVar
12
12
 
13
+
13
14
  _CallableT = TypeVar("_CallableT", bound=Callable[..., Any])
14
15
 
15
16
 
@@ -6,6 +6,7 @@ Version: v2024.12.0
6
6
 
7
7
  import asyncio
8
8
  import logging
9
+ from typing import Dict, List
9
10
 
10
11
  from .types import (
11
12
  ATTR_CALIBRATION_POINTS,
@@ -36,8 +37,10 @@ from .types import (
36
37
  DEFAULT_VALUES,
37
38
  CameraModes,
38
39
  Colors,
40
+ TrimsData,
39
41
  )
40
42
 
43
+
41
44
  _LOGGER = logging.getLogger(__name__)
42
45
 
43
46
 
@@ -99,8 +102,23 @@ class CameraShared:
99
102
  self.map_pred_points = None # Predefined points data
100
103
  self.map_new_path = None # New path data
101
104
  self.map_old_path = None # Old path data
102
- self.trim_crop_data = None
103
105
  self.user_language = None # User language
106
+ self.trim_crop_data = None
107
+ self.trims: Dict[TrimsData, int] = {
108
+ TrimsData.TRIM_LEFT: 0,
109
+ TrimsData.TRIM_UP: 0,
110
+ TrimsData.TRIM_RIGHT: 0,
111
+ TrimsData.TRIM_DOWN: 0,
112
+ }
113
+ self.skip_room_ids: List[str] = []
114
+
115
+ def get_trims_dictionary(self):
116
+ return {
117
+ "trim_left": self.trims.get(TrimsData.TRIM_LEFT, 0),
118
+ "trim_up": self.trims.get(TrimsData.TRIM_UP, 0),
119
+ "trim_right": self.trims.get(TrimsData.TRIM_RIGHT, 0),
120
+ "trim_down": self.trims.get(TrimsData.TRIM_DOWN, 0),
121
+ }
104
122
 
105
123
  def update_user_colors(self, user_colors):
106
124
  """Update the user colors."""
@@ -218,11 +236,24 @@ class CameraSharedManager:
218
236
  instance.vacuum_status_position = device_info.get(
219
237
  CONF_VAC_STAT_POS, DEFAULT_VALUES["vac_status_position"]
220
238
  )
221
-
222
239
  # If enable_snapshots, check for png in www.
223
240
  instance.enable_snapshots = device_info.get(
224
241
  CONF_SNAPSHOTS_ENABLE, DEFAULT_VALUES["enable_www_snapshots"]
225
242
  )
243
+ instance.trims = {
244
+ TrimsData.TRIM_LEFT: device_info.get(
245
+ "trims_data", DEFAULT_VALUES["trims_data"]
246
+ ).get("trim_left", 0),
247
+ TrimsData.TRIM_UP: device_info.get(
248
+ "trims_data", DEFAULT_VALUES["trims_data"]
249
+ ).get("trim_up", 0),
250
+ TrimsData.TRIM_RIGHT: device_info.get(
251
+ "trims_data", DEFAULT_VALUES["trims_data"]
252
+ ).get("trim_right", 0),
253
+ TrimsData.TRIM_DOWN: device_info.get(
254
+ "trims_data", DEFAULT_VALUES["trims_data"]
255
+ ).get("trim_down", 0),
256
+ }
226
257
 
227
258
  except TypeError as ex:
228
259
  _LOGGER.error("Shared data can't be initialized due to a TypeError! %s", ex)
@@ -7,11 +7,13 @@ import asyncio
7
7
  import json
8
8
  import logging
9
9
  from dataclasses import dataclass
10
+ from enum import Enum
10
11
  from typing import Any, Dict, Tuple, Union
11
12
 
12
13
  import numpy as np
13
14
  from PIL import Image
14
15
 
16
+
15
17
  DEFAULT_ROOMS = 1
16
18
 
17
19
  MY_LOGGER = logging.getLogger(__name__)
@@ -283,6 +285,7 @@ DEFAULT_VALUES = {
283
285
  "vac_status_position": True,
284
286
  "get_svg_file": False,
285
287
  "save_trims": True,
288
+ "trims_data": {"trim_left": 0, "trim_up": 0, "trim_right": 0, "trim_down": 0},
286
289
  "enable_www_snapshots": False,
287
290
  "color_charger": [255, 128, 0],
288
291
  "color_move": [238, 247, 255],
@@ -344,6 +347,7 @@ KEYS_TO_UPDATE = [
344
347
  "offset_bottom",
345
348
  "offset_left",
346
349
  "offset_right",
350
+ "trims_data",
347
351
  "auto_zoom",
348
352
  "zoom_lock_ratio",
349
353
  "show_vac_status",
@@ -587,3 +591,12 @@ class CameraModes:
587
591
  CAMERA_STANDBY = "camera_standby"
588
592
  CAMERA_OFF = False
589
593
  CAMERA_ON = True
594
+
595
+
596
+ class TrimsData(Enum):
597
+ """Constants for the trims data."""
598
+
599
+ TRIM_LEFT = "trim_left"
600
+ TRIM_UP = "trim_up"
601
+ TRIM_RIGHT = "trim_right"
602
+ TRIM_DOWN = "trim_down"
@@ -4,10 +4,12 @@ import hashlib
4
4
  import json
5
5
  from dataclasses import dataclass
6
6
  from logging import getLogger
7
+ from typing import Callable, List, Optional
7
8
 
8
- from PIL import Image, ImageOps
9
+ from PIL import ImageOps
10
+
11
+ from .types import ChargerPosition, ImageSize, NumpyArray, PilPNG, RobotPosition
9
12
 
10
- from .types import ChargerPosition, ImageSize, NumpyArray, RobotPosition
11
13
 
12
14
  _LOGGER = getLogger(__name__)
13
15
 
@@ -16,13 +18,13 @@ _LOGGER = getLogger(__name__)
16
18
  class ResizeParams:
17
19
  """Resize the image to the given dimensions and aspect ratio."""
18
20
 
19
- pil_img: Image # PIL image object
21
+ pil_img: PilPNG
20
22
  width: int
21
23
  height: int
22
- aspect_ratio: str = None
23
- crop_size: list = None
24
- is_rand: bool = False
25
- offset_func: callable = None # Function reference for offset calculation
24
+ aspect_ratio: str
25
+ crop_size: List[int]
26
+ is_rand: Optional[bool] = False
27
+ offset_func: Optional[Callable] = None
26
28
 
27
29
 
28
30
  @dataclass
@@ -33,7 +35,7 @@ class OffsetParams:
33
35
  hsf: int
34
36
  width: int
35
37
  height: int
36
- rand256: bool = False
38
+ rand256: Optional[bool] = False
37
39
 
38
40
 
39
41
  class BaseHandler:
@@ -91,7 +93,7 @@ class BaseHandler:
91
93
  )
92
94
 
93
95
  def _set_image_offset_ratio_1_1(
94
- self, width: int, height: int, rand256: bool = False
96
+ self, width: int, height: int, rand256: Optional[bool] = False
95
97
  ) -> None:
96
98
  """Set the image offset ratio to 1:1."""
97
99
 
@@ -118,7 +120,7 @@ class BaseHandler:
118
120
  )
119
121
 
120
122
  def _set_image_offset_ratio_2_1(
121
- self, width: int, height: int, rand256: bool = False
123
+ self, width: int, height: int, rand256: Optional[bool] = False
122
124
  ) -> None:
123
125
  """Set the image offset ratio to 2:1."""
124
126
 
@@ -146,7 +148,7 @@ class BaseHandler:
146
148
  )
147
149
 
148
150
  def _set_image_offset_ratio_3_2(
149
- self, width: int, height: int, rand256: bool = False
151
+ self, width: int, height: int, rand256: Optional[bool] = False
150
152
  ) -> None:
151
153
  """Set the image offset ratio to 3:2."""
152
154
 
@@ -177,7 +179,7 @@ class BaseHandler:
177
179
  )
178
180
 
179
181
  def _set_image_offset_ratio_5_4(
180
- self, width: int, height: int, rand256: bool = False
182
+ self, width: int, height: int, rand256: Optional[bool] = False
181
183
  ) -> None:
182
184
  """Set the image offset ratio to 5:4."""
183
185
 
@@ -209,7 +211,7 @@ class BaseHandler:
209
211
  )
210
212
 
211
213
  def _set_image_offset_ratio_9_16(
212
- self, width: int, height: int, rand256: bool = False
214
+ self, width: int, height: int, rand256: Optional[bool] = False
213
215
  ) -> None:
214
216
  """Set the image offset ratio to 9:16."""
215
217
 
@@ -237,7 +239,7 @@ class BaseHandler:
237
239
  )
238
240
 
239
241
  def _set_image_offset_ratio_16_9(
240
- self, width: int, height: int, rand256: bool = False
242
+ self, width: int, height: int, rand256: Optional[bool] = False
241
243
  ) -> None:
242
244
  """Set the image offset ratio to 16:9."""
243
245
 
@@ -298,8 +300,8 @@ class BaseHandler:
298
300
 
299
301
  @staticmethod
300
302
  async def calculate_array_hash(
301
- layers: dict, active: list[int] = None
302
- ) -> str or None:
303
+ layers: dict, active: Optional[List[int]]
304
+ ) -> str | None:
303
305
  """Calculate the hash of the image based on layers and active zones."""
304
306
  if layers and active:
305
307
  data_to_hash = {
@@ -499,7 +501,7 @@ async def async_resize_image(params: ResizeParams):
499
501
  str(hsf),
500
502
  )
501
503
 
502
- if params.crop_size is not None:
504
+ if (params.crop_size is not None) and (params.offset_func is not None):
503
505
  offset = OffsetParams(wsf, hsf, new_width, new_height, params.is_rand)
504
506
  params.crop_size[0], params.crop_size[1] = await params.offset_func(offset)
505
507
 
@@ -507,6 +509,7 @@ async def async_resize_image(params: ResizeParams):
507
509
 
508
510
  return ImageOps.pad(params.pil_img, (params.width, params.height))
509
511
 
512
+
510
513
  def prepare_resize_params(handler, pil_img, rand):
511
514
  """Prepare resize parameters for image resizing."""
512
515
  return ResizeParams(
@@ -516,5 +519,5 @@ def prepare_resize_params(handler, pil_img, rand):
516
519
  aspect_ratio=handler.shared.image_aspect_ratio,
517
520
  crop_size=handler.crop_img_size,
518
521
  offset_func=handler.async_map_coordinates_offset,
519
- is_rand=rand
522
+ is_rand=rand,
520
523
  )
@@ -10,6 +10,7 @@ import logging
10
10
 
11
11
  from .config.types import Color, JsonType, NumpyArray, RobotPosition
12
12
 
13
+
13
14
  _LOGGER = logging.getLogger(__name__)
14
15
 
15
16
 
@@ -15,11 +15,12 @@ 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, TrimsData
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
22
22
 
23
+
23
24
  _LOGGER = logging.getLogger(__name__)
24
25
 
25
26
 
@@ -41,10 +42,18 @@ class HypferMapImageHandler(BaseHandler):
41
42
  self.img_base_layer = None # numpy array store the map base layer.
42
43
  self.active_zones = None # vacuum active zones.
43
44
  self.svg_wait = False # SVG image creation wait.
44
- self.trim_down = 0 # memory stored trims calculated once.
45
- self.trim_left = 0 # memory stored trims calculated once.
46
- self.trim_right = 0 # memory stored trims calculated once.
47
- self.trim_up = 0 # memory stored trims calculated once.
45
+ self.trim_up = self.shared.trims.get(
46
+ TrimsData.TRIM_UP, 0
47
+ ) # memory stored trims calculated once.
48
+ self.trim_down = self.shared.trims.get(
49
+ TrimsData.TRIM_DOWN, 0
50
+ ) # memory stored trims calculated once.
51
+ self.trim_left = self.shared.trims.get(
52
+ TrimsData.TRIM_LEFT, 0
53
+ ) # memory stored trims calculated once.
54
+ self.trim_right = self.shared.trims.get(
55
+ TrimsData.TRIM_RIGHT, 0
56
+ ) # memory stored trims calculated once.
48
57
  self.offset_top = self.shared.offset_top # offset top
49
58
  self.offset_bottom = self.shared.offset_down # offset bottom
50
59
  self.offset_left = self.shared.offset_left # offset left
@@ -23,11 +23,13 @@ from .config.types import (
23
23
  PilPNG,
24
24
  RobotPosition,
25
25
  RoomsProperties,
26
+ TrimsData,
26
27
  )
27
28
  from .config.utils import BaseHandler, prepare_resize_params
28
29
  from .map_data import RandImageData
29
30
  from .reimg_draw import ImageDraw
30
31
 
32
+
31
33
  _LOGGER = logging.getLogger(__name__)
32
34
 
33
35
 
@@ -51,10 +53,18 @@ class ReImageHandler(BaseHandler):
51
53
  self.room_propriety = None # Room propriety data
52
54
  self.shared = camera_shared # Shared data
53
55
  self.active_zones = None # Active zones
54
- self.trim_down = None # Trim down
55
- self.trim_left = None # Trim left
56
- self.trim_right = None # Trim right
57
- self.trim_up = None # Trim up
56
+ self.trim_up = self.shared.trims.get(
57
+ TrimsData.TRIM_UP, 0
58
+ ) # memory stored trims calculated once.
59
+ self.trim_down = self.shared.trims.get(
60
+ TrimsData.TRIM_DOWN, 0
61
+ ) # memory stored trims calculated once.
62
+ self.trim_left = self.shared.trims.get(
63
+ TrimsData.TRIM_LEFT, 0
64
+ ) # memory stored trims calculated once.
65
+ self.trim_right = self.shared.trims.get(
66
+ TrimsData.TRIM_RIGHT, 0
67
+ ) # memory stored trims calculated once.
58
68
  self.file_name = self.shared.file_name # File name
59
69
  self.offset_top = self.shared.offset_top # offset top
60
70
  self.offset_bottom = self.shared.offset_down # offset bottom
@@ -12,6 +12,7 @@ from .config.drawable import Drawable
12
12
  from .config.types import Color, JsonType, NumpyArray
13
13
  from .map_data import ImageData, RandImageData
14
14
 
15
+
15
16
  _LOGGER = logging.getLogger(__name__)
16
17
 
17
18
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "valetudo-map-parser"
3
- version = "0.1.9.b22"
3
+ version = "0.1.9.b24"
4
4
  description = "A Python library to parse Valetudo map data returning a PIL Image object."
5
5
  authors = ["Sandro Cantarella <gsca075@gmail.com>"]
6
6
  license = "Apache-2.0"
@@ -41,8 +41,9 @@ lines_after_imports = 2
41
41
 
42
42
  # Pylint settings
43
43
  [tool.pylint]
44
- disable = ["C0103", "C0116", "R0902", "R0903", "R0913",
45
- "R0914", "W0640", "R0917", "R0904", "R0915", "W0511"]
44
+ disable = ["C0103", "C0116", "R0902", "R0903", "R0904","R0913",
45
+ "R0914", "R0917", "R0915", "W0640"]
46
+
46
47
  max-line-length = 120
47
48
 
48
49
  [build-system]