valetudo-map-parser 0.1.9b40__py3-none-any.whl → 0.1.9b42__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.
@@ -0,0 +1,312 @@
1
+ """
2
+ Drawable Elements Configuration.
3
+ Defines the elements that can be drawn on the map and their properties.
4
+ Version: 0.1.9
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import logging
10
+ from enum import IntEnum
11
+ from typing import Dict, List, Tuple, Union
12
+
13
+ from .colors import DefaultColors, SupportedColor
14
+
15
+
16
+ # numpy is not used in this file
17
+
18
+
19
+ _LOGGER = logging.getLogger(__name__)
20
+
21
+ # Type aliases
22
+ Color = Tuple[int, int, int, int] # RGBA color
23
+ PropertyDict = Dict[str, Union[Color, float, int]]
24
+
25
+
26
+ class DrawableElement(IntEnum):
27
+ """Enumeration of drawable map elements with unique integer codes."""
28
+
29
+ # Base elements
30
+ FLOOR = 1
31
+ WALL = 2
32
+ ROBOT = 3
33
+ CHARGER = 4
34
+ VIRTUAL_WALL = 5
35
+ RESTRICTED_AREA = 6
36
+ NO_MOP_AREA = 7
37
+ OBSTACLE = 8
38
+ PATH = 9
39
+ PREDICTED_PATH = 10
40
+ GO_TO_TARGET = 11
41
+
42
+ # Rooms (101-115 for up to 15 rooms)
43
+ ROOM_1 = 101
44
+ ROOM_2 = 102
45
+ ROOM_3 = 103
46
+ ROOM_4 = 104
47
+ ROOM_5 = 105
48
+ ROOM_6 = 106
49
+ ROOM_7 = 107
50
+ ROOM_8 = 108
51
+ ROOM_9 = 109
52
+ ROOM_10 = 110
53
+ ROOM_11 = 111
54
+ ROOM_12 = 112
55
+ ROOM_13 = 113
56
+ ROOM_14 = 114
57
+ ROOM_15 = 115
58
+
59
+
60
+ class DrawingConfig:
61
+ """Configuration for which elements to draw and their properties."""
62
+
63
+ def __init__(self):
64
+ """Initialize with all elements enabled by default."""
65
+ # Dictionary of element_code -> enabled status
66
+ self._enabled_elements = {element: True for element in DrawableElement}
67
+
68
+ # Dictionary of element_code -> drawing properties (color, opacity, etc.)
69
+ self._element_properties: Dict[DrawableElement, PropertyDict] = {}
70
+
71
+ # Initialize default properties
72
+ self._set_default_properties()
73
+
74
+ def _set_default_properties(self):
75
+ """Set default drawing properties for each element."""
76
+ # Set properties for rooms using DefaultColors
77
+ for room_id in range(1, 16):
78
+ room_element = getattr(DrawableElement, f"ROOM_{room_id}")
79
+ room_key = SupportedColor.room_key(room_id - 1)
80
+ rgb = DefaultColors.DEFAULT_ROOM_COLORS.get(room_key, (135, 206, 250))
81
+ alpha = DefaultColors.DEFAULT_ALPHA.get(f"alpha_room_{room_id - 1}", 255.0)
82
+
83
+ self._element_properties[room_element] = {
84
+ "color": (*rgb, int(alpha)),
85
+ "opacity": alpha / 255.0,
86
+ "z_index": 10, # Drawing order
87
+ }
88
+
89
+ # Map DrawableElement to SupportedColor
90
+ element_color_mapping = {
91
+ DrawableElement.FLOOR: SupportedColor.MAP_BACKGROUND,
92
+ DrawableElement.WALL: SupportedColor.WALLS,
93
+ DrawableElement.ROBOT: SupportedColor.ROBOT,
94
+ DrawableElement.CHARGER: SupportedColor.CHARGER,
95
+ DrawableElement.VIRTUAL_WALL: SupportedColor.NO_GO,
96
+ DrawableElement.RESTRICTED_AREA: SupportedColor.NO_GO,
97
+ DrawableElement.PATH: SupportedColor.PATH,
98
+ DrawableElement.PREDICTED_PATH: SupportedColor.PREDICTED_PATH,
99
+ DrawableElement.GO_TO_TARGET: SupportedColor.GO_TO,
100
+ DrawableElement.NO_MOP_AREA: SupportedColor.NO_GO, # Using NO_GO for no-mop areas
101
+ DrawableElement.OBSTACLE: SupportedColor.NO_GO, # Using NO_GO for obstacles
102
+ }
103
+
104
+ # Set z-index for each element type
105
+ z_indices = {
106
+ DrawableElement.FLOOR: 0,
107
+ DrawableElement.WALL: 20,
108
+ DrawableElement.ROBOT: 50,
109
+ DrawableElement.CHARGER: 40,
110
+ DrawableElement.VIRTUAL_WALL: 30,
111
+ DrawableElement.RESTRICTED_AREA: 25,
112
+ DrawableElement.NO_MOP_AREA: 25,
113
+ DrawableElement.OBSTACLE: 15,
114
+ DrawableElement.PATH: 35,
115
+ DrawableElement.PREDICTED_PATH: 34,
116
+ DrawableElement.GO_TO_TARGET: 45,
117
+ }
118
+
119
+ # Set properties for other elements using DefaultColors
120
+ for element, color_key in element_color_mapping.items():
121
+ rgb = DefaultColors.COLORS_RGB.get(color_key, (0, 0, 0))
122
+ alpha_key = f"alpha_{color_key}"
123
+ alpha = DefaultColors.DEFAULT_ALPHA.get(alpha_key, 255.0)
124
+
125
+ # Special case for semi-transparent elements
126
+ if element in [
127
+ DrawableElement.RESTRICTED_AREA,
128
+ DrawableElement.NO_MOP_AREA,
129
+ DrawableElement.PREDICTED_PATH,
130
+ ]:
131
+ alpha = 125.0 # Semi-transparent by default
132
+
133
+ self._element_properties[element] = {
134
+ "color": (*rgb, int(alpha)),
135
+ "opacity": alpha / 255.0,
136
+ "z_index": z_indices.get(element, 0),
137
+ }
138
+
139
+ def enable_element(self, element_code: DrawableElement) -> None:
140
+ """Enable drawing of a specific element."""
141
+ if element_code in self._enabled_elements:
142
+ self._enabled_elements[element_code] = True
143
+ _LOGGER.info(
144
+ "Enabled element %s (%s)", element_code.name, element_code.value
145
+ )
146
+ _LOGGER.info(
147
+ "Element %s is now enabled: %s",
148
+ element_code.name,
149
+ self._enabled_elements[element_code],
150
+ )
151
+
152
+ def disable_element(self, element_code: DrawableElement) -> None:
153
+ """Disable drawing of a specific element."""
154
+ if element_code in self._enabled_elements:
155
+ self._enabled_elements[element_code] = False
156
+ _LOGGER.info(
157
+ "Disabled element %s (%s)", element_code.name, element_code.value
158
+ )
159
+ _LOGGER.info(
160
+ "Element %s is now enabled: %s",
161
+ element_code.name,
162
+ self._enabled_elements[element_code],
163
+ )
164
+
165
+ def set_elements(self, element_codes: List[DrawableElement]) -> None:
166
+ """Enable only the specified elements, disable all others."""
167
+ # First disable all
168
+ for element in self._enabled_elements:
169
+ self._enabled_elements[element] = False
170
+
171
+ # Then enable specified ones
172
+ for element in element_codes:
173
+ if element in self._enabled_elements:
174
+ self._enabled_elements[element] = True
175
+
176
+ def is_enabled(self, element_code: DrawableElement) -> bool:
177
+ """Check if an element is enabled for drawing."""
178
+ enabled = self._enabled_elements.get(element_code, False)
179
+ _LOGGER.debug(
180
+ "Checking if element %s is enabled: %s",
181
+ element_code.name if hasattr(element_code, "name") else element_code,
182
+ enabled,
183
+ )
184
+ return enabled
185
+
186
+ def set_property(
187
+ self, element_code: DrawableElement, property_name: str, value
188
+ ) -> None:
189
+ """Set a drawing property for an element."""
190
+ if element_code in self._element_properties:
191
+ self._element_properties[element_code][property_name] = value
192
+
193
+ def get_property(
194
+ self, element_code: DrawableElement, property_name: str, default=None
195
+ ):
196
+ """Get a drawing property for an element."""
197
+ if element_code in self._element_properties:
198
+ return self._element_properties[element_code].get(property_name, default)
199
+ return default
200
+
201
+ def get_enabled_elements(self) -> List[DrawableElement]:
202
+ """Get list of enabled element codes."""
203
+ return [
204
+ element for element, enabled in self._enabled_elements.items() if enabled
205
+ ]
206
+
207
+ def get_drawing_order(self) -> List[DrawableElement]:
208
+ """Get list of enabled elements in drawing order (by z_index)."""
209
+ enabled = self.get_enabled_elements()
210
+ return sorted(enabled, key=lambda e: self.get_property(e, "z_index", 0))
211
+
212
+ def update_from_device_info(self, device_info: dict) -> None:
213
+ """Update configuration based on device info dictionary."""
214
+ # Map DrawableElement to SupportedColor
215
+ element_color_mapping = {
216
+ DrawableElement.FLOOR: SupportedColor.MAP_BACKGROUND,
217
+ DrawableElement.WALL: SupportedColor.WALLS,
218
+ DrawableElement.ROBOT: SupportedColor.ROBOT,
219
+ DrawableElement.CHARGER: SupportedColor.CHARGER,
220
+ DrawableElement.VIRTUAL_WALL: SupportedColor.NO_GO,
221
+ DrawableElement.RESTRICTED_AREA: SupportedColor.NO_GO,
222
+ DrawableElement.PATH: SupportedColor.PATH,
223
+ DrawableElement.PREDICTED_PATH: SupportedColor.PREDICTED_PATH,
224
+ DrawableElement.GO_TO_TARGET: SupportedColor.GO_TO,
225
+ DrawableElement.NO_MOP_AREA: SupportedColor.NO_GO,
226
+ DrawableElement.OBSTACLE: SupportedColor.NO_GO,
227
+ }
228
+
229
+ # Update room colors from device info
230
+ for room_id in range(1, 16):
231
+ room_element = getattr(DrawableElement, f"ROOM_{room_id}")
232
+ color_key = SupportedColor.room_key(room_id - 1)
233
+ alpha_key = f"alpha_room_{room_id - 1}"
234
+
235
+ if color_key in device_info:
236
+ rgb = device_info[color_key]
237
+ alpha = device_info.get(alpha_key, 255.0)
238
+
239
+ # Create RGBA color
240
+ rgba = (*rgb, int(alpha))
241
+
242
+ # Update color and opacity
243
+ self.set_property(room_element, "color", rgba)
244
+ self.set_property(room_element, "opacity", alpha / 255.0)
245
+
246
+ _LOGGER.debug(
247
+ "Updated room %d color to %s with alpha %s", room_id, rgb, alpha
248
+ )
249
+
250
+ # Update other element colors
251
+ for element, color_key in element_color_mapping.items():
252
+ if color_key in device_info:
253
+ rgb = device_info[color_key]
254
+ alpha_key = f"alpha_{color_key}"
255
+ alpha = device_info.get(alpha_key, 255.0)
256
+
257
+ # Special case for semi-transparent elements
258
+ if element in [
259
+ DrawableElement.RESTRICTED_AREA,
260
+ DrawableElement.NO_MOP_AREA,
261
+ DrawableElement.PREDICTED_PATH,
262
+ ]:
263
+ if alpha > 200: # If alpha is too high for these elements
264
+ alpha = 125.0 # Use a more appropriate default
265
+
266
+ # Create RGBA color
267
+ rgba = (*rgb, int(alpha))
268
+
269
+ # Update color and opacity
270
+ self.set_property(element, "color", rgba)
271
+ self.set_property(element, "opacity", alpha / 255.0)
272
+
273
+ _LOGGER.debug(
274
+ "Updated element %s color to %s with alpha %s",
275
+ element.name,
276
+ rgb,
277
+ alpha,
278
+ )
279
+
280
+ # Check for disabled elements using specific boolean flags
281
+ # Map element disable flags to DrawableElement enum values
282
+ element_disable_mapping = {
283
+ "disable_floor": DrawableElement.FLOOR,
284
+ "disable_wall": DrawableElement.WALL,
285
+ "disable_robot": DrawableElement.ROBOT,
286
+ "disable_charger": DrawableElement.CHARGER,
287
+ "disable_virtual_walls": DrawableElement.VIRTUAL_WALL,
288
+ "disable_restricted_areas": DrawableElement.RESTRICTED_AREA,
289
+ "disable_no_mop_areas": DrawableElement.NO_MOP_AREA,
290
+ "disable_obstacles": DrawableElement.OBSTACLE,
291
+ "disable_path": DrawableElement.PATH,
292
+ "disable_predicted_path": DrawableElement.PREDICTED_PATH,
293
+ "disable_go_to_target": DrawableElement.GO_TO_TARGET,
294
+ }
295
+
296
+ # Process base element disable flags
297
+ for disable_key, element in element_disable_mapping.items():
298
+ if device_info.get(disable_key, False):
299
+ self.disable_element(element)
300
+ _LOGGER.info(
301
+ "Disabled %s element from device_info setting", element.name
302
+ )
303
+
304
+ # Process room disable flags (1-15)
305
+ for room_id in range(1, 16):
306
+ disable_key = f"disable_room_{room_id}"
307
+ if device_info.get(disable_key, False):
308
+ room_element = getattr(DrawableElement, f"ROOM_{room_id}")
309
+ self.disable_element(room_element)
310
+ _LOGGER.info(
311
+ "Disabled ROOM_%d element from device_info setting", room_id
312
+ )