valetudo-map-parser 0.1.9b5__py3-none-any.whl → 0.1.9b6__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.
@@ -6,7 +6,6 @@ from logging import getLogger
6
6
 
7
7
  from PIL import ImageOps
8
8
 
9
- from ..images_utils import ImageUtils as ImUtils
10
9
  from .types import ChargerPosition, ImageSize, NumpyArray, RobotPosition
11
10
 
12
11
  _LOGGER = getLogger(__name__)
@@ -29,7 +28,9 @@ class BaseHandler:
29
28
  self.frame_number = 0
30
29
  self.max_frames = 1024
31
30
  self.crop_img_size = [0, 0]
32
- self.imu = ImUtils(self) # Image Utils
31
+ self.offset_x = 0
32
+ self.offset_y = 0
33
+ self.shared = None
33
34
 
34
35
  def get_frame_number(self) -> int:
35
36
  """Return the frame number of the image."""
@@ -89,17 +90,17 @@ class BaseHandler:
89
90
  """
90
91
 
91
92
  if wsf == 1 and hsf == 1:
92
- self.imu.set_image_offset_ratio_1_1(width, height, rand256)
93
+ self.set_image_offset_ratio_1_1(width, height, rand256)
93
94
  elif wsf == 2 and hsf == 1:
94
- self.imu.set_image_offset_ratio_2_1(width, height, rand256)
95
+ self.set_image_offset_ratio_2_1(width, height, rand256)
95
96
  elif wsf == 3 and hsf == 2:
96
- self.imu.set_image_offset_ratio_3_2(width, height, rand256)
97
+ self.set_image_offset_ratio_3_2(width, height, rand256)
97
98
  elif wsf == 5 and hsf == 4:
98
- self.imu.set_image_offset_ratio_5_4(width, height, rand256)
99
+ self.set_image_offset_ratio_5_4(width, height, rand256)
99
100
  elif wsf == 9 and hsf == 16:
100
- self.imu.set_image_offset_ratio_9_16(width, height, rand256=True)
101
+ self.set_image_offset_ratio_9_16(width, height, rand256)
101
102
  elif wsf == 16 and hsf == 9:
102
- self.imu.set_image_offset_ratio_16_9(width, height, rand256=True)
103
+ self.set_image_offset_ratio_16_9(width, height, rand256)
103
104
  return width, height
104
105
 
105
106
  @staticmethod
@@ -130,3 +131,318 @@ class BaseHandler:
130
131
  }, # Bottom-right corner 2
131
132
  {"x": 0, "y": self.crop_img_size[1]}, # Bottom-left corner (optional) 3
132
133
  ]
134
+
135
+ def set_image_offset_ratio_1_1(
136
+ self, width: int, height: int, rand256: bool = False
137
+ ) -> None:
138
+ """Set the image offset ratio to 1:1."""
139
+
140
+ rotation = self.shared.image_rotate
141
+ if not rand256:
142
+ if rotation in [0, 180]:
143
+ self.offset_y = self.crop_img_size[0] - width
144
+ self.offset_x = (height - self.crop_img_size[1]) // 2
145
+ elif rotation in [90, 270]:
146
+ self.offset_y = width - self.crop_img_size[0]
147
+ self.offset_x = (self.crop_img_size[1] - height) // 2
148
+ else:
149
+ if rotation in [0, 180]:
150
+ self.offset_x = (width - self.crop_img_size[0]) // 2
151
+ self.offset_y = height - self.crop_img_size[1]
152
+ elif rotation in [90, 270]:
153
+ self.offset_y = (self.crop_img_size[0] - width) // 2
154
+ self.offset_x = self.crop_img_size[1] - height
155
+ _LOGGER.debug(
156
+ "%s Image Coordinates Offsets (x,y): %s. %s",
157
+ self.file_name,
158
+ self.offset_x,
159
+ self.offset_y,
160
+ )
161
+
162
+ def set_image_offset_ratio_2_1(
163
+ self, width: int, height: int, rand256: bool = False
164
+ ) -> None:
165
+ """Set the image offset ratio to 2:1."""
166
+
167
+ rotation = self.shared.image_rotate
168
+ if not rand256:
169
+ if rotation in [0, 180]:
170
+ self.offset_y = width - self.crop_img_size[0]
171
+ self.offset_x = height - self.crop_img_size[1]
172
+ elif rotation in [90, 270]:
173
+ self.offset_x = width - self.crop_img_size[0]
174
+ self.offset_y = height - self.crop_img_size[1]
175
+ else:
176
+ if rotation in [0, 180]:
177
+ self.offset_y = width - self.crop_img_size[0]
178
+ self.offset_x = height - self.crop_img_size[1]
179
+ elif rotation in [90, 270]:
180
+ self.offset_x = width - self.crop_img_size[0]
181
+ self.offset_y = height - self.crop_img_size[1]
182
+
183
+ _LOGGER.debug(
184
+ "%s Image Coordinates Offsets (x,y): %s. %s",
185
+ self.file_name,
186
+ self.offset_x,
187
+ self.offset_y,
188
+ )
189
+
190
+ def set_image_offset_ratio_3_2(
191
+ self, width: int, height: int, rand256: bool = False
192
+ ) -> None:
193
+ """Set the image offset ratio to 3:2."""
194
+
195
+ rotation = self.shared.image_rotate
196
+
197
+ if not rand256:
198
+ if rotation in [0, 180]:
199
+ self.offset_y = width - self.crop_img_size[0]
200
+ self.offset_x = ((height - self.crop_img_size[1]) // 2) - (
201
+ self.crop_img_size[1] // 10
202
+ )
203
+ elif rotation in [90, 270]:
204
+ self.offset_y = (self.crop_img_size[0] - width) // 2
205
+ self.offset_x = (self.crop_img_size[1] - height) + (
206
+ (height // 10) // 2
207
+ )
208
+ else:
209
+ if rotation in [0, 180]:
210
+ self.offset_x = (width - self.crop_img_size[0]) // 2
211
+ self.offset_y = height - self.crop_img_size[1]
212
+ elif rotation in [90, 270]:
213
+ self.offset_y = (self.crop_img_size[0] - width) // 2
214
+ self.offset_x = self.crop_img_size[1] - height
215
+
216
+ _LOGGER.debug(
217
+ "%s Image Coordinates Offsets (x,y): %s. %s",
218
+ self.file_name,
219
+ self.offset_x,
220
+ self.offset_y,
221
+ )
222
+
223
+ def set_image_offset_ratio_5_4(
224
+ self, width: int, height: int, rand256: bool = False
225
+ ) -> None:
226
+ """Set the image offset ratio to 5:4."""
227
+
228
+ rotation = self.shared.image_rotate
229
+ if not rand256:
230
+ if rotation in [0, 180]:
231
+ self.offset_x = ((width - self.crop_img_size[0]) // 2) - (
232
+ self.crop_img_size[0] // 2
233
+ )
234
+ self.offset_y = (self.crop_img_size[1] - height) - (
235
+ self.crop_img_size[1] // 2
236
+ )
237
+ elif rotation in [90, 270]:
238
+ self.offset_y = ((self.crop_img_size[0] - width) // 2) - 10
239
+ self.offset_x = (self.crop_img_size[1] - height) + (
240
+ height // 10
241
+ )
242
+ else:
243
+ if rotation in [0, 180]:
244
+ self.offset_y = (width - self.crop_img_size[0]) // 2
245
+ self.offset_x = self.crop_img_size[1] - height
246
+ elif rotation in [90, 270]:
247
+ self.offset_y = (self.crop_img_size[0] - width) // 2
248
+ self.offset_x = self.crop_img_size[1] - height
249
+
250
+ _LOGGER.debug(
251
+ "%s Image Coordinates Offsets (x,y): %s. %s",
252
+ self.file_name,
253
+ self.offset_x,
254
+ self.offset_y,
255
+ )
256
+
257
+ def set_image_offset_ratio_9_16(
258
+ self, width: int, height: int, rand256: bool = False
259
+ ) -> None:
260
+ """Set the image offset ratio to 9:16."""
261
+
262
+ rotation = self.shared.image_rotate
263
+ if not rand256:
264
+ if rotation in [0, 180]:
265
+ self.offset_y = width - self.crop_img_size[0]
266
+ self.offset_x = height - self.crop_img_size[1]
267
+ elif rotation in [90, 270]:
268
+ self.offset_x = (width - self.crop_img_size[0]) + (height // 10)
269
+ self.offset_y = height - self.crop_img_size[1]
270
+ else:
271
+ if rotation in [0, 180]:
272
+ self.offset_y = width - self.crop_img_size[0]
273
+ self.offset_x = height - self.crop_img_size[1]
274
+ elif rotation in [90, 270]:
275
+ self.offset_x = width - self.crop_img_size[0]
276
+ self.offset_y = height - self.crop_img_size[1]
277
+
278
+ _LOGGER.debug(
279
+ "%s Image Coordinates Offsets (x,y): %s. %s",
280
+ self.file_name,
281
+ self.offset_x,
282
+ self.offset_y,
283
+ )
284
+
285
+ def set_image_offset_ratio_16_9(
286
+ self, width: int, height: int, rand256: bool = False
287
+ ) -> None:
288
+ """Set the image offset ratio to 16:9."""
289
+
290
+ rotation = self.shared.image_rotate
291
+ if not rand256:
292
+ if rotation in [0, 180]:
293
+ self.offset_y = width - self.crop_img_size[0]
294
+ self.offset_x = height - self.crop_img_size[1]
295
+ elif rotation in [90, 270]:
296
+ self.offset_x = width - self.crop_img_size[0]
297
+ self.offset_y = height - self.crop_img_size[1]
298
+ else:
299
+ if rotation in [0, 180]:
300
+ self.offset_y = width - self.crop_img_size[0]
301
+ self.offset_x = height - self.crop_img_size[1]
302
+ elif rotation in [90, 270]:
303
+ self.offset_x = width - self.crop_img_size[0]
304
+ self.offset_y = height - self.crop_img_size[1]
305
+
306
+ _LOGGER.debug(
307
+ "%s Image Coordinates Offsets (x,y): %s. %s",
308
+ self.file_name,
309
+ self.offset_x,
310
+ self.offset_y,
311
+ )
312
+
313
+ def get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
314
+ """Calculate the calibration points based on the rotation angle."""
315
+
316
+ # get_calibration_data
317
+ vacuum_points = [
318
+ {
319
+ "x": self.img.crop_area[0] + self.img.offset_x,
320
+ "y": self.img.crop_area[1] + self.img.offset_y,
321
+ }, # Top-left corner 0
322
+ {
323
+ "x": self.img.crop_area[2] - self.img.offset_x,
324
+ "y": self.img.crop_area[1] + self.img.offset_y,
325
+ }, # Top-right corner 1
326
+ {
327
+ "x": self.img.crop_area[2] - self.img.offset_x,
328
+ "y": self.img.crop_area[3] - self.img.offset_y,
329
+ }, # Bottom-right corner 2
330
+ {
331
+ "x": self.img.crop_area[0] + self.img.offset_x,
332
+ "y": self.img.crop_area[3] - self.img.offset_y,
333
+ }, # Bottom-left corner (optional)3
334
+ ]
335
+
336
+ # Rotate the vacuum points based on the rotation angle
337
+ if rotation_angle == 90:
338
+ vacuum_points = [
339
+ vacuum_points[1],
340
+ vacuum_points[2],
341
+ vacuum_points[3],
342
+ vacuum_points[0],
343
+ ]
344
+ elif rotation_angle == 180:
345
+ vacuum_points = [
346
+ vacuum_points[2],
347
+ vacuum_points[3],
348
+ vacuum_points[0],
349
+ vacuum_points[1],
350
+ ]
351
+ elif rotation_angle == 270:
352
+ vacuum_points = [
353
+ vacuum_points[3],
354
+ vacuum_points[0],
355
+ vacuum_points[1],
356
+ vacuum_points[2],
357
+ ]
358
+
359
+ return vacuum_points
360
+
361
+ def re_get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
362
+ """Recalculate the calibration points based on the rotation angle.
363
+ RAND256 Vacuums Calibration Points are in 10th of a mm."""
364
+ vacuum_points = [
365
+ {
366
+ "x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
367
+ "y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
368
+ }, # Top-left corner 0
369
+ {
370
+ "x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
371
+ "y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
372
+ }, # Top-right corner 1
373
+ {
374
+ "x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
375
+ "y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
376
+ }, # Bottom-right corner 2
377
+ {
378
+ "x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
379
+ "y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
380
+ }, # Bottom-left corner (optional)3
381
+ ]
382
+
383
+ # Rotate the vacuum points based on the rotation angle
384
+ if rotation_angle == 90:
385
+ vacuum_points = [
386
+ vacuum_points[1],
387
+ vacuum_points[2],
388
+ vacuum_points[3],
389
+ vacuum_points[0],
390
+ ]
391
+ elif rotation_angle == 180:
392
+ vacuum_points = [
393
+ vacuum_points[2],
394
+ vacuum_points[3],
395
+ vacuum_points[0],
396
+ vacuum_points[1],
397
+ ]
398
+ elif rotation_angle == 270:
399
+ vacuum_points = [
400
+ vacuum_points[3],
401
+ vacuum_points[0],
402
+ vacuum_points[1],
403
+ vacuum_points[2],
404
+ ]
405
+
406
+ return vacuum_points
407
+
408
+ async def async_zone_propriety(self, zones_data) -> dict:
409
+ """Get the zone propriety"""
410
+ zone_properties = {}
411
+ id_count = 1
412
+ for zone in zones_data:
413
+ zone_name = zone.get("name")
414
+ coordinates = zone.get("coordinates")
415
+ if coordinates and len(coordinates) > 0:
416
+ coordinates[0].pop()
417
+ x1, y1, x2, y2 = coordinates[0]
418
+ zone_properties[zone_name] = {
419
+ "zones": coordinates,
420
+ "name": zone_name,
421
+ "x": ((x1 + x2) // 2),
422
+ "y": ((y1 + y2) // 2),
423
+ }
424
+ id_count += 1
425
+ if id_count > 1:
426
+ _LOGGER.debug("%s: Zones Properties updated.", self.file_name)
427
+ return zone_properties
428
+
429
+ async def async_points_propriety(self, points_data) -> dict:
430
+ """Get the point propriety"""
431
+ point_properties = {}
432
+ id_count = 1
433
+ for point in points_data:
434
+ point_name = point.get("name")
435
+ coordinates = point.get("coordinates")
436
+ if coordinates and len(coordinates) > 0:
437
+ coordinates = point.get("coordinates")
438
+ x1, y1 = coordinates
439
+ point_properties[id_count] = {
440
+ "position": coordinates,
441
+ "name": point_name,
442
+ "x": x1,
443
+ "y": y1,
444
+ }
445
+ id_count += 1
446
+ if id_count > 1:
447
+ _LOGGER.debug("%s: Point Properties updated.", self.file_name)
448
+ return point_properties
@@ -51,8 +51,6 @@ class HypferMapImageHandler(BaseHandler):
51
51
  self.offset_bottom = self.shared.offset_down # offset bottom
52
52
  self.offset_left = self.shared.offset_left # offset left
53
53
  self.offset_right = self.shared.offset_right # offset right
54
- self.offset_x = 0 # offset x for the aspect ratio.
55
- self.offset_y = 0 # offset y for the aspect ratio.
56
54
  self.imd = ImDraw(self)
57
55
  self.ac = AutoCrop(self)
58
56
  self.color_grey = (128, 128, 128, 255)
@@ -303,7 +301,7 @@ class HypferMapImageHandler(BaseHandler):
303
301
  # Define the map points (fixed)
304
302
  map_points = self.get_map_points()
305
303
  # Calculate the calibration points in the vacuum coordinate system
306
- vacuum_points = self.imu.get_vacuum_points(rotation_angle)
304
+ vacuum_points = self.get_vacuum_points(rotation_angle)
307
305
 
308
306
  # Create the calibration data for each point
309
307
  for vacuum_point, map_point in zip(vacuum_points, map_points):
@@ -57,8 +57,6 @@ class ReImageHandler(BaseHandler):
57
57
  self.trim_up = None # Trim up
58
58
  self.zooming = False # Zooming flag
59
59
  self.file_name = self.shared.file_name # File name
60
- self.offset_x = 0 # offset x for the aspect ratio.
61
- self.offset_y = 0 # offset y for the aspect ratio.
62
60
  self.offset_top = self.shared.offset_top # offset top
63
61
  self.offset_bottom = self.shared.offset_down # offset bottom
64
62
  self.offset_left = self.shared.offset_left # offset left
@@ -121,9 +119,9 @@ class ReImageHandler(BaseHandler):
121
119
  "y": (y_min + y_max) // 2,
122
120
  }
123
121
  # get the zones and points data
124
- zone_properties = await self.imu.async_zone_propriety(zones_data)
122
+ zone_properties = await self.async_zone_propriety(zones_data)
125
123
  # get the points data
126
- point_properties = await self.imu.async_points_propriety(points_data)
124
+ point_properties = await self.async_points_propriety(points_data)
127
125
  if room_properties or zone_properties:
128
126
  extracted_data = [
129
127
  f"{len(room_properties)} Rooms" if room_properties else None,
@@ -381,7 +379,7 @@ class ReImageHandler(BaseHandler):
381
379
  map_points = self.get_map_points()
382
380
 
383
381
  # Valetudo Re version need corrections of the coordinates and are implemented with *10
384
- vacuum_points = self.imu.re_get_vacuum_points(rotation_angle)
382
+ vacuum_points = self.re_get_vacuum_points(rotation_angle)
385
383
 
386
384
  # Create the calibration data for each point
387
385
  for vacuum_point, map_point in zip(vacuum_points, map_points):
@@ -6,8 +6,6 @@ Version: 2024.12.0
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- import hashlib
10
- import json
11
9
  import logging
12
10
 
13
11
  from .config.drawable import Drawable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: valetudo-map-parser
3
- Version: 0.1.9b5
3
+ Version: 0.1.9b6
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
@@ -6,16 +6,15 @@ valetudo_map_parser/config/drawable.py,sha256=hsrEJCMVOrjs5sJfr26SeqJD0VNlYWwxcV
6
6
  valetudo_map_parser/config/rand25_parser.py,sha256=fehyF18hRWRWbXbojocQCIaIch21Lbh1wtl2XdKRSl0,16447
7
7
  valetudo_map_parser/config/shared.py,sha256=LQV5K8tbVhEKUkby9ssjEmh_T4Ai-Euzsbag_HWYVRc,9448
8
8
  valetudo_map_parser/config/types.py,sha256=-8F1WwCH5hKSih83-WPjYbGdQyKmNqkDmSKvlyz6qPg,16163
9
- valetudo_map_parser/config/utils.py,sha256=l59-8LtDlFpUbqVL1ZSdmvNOpNuo65JwGnxUI7SYp9k,4728
9
+ valetudo_map_parser/config/utils.py,sha256=W4meKptsRCAmfNLGPktFy1GiBM1F6tLLZW750VCwCJ8,16717
10
10
  valetudo_map_parser/hypfer_draw.py,sha256=JFiWb-06WI1Gt0TrIl2ieBVLHe1_zxh4h9N7V5dXtaM,14951
11
- valetudo_map_parser/hypfer_handler.py,sha256=lb3pTS48C0O_twOCIyz6K1DAO8Cpg78WpbbQZ3LMkE8,14211
12
- valetudo_map_parser/images_utils.py,sha256=1HMf57CODrgfIsIxKAmHcfiylitQ-wUPEsYoqiGqHbo,12947
11
+ valetudo_map_parser/hypfer_handler.py,sha256=SAQFg0VUEA5tDdvnAqDOD6oM_1v5EMRFHwuUcyBmN9g,14087
13
12
  valetudo_map_parser/map_data.py,sha256=qm1Zlfex0JrfhQsAKUOzsceZL0X92oAyGJ5Wvsq6YhA,19447
14
13
  valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- valetudo_map_parser/rand25_handler.py,sha256=htoWivyLFs1xK6ca8E4zx2k9Zf4mNPGcpw4l-5xAfH0,15959
16
- valetudo_map_parser/reimg_draw.py,sha256=yozq4QesZVljZwFcWOXm_65AUxhD_9KwJUjnf9tqPCg,12533
17
- valetudo_map_parser-0.1.9b5.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
18
- valetudo_map_parser-0.1.9b5.dist-info/METADATA,sha256=AUp_Ttj2g0gM0u5TINPEfkSnfMepqjqtzZy36Y5fiXw,1028
19
- valetudo_map_parser-0.1.9b5.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
20
- valetudo_map_parser-0.1.9b5.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
21
- valetudo_map_parser-0.1.9b5.dist-info/RECORD,,
14
+ valetudo_map_parser/rand25_handler.py,sha256=vph1BCO0g77kTi18y6sqqJfyJfT5033l9CoxJIDO1Ak,15827
15
+ valetudo_map_parser/reimg_draw.py,sha256=dtdbYKKxmQnbOaHBHayWEF07OdSnTKo2CPSOW0qpgH0,12506
16
+ valetudo_map_parser-0.1.9b6.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
17
+ valetudo_map_parser-0.1.9b6.dist-info/METADATA,sha256=khbAEjQwo2HSh1P9JHBa3OX1tei2MtdgvA2_mWTvvJM,1028
18
+ valetudo_map_parser-0.1.9b6.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
19
+ valetudo_map_parser-0.1.9b6.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
20
+ valetudo_map_parser-0.1.9b6.dist-info/RECORD,,
@@ -1,335 +0,0 @@
1
- """
2
- Image Utils Class for Valetudo Hypfer Image Handling.
3
- This class is used to simplify the ImageHandler class.
4
- Version: 0.1.6
5
- """
6
-
7
- from __future__ import annotations
8
-
9
- import logging
10
-
11
- _LOGGER = logging.getLogger(__name__)
12
-
13
-
14
- class ImageUtils:
15
- """Image Utils Class for Valetudo Hypfer Image Handler.
16
- It is used to simplify the ImageHandler class."""
17
-
18
- def __init__(self, image_handler):
19
- self.img = image_handler
20
- self.file_name = self.img.shared.file_name
21
-
22
- def get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
23
- """Calculate the calibration points based on the rotation angle."""
24
-
25
- # get_calibration_data
26
- vacuum_points = [
27
- {
28
- "x": self.img.crop_area[0] + self.img.offset_x,
29
- "y": self.img.crop_area[1] + self.img.offset_y,
30
- }, # Top-left corner 0
31
- {
32
- "x": self.img.crop_area[2] - self.img.offset_x,
33
- "y": self.img.crop_area[1] + self.img.offset_y,
34
- }, # Top-right corner 1
35
- {
36
- "x": self.img.crop_area[2] - self.img.offset_x,
37
- "y": self.img.crop_area[3] - self.img.offset_y,
38
- }, # Bottom-right corner 2
39
- {
40
- "x": self.img.crop_area[0] + self.img.offset_x,
41
- "y": self.img.crop_area[3] - self.img.offset_y,
42
- }, # Bottom-left corner (optional)3
43
- ]
44
-
45
- # Rotate the vacuum points based on the rotation angle
46
- if rotation_angle == 90:
47
- vacuum_points = [
48
- vacuum_points[1],
49
- vacuum_points[2],
50
- vacuum_points[3],
51
- vacuum_points[0],
52
- ]
53
- elif rotation_angle == 180:
54
- vacuum_points = [
55
- vacuum_points[2],
56
- vacuum_points[3],
57
- vacuum_points[0],
58
- vacuum_points[1],
59
- ]
60
- elif rotation_angle == 270:
61
- vacuum_points = [
62
- vacuum_points[3],
63
- vacuum_points[0],
64
- vacuum_points[1],
65
- vacuum_points[2],
66
- ]
67
-
68
- return vacuum_points
69
-
70
- def re_get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
71
- """Recalculate the calibration points based on the rotation angle.
72
- RAND256 Vacuums Calibration Points are in 10th of a mm."""
73
- vacuum_points = [
74
- {
75
- "x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
76
- "y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
77
- }, # Top-left corner 0
78
- {
79
- "x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
80
- "y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
81
- }, # Top-right corner 1
82
- {
83
- "x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
84
- "y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
85
- }, # Bottom-right corner 2
86
- {
87
- "x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
88
- "y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
89
- }, # Bottom-left corner (optional)3
90
- ]
91
-
92
- # Rotate the vacuum points based on the rotation angle
93
- if rotation_angle == 90:
94
- vacuum_points = [
95
- vacuum_points[1],
96
- vacuum_points[2],
97
- vacuum_points[3],
98
- vacuum_points[0],
99
- ]
100
- elif rotation_angle == 180:
101
- vacuum_points = [
102
- vacuum_points[2],
103
- vacuum_points[3],
104
- vacuum_points[0],
105
- vacuum_points[1],
106
- ]
107
- elif rotation_angle == 270:
108
- vacuum_points = [
109
- vacuum_points[3],
110
- vacuum_points[0],
111
- vacuum_points[1],
112
- vacuum_points[2],
113
- ]
114
-
115
- return vacuum_points
116
-
117
- def set_image_offset_ratio_1_1(
118
- self, width: int, height: int, rand256: bool = False
119
- ) -> None:
120
- """Set the image offset ratio to 1:1."""
121
-
122
- rotation = self.img.shared.image_rotate
123
- if not rand256:
124
- if rotation in [0, 180]:
125
- self.img.offset_y = self.img.crop_img_size[0] - width
126
- self.img.offset_x = (height - self.img.crop_img_size[1]) // 2
127
- elif rotation in [90, 270]:
128
- self.img.offset_y = width - self.img.crop_img_size[0]
129
- self.img.offset_x = (self.img.crop_img_size[1] - height) // 2
130
- else:
131
- if rotation in [0, 180]:
132
- self.img.offset_x = (width - self.img.crop_img_size[0]) // 2
133
- self.img.offset_y = height - self.img.crop_img_size[1]
134
- elif rotation in [90, 270]:
135
- self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
136
- self.img.offset_x = self.img.crop_img_size[1] - height
137
- _LOGGER.debug(
138
- "%s Image Coordinates Offsets (x,y): %s. %s",
139
- self.file_name,
140
- self.img.offset_x,
141
- self.img.offset_y,
142
- )
143
-
144
- def set_image_offset_ratio_2_1(
145
- self, width: int, height: int, rand256: bool = False
146
- ) -> None:
147
- """Set the image offset ratio to 2:1."""
148
-
149
- rotation = self.img.shared.image_rotate
150
- if not rand256:
151
- if rotation in [0, 180]:
152
- self.img.offset_y = width - self.img.crop_img_size[0]
153
- self.img.offset_x = height - self.img.crop_img_size[1]
154
- elif rotation in [90, 270]:
155
- self.img.offset_x = width - self.img.crop_img_size[0]
156
- self.img.offset_y = height - self.img.crop_img_size[1]
157
- else:
158
- if rotation in [0, 180]:
159
- self.img.offset_y = width - self.img.crop_img_size[0]
160
- self.img.offset_x = height - self.img.crop_img_size[1]
161
- elif rotation in [90, 270]:
162
- self.img.offset_x = width - self.img.crop_img_size[0]
163
- self.img.offset_y = height - self.img.crop_img_size[1]
164
-
165
- _LOGGER.debug(
166
- "%s Image Coordinates Offsets (x,y): %s. %s",
167
- self.file_name,
168
- self.img.offset_x,
169
- self.img.offset_y,
170
- )
171
-
172
- def set_image_offset_ratio_3_2(
173
- self, width: int, height: int, rand256: bool = False
174
- ) -> None:
175
- """Set the image offset ratio to 3:2."""
176
-
177
- rotation = self.img.shared.image_rotate
178
-
179
- if not rand256:
180
- if rotation in [0, 180]:
181
- self.img.offset_y = width - self.img.crop_img_size[0]
182
- self.img.offset_x = ((height - self.img.crop_img_size[1]) // 2) - (
183
- self.img.crop_img_size[1] // 10
184
- )
185
- elif rotation in [90, 270]:
186
- self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
187
- self.img.offset_x = (self.img.crop_img_size[1] - height) + (
188
- (height // 10) // 2
189
- )
190
- else:
191
- if rotation in [0, 180]:
192
- self.img.offset_x = (width - self.img.crop_img_size[0]) // 2
193
- self.img.offset_y = height - self.img.crop_img_size[1]
194
- elif rotation in [90, 270]:
195
- self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
196
- self.img.offset_x = self.img.crop_img_size[1] - height
197
-
198
- _LOGGER.debug(
199
- "%s Image Coordinates Offsets (x,y): %s. %s",
200
- self.file_name,
201
- self.img.offset_x,
202
- self.img.offset_y,
203
- )
204
-
205
- def set_image_offset_ratio_5_4(
206
- self, width: int, height: int, rand256: bool = False
207
- ) -> None:
208
- """Set the image offset ratio to 5:4."""
209
-
210
- rotation = self.img.shared.image_rotate
211
- if not rand256:
212
- if rotation in [0, 180]:
213
- self.img.offset_x = ((width - self.img.crop_img_size[0]) // 2) - (
214
- self.img.crop_img_size[0] // 2
215
- )
216
- self.img.offset_y = (self.img.crop_img_size[1] - height) - (
217
- self.img.crop_img_size[1] // 2
218
- )
219
- elif rotation in [90, 270]:
220
- self.img.offset_y = ((self.img.crop_img_size[0] - width) // 2) - 10
221
- self.img.offset_x = (self.img.crop_img_size[1] - height) + (
222
- height // 10
223
- )
224
- else:
225
- if rotation in [0, 180]:
226
- self.img.offset_y = (width - self.img.crop_img_size[0]) // 2
227
- self.img.offset_x = self.img.crop_img_size[1] - height
228
- elif rotation in [90, 270]:
229
- self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
230
- self.img.offset_x = self.img.crop_img_size[1] - height
231
-
232
- _LOGGER.debug(
233
- "%s Image Coordinates Offsets (x,y): %s. %s",
234
- self.file_name,
235
- self.img.offset_x,
236
- self.img.offset_y,
237
- )
238
-
239
- def set_image_offset_ratio_9_16(
240
- self, width: int, height: int, rand256: bool = False
241
- ) -> None:
242
- """Set the image offset ratio to 9:16."""
243
-
244
- rotation = self.img.shared.image_rotate
245
- if not rand256:
246
- if rotation in [0, 180]:
247
- self.img.offset_y = width - self.img.crop_img_size[0]
248
- self.img.offset_x = height - self.img.crop_img_size[1]
249
- elif rotation in [90, 270]:
250
- self.img.offset_x = (width - self.img.crop_img_size[0]) + (height // 10)
251
- self.img.offset_y = height - self.img.crop_img_size[1]
252
- else:
253
- if rotation in [0, 180]:
254
- self.img.offset_y = width - self.img.crop_img_size[0]
255
- self.img.offset_x = height - self.img.crop_img_size[1]
256
- elif rotation in [90, 270]:
257
- self.img.offset_x = width - self.img.crop_img_size[0]
258
- self.img.offset_y = height - self.img.crop_img_size[1]
259
-
260
- _LOGGER.debug(
261
- "%s Image Coordinates Offsets (x,y): %s. %s",
262
- self.file_name,
263
- self.img.offset_x,
264
- self.img.offset_y,
265
- )
266
-
267
- def set_image_offset_ratio_16_9(
268
- self, width: int, height: int, rand256: bool = False
269
- ) -> None:
270
- """Set the image offset ratio to 16:9."""
271
-
272
- rotation = self.img.shared.image_rotate
273
- if not rand256:
274
- if rotation in [0, 180]:
275
- self.img.offset_y = width - self.img.crop_img_size[0]
276
- self.img.offset_x = height - self.img.crop_img_size[1]
277
- elif rotation in [90, 270]:
278
- self.img.offset_x = width - self.img.crop_img_size[0]
279
- self.img.offset_y = height - self.img.crop_img_size[1]
280
- else:
281
- if rotation in [0, 180]:
282
- self.img.offset_y = width - self.img.crop_img_size[0]
283
- self.img.offset_x = height - self.img.crop_img_size[1]
284
- elif rotation in [90, 270]:
285
- self.img.offset_x = width - self.img.crop_img_size[0]
286
- self.img.offset_y = height - self.img.crop_img_size[1]
287
-
288
- _LOGGER.debug(
289
- "%s Image Coordinates Offsets (x,y): %s. %s",
290
- self.file_name,
291
- self.img.offset_x,
292
- self.img.offset_y,
293
- )
294
-
295
- async def async_zone_propriety(self, zones_data) -> dict:
296
- """Get the zone propriety"""
297
- zone_properties = {}
298
- id_count = 1
299
- for zone in zones_data:
300
- zone_name = zone.get("name")
301
- coordinates = zone.get("coordinates")
302
- if coordinates and len(coordinates) > 0:
303
- coordinates[0].pop()
304
- x1, y1, x2, y2 = coordinates[0]
305
- zone_properties[zone_name] = {
306
- "zones": coordinates,
307
- "name": zone_name,
308
- "x": ((x1 + x2) // 2),
309
- "y": ((y1 + y2) // 2),
310
- }
311
- id_count += 1
312
- if id_count > 1:
313
- _LOGGER.debug("%s: Zones Properties updated.", self.file_name)
314
- return zone_properties
315
-
316
- async def async_points_propriety(self, points_data) -> dict:
317
- """Get the point propriety"""
318
- point_properties = {}
319
- id_count = 1
320
- for point in points_data:
321
- point_name = point.get("name")
322
- coordinates = point.get("coordinates")
323
- if coordinates and len(coordinates) > 0:
324
- coordinates = point.get("coordinates")
325
- x1, y1 = coordinates
326
- point_properties[id_count] = {
327
- "position": coordinates,
328
- "name": point_name,
329
- "x": x1,
330
- "y": y1,
331
- }
332
- id_count += 1
333
- if id_count > 1:
334
- _LOGGER.debug("%s: Point Properties updated.", self.file_name)
335
- return point_properties