valetudo-map-parser 0.1.8__py3-none-any.whl → 0.1.9a0__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.
Files changed (30) hide show
  1. valetudo_map_parser/__init__.py +28 -13
  2. valetudo_map_parser/config/async_utils.py +93 -0
  3. valetudo_map_parser/config/auto_crop.py +312 -123
  4. valetudo_map_parser/config/color_utils.py +105 -0
  5. valetudo_map_parser/config/colors.py +662 -13
  6. valetudo_map_parser/config/drawable.py +613 -268
  7. valetudo_map_parser/config/drawable_elements.py +292 -0
  8. valetudo_map_parser/config/enhanced_drawable.py +324 -0
  9. valetudo_map_parser/config/optimized_element_map.py +406 -0
  10. valetudo_map_parser/config/rand256_parser.py +395 -0
  11. valetudo_map_parser/config/shared.py +94 -11
  12. valetudo_map_parser/config/types.py +105 -52
  13. valetudo_map_parser/config/utils.py +1025 -0
  14. valetudo_map_parser/hypfer_draw.py +464 -148
  15. valetudo_map_parser/hypfer_handler.py +366 -259
  16. valetudo_map_parser/hypfer_rooms_handler.py +599 -0
  17. valetudo_map_parser/map_data.py +56 -66
  18. valetudo_map_parser/rand256_handler.py +674 -0
  19. valetudo_map_parser/reimg_draw.py +68 -84
  20. valetudo_map_parser/rooms_handler.py +474 -0
  21. valetudo_map_parser-0.1.9a0.dist-info/METADATA +93 -0
  22. valetudo_map_parser-0.1.9a0.dist-info/RECORD +27 -0
  23. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a0.dist-info}/WHEEL +1 -1
  24. valetudo_map_parser/config/rand25_parser.py +0 -398
  25. valetudo_map_parser/images_utils.py +0 -398
  26. valetudo_map_parser/rand25_handler.py +0 -455
  27. valetudo_map_parser-0.1.8.dist-info/METADATA +0 -23
  28. valetudo_map_parser-0.1.8.dist-info/RECORD +0 -20
  29. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a0.dist-info}/LICENSE +0 -0
  30. {valetudo_map_parser-0.1.8.dist-info → valetudo_map_parser-0.1.9a0.dist-info}/NOTICE.txt +0 -0
@@ -4,29 +4,27 @@ Version 0.0.1
4
4
  """
5
5
 
6
6
  import asyncio
7
- from dataclasses import dataclass
8
7
  import json
9
8
  import logging
10
- from typing import Any, Dict, Tuple, Union
9
+ import threading
10
+ from dataclasses import asdict, dataclass
11
+ from typing import Any, Dict, Optional, Tuple, TypedDict, Union
11
12
 
12
- from PIL import Image
13
13
  import numpy as np
14
+ from PIL import Image
15
+
14
16
 
15
17
  DEFAULT_ROOMS = 1
16
18
 
17
- MY_LOGGER = logging.getLogger(__name__)
19
+ LOGGER = logging.getLogger(__package__)
18
20
 
19
- Color = Union[Tuple[int, int, int], Tuple[int, int, int, int]]
20
- Colors = Dict[str, Color]
21
- CalibrationPoints = list[dict[str, Any]]
22
- RobotPosition = dict[str, int | float]
23
- ChargerPosition = dict[str, Any]
24
- RoomsProperties = dict[str, dict[str, int | list[tuple[Any, Any]]]]
25
- ImageSize = dict[str, int | list[int]]
26
- JsonType = Any # json.loads() return type is Any
27
- PilPNG = Image.Image
28
- NumpyArray = np.ndarray
29
- Point = Tuple[int, int]
21
+
22
+ class RoomProperty(TypedDict):
23
+ number: int
24
+ outline: list[tuple[int, int]]
25
+ name: str
26
+ x: int
27
+ y: int
30
28
 
31
29
 
32
30
  # pylint: disable=no-member
@@ -73,43 +71,37 @@ class TrimCropData:
73
71
  )
74
72
 
75
73
 
76
- # pylint: disable=no-member
77
74
  class RoomStore:
78
- """Store the room data for the vacuum."""
79
-
80
- _instance = None
81
- _lock = asyncio.Lock()
82
-
83
- def __init__(self):
84
- self.vacuums_data = {}
85
-
86
- def __new__(cls):
87
- if cls._instance is None:
88
- cls._instance = super(RoomStore, cls).__new__(cls)
89
- cls._instance.vacuums_data = {}
90
- return cls._instance
91
-
92
- async def async_set_rooms_data(self, vacuum_id: str, rooms_data: dict) -> None:
93
- """Set the room data for the vacuum."""
94
- async with self._lock:
95
- self.vacuums_data[vacuum_id] = rooms_data
75
+ _instances: Dict[str, "RoomStore"] = {}
76
+ _lock = threading.Lock()
77
+
78
+ def __new__(cls, vacuum_id: str, rooms_data: Optional[dict] = None) -> "RoomStore":
79
+ with cls._lock:
80
+ if vacuum_id not in cls._instances:
81
+ instance = super(RoomStore, cls).__new__(cls)
82
+ instance.vacuum_id = vacuum_id
83
+ instance.vacuums_data = rooms_data or {}
84
+ cls._instances[vacuum_id] = instance
85
+ else:
86
+ if rooms_data is not None:
87
+ cls._instances[vacuum_id].vacuums_data = rooms_data
88
+ return cls._instances[vacuum_id]
89
+
90
+ def get_rooms(self) -> dict:
91
+ return self.vacuums_data
92
+
93
+ def set_rooms(self, rooms_data: dict) -> None:
94
+ self.vacuums_data = rooms_data
95
+
96
+ def get_rooms_count(self) -> int:
97
+ if isinstance(self.vacuums_data, dict):
98
+ count = len(self.vacuums_data)
99
+ return count if count > 0 else DEFAULT_ROOMS
100
+ return DEFAULT_ROOMS
96
101
 
97
- async def async_get_rooms_data(self, vacuum_id: str) -> dict:
98
- """Get the room data for a vacuum."""
99
- async with self._lock:
100
- data = self.vacuums_data.get(vacuum_id, {})
101
- if isinstance(data, str):
102
- json_data = json.loads(data)
103
- return json_data
104
- return data
105
-
106
- async def async_get_rooms_count(self, vacuum_id: str) -> int:
107
- """Count the number of rooms for a vacuum."""
108
- async with self._lock:
109
- count = len(self.vacuums_data.get(vacuum_id, {}))
110
- if count == 0:
111
- return DEFAULT_ROOMS
112
- return count
102
+ @classmethod
103
+ def get_all_instances(cls) -> Dict[str, "RoomStore"]:
104
+ return cls._instances
113
105
 
114
106
 
115
107
  # pylint: disable=no-member
@@ -202,8 +194,20 @@ class SnapshotStore:
202
194
  self.vacuum_json_data[vacuum_id] = json_data
203
195
 
204
196
 
197
+ Color = Union[Tuple[int, int, int], Tuple[int, int, int, int]]
198
+ Colors = Dict[str, Color]
199
+ CalibrationPoints = list[dict[str, Any]]
200
+ RobotPosition = dict[str, int | float]
201
+ ChargerPosition = dict[str, Any]
202
+ RoomsProperties = dict[str, RoomProperty]
203
+ ImageSize = dict[str, int | list[int]]
204
+ JsonType = Any # json.loads() return type is Any
205
+ PilPNG = Image.Image # Keep for backward compatibility
206
+ WebPBytes = bytes # WebP image as bytes
207
+ NumpyArray = np.ndarray
208
+ Point = Tuple[int, int]
209
+
205
210
  CAMERA_STORAGE = "valetudo_camera"
206
- DEFAULT_ROOMS = 1 # 15 is the maximum number of rooms.
207
211
  ATTR_ROTATE = "rotate_image"
208
212
  ATTR_CROP = "crop_image"
209
213
  ATTR_MARGINS = "margins"
@@ -284,6 +288,7 @@ DEFAULT_VALUES = {
284
288
  "vac_status_position": True,
285
289
  "get_svg_file": False,
286
290
  "save_trims": True,
291
+ "trims_data": {"trim_left": 0, "trim_up": 0, "trim_right": 0, "trim_down": 0},
287
292
  "enable_www_snapshots": False,
288
293
  "color_charger": [255, 128, 0],
289
294
  "color_move": [238, 247, 255],
@@ -345,6 +350,7 @@ KEYS_TO_UPDATE = [
345
350
  "offset_bottom",
346
351
  "offset_left",
347
352
  "offset_right",
353
+ "trims_data",
348
354
  "auto_zoom",
349
355
  "zoom_lock_ratio",
350
356
  "show_vac_status",
@@ -562,7 +568,8 @@ ALPHA_ROOM_15 = "alpha_room_15"
562
568
 
563
569
  """ Constants for the attribute keys """
564
570
  ATTR_FRIENDLY_NAME = "friendly_name"
565
- ATTR_VACUUM_BATTERY = "vacuum_battery"
571
+ ATTR_VACUUM_BATTERY = "battery"
572
+ ATTR_VACUUM_CHARGING = "charging"
566
573
  ATTR_VACUUM_POSITION = "vacuum_position"
567
574
  ATTR_VACUUM_TOPIC = "vacuum_topic"
568
575
  ATTR_VACUUM_STATUS = "vacuum_status"
@@ -588,3 +595,49 @@ class CameraModes:
588
595
  CAMERA_STANDBY = "camera_standby"
589
596
  CAMERA_OFF = False
590
597
  CAMERA_ON = True
598
+
599
+
600
+ # noinspection PyTypeChecker
601
+ @dataclass
602
+ class TrimsData:
603
+ """Dataclass to store and manage trims data."""
604
+
605
+ floor: str = ""
606
+ trim_up: int = 0
607
+ trim_left: int = 0
608
+ trim_down: int = 0
609
+ trim_right: int = 0
610
+
611
+ @classmethod
612
+ def from_json(cls, json_data: str):
613
+ """Create a TrimsConfig instance from a JSON string."""
614
+ data = json.loads(json_data)
615
+ return cls(
616
+ floor=data.get("floor", ""),
617
+ trim_up=data.get("trim_up", 0),
618
+ trim_left=data.get("trim_left", 0),
619
+ trim_down=data.get("trim_down", 0),
620
+ trim_right=data.get("trim_right", 0),
621
+ )
622
+
623
+ def to_json(self) -> str:
624
+ """Convert TrimsConfig instance to a JSON string."""
625
+ return json.dumps(asdict(self))
626
+
627
+ @classmethod
628
+ def from_dict(cls, data: dict):
629
+ """Initialize TrimData from a dictionary."""
630
+ return cls(**data)
631
+
632
+ def to_dict(self) -> dict:
633
+ """Convert TrimData to a dictionary."""
634
+ return asdict(self)
635
+
636
+ def clear(self) -> dict:
637
+ """Clear all the trims."""
638
+ self.floor = ""
639
+ self.trim_up = 0
640
+ self.trim_left = 0
641
+ self.trim_down = 0
642
+ self.trim_right = 0
643
+ return asdict(self)