valetudo-map-parser 0.1.9b41__tar.gz → 0.1.9b42__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 (26) hide show
  1. valetudo_map_parser-0.1.9b42/PKG-INFO +92 -0
  2. valetudo_map_parser-0.1.9b42/README.md +71 -0
  3. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/__init__.py +6 -3
  4. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/drawable.py +22 -2
  5. valetudo_map_parser-0.1.9b42/SCR/valetudo_map_parser/config/drawable_elements.py +312 -0
  6. valetudo_map_parser-0.1.9b42/SCR/valetudo_map_parser/config/enhanced_drawable.py +447 -0
  7. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/shared.py +27 -0
  8. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/types.py +2 -1
  9. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/utils.py +410 -1
  10. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/hypfer_draw.py +194 -60
  11. valetudo_map_parser-0.1.9b42/SCR/valetudo_map_parser/hypfer_handler.py +593 -0
  12. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/rand25_handler.py +223 -38
  13. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/pyproject.toml +2 -2
  14. valetudo_map_parser-0.1.9b41/PKG-INFO +0 -47
  15. valetudo_map_parser-0.1.9b41/README.md +0 -26
  16. valetudo_map_parser-0.1.9b41/SCR/valetudo_map_parser/hypfer_handler.py +0 -289
  17. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/LICENSE +0 -0
  18. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/NOTICE.txt +0 -0
  19. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/__init__.py +0 -0
  20. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/auto_crop.py +0 -0
  21. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/colors.py +0 -0
  22. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/colors_man.py +0 -0
  23. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/config/rand25_parser.py +0 -0
  24. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/map_data.py +0 -0
  25. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/py.typed +0 -0
  26. {valetudo_map_parser-0.1.9b41 → valetudo_map_parser-0.1.9b42}/SCR/valetudo_map_parser/reimg_draw.py +0 -0
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.3
2
+ Name: valetudo-map-parser
3
+ Version: 0.1.9b42
4
+ Summary: A Python library to parse Valetudo map data returning a PIL Image object.
5
+ License: Apache-2.0
6
+ Author: Sandro Cantarella
7
+ Author-email: gsca075@gmail.com
8
+ Requires-Python: >=3.12
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: Pillow (>=10.3.0)
14
+ Requires-Dist: numpy (>=1.26.4)
15
+ Project-URL: Bug Tracker, https://github.com/sca075/Python-package-valetudo-map-parser/issues
16
+ Project-URL: Changelog, https://github.com/sca075/Python-package-valetudo-map-parser/releases
17
+ Project-URL: Homepage, https://github.com/sca075/Python-package-valetudo-map-parser
18
+ Project-URL: Repository, https://github.com/sca075/Python-package-valetudo-map-parser
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Python-package-valetudo-map-parser
22
+
23
+ ---
24
+ ### What is it:
25
+ ❗This is an _unofficial_ project and is not created, maintained, or in any sense linked to [valetudo.cloud](https://valetudo.cloud)
26
+
27
+ A Python library that converts Valetudo vacuum JSON map data into PIL (Python Imaging Library) images. This package is primarily developed for and used in the [MQTT Vacuum Camera](https://github.com/sca075/mqtt_vacuum_camera) project.
28
+
29
+ ---
30
+
31
+ ### Features:
32
+ - Processes map data from Valetudo-compatible robot vacuums
33
+ - Supports both Hypfer and Rand256 vacuum data formats
34
+ - Renders comprehensive map visualizations including:
35
+ - Walls and obstacles
36
+ - Robot position and cleaning path
37
+ - Room segments and boundaries
38
+ - Cleaning zones
39
+ - Virtual restrictions
40
+ - LiDAR data
41
+ - Provides auto-cropping and dynamic zooming
42
+ - Supports image rotation and aspect ratio management
43
+ - Enables custom color schemes
44
+ - Handles multilingual labels
45
+ - Implements thread-safe data sharing
46
+
47
+ ### Installation:
48
+ ```bash
49
+ pip install valetudo_map_parser
50
+ ```
51
+
52
+ ### Requirements:
53
+ - Python 3.12 or higher
54
+ - Dependencies:
55
+ - Pillow (PIL) for image processing
56
+ - NumPy for array operations
57
+
58
+ ### Usage:
59
+ The library is configured using a dictionary format. See our [sample code](https://github.com/sca075/Python-package-valetudo-map-parser/blob/main/tests/test.py) for implementation examples.
60
+
61
+ Key functionalities:
62
+ - Decodes raw data from Rand256 format
63
+ - Processes JSON data from compatible vacuums
64
+ - Returns Pillow PNG images
65
+ - Provides calibration and room property extraction
66
+ - Supports asynchronous operations
67
+
68
+ ### Development Status:
69
+ Current version: 0.1.9.b41
70
+ - Full functionality available in versions >= 0.1.9
71
+ - Actively maintained and enhanced
72
+ - Uses Poetry for dependency management
73
+ - Implements comprehensive testing
74
+ - Enforces code quality through ruff, isort, and pylint
75
+
76
+ ### Contributing:
77
+ Contributions are welcome! You can help by:
78
+ - Submitting code improvements
79
+ - Enhancing documentation
80
+ - Reporting issues
81
+ - Suggesting new features
82
+
83
+ ### Disclaimer:
84
+ This project is provided "as is" without warranty of any kind. Users assume all risks associated with its use.
85
+
86
+ ### License:
87
+ Apache-2.0
88
+
89
+ ---
90
+ For more information about Valetudo, visit [valetudo.cloud](https://valetudo.cloud)
91
+ Integration with Home Assistant: [MQTT Vacuum Camera](https://github.com/sca075/mqtt_vacuum_camera)
92
+
@@ -0,0 +1,71 @@
1
+ # Python-package-valetudo-map-parser
2
+
3
+ ---
4
+ ### What is it:
5
+ ❗This is an _unofficial_ project and is not created, maintained, or in any sense linked to [valetudo.cloud](https://valetudo.cloud)
6
+
7
+ A Python library that converts Valetudo vacuum JSON map data into PIL (Python Imaging Library) images. This package is primarily developed for and used in the [MQTT Vacuum Camera](https://github.com/sca075/mqtt_vacuum_camera) project.
8
+
9
+ ---
10
+
11
+ ### Features:
12
+ - Processes map data from Valetudo-compatible robot vacuums
13
+ - Supports both Hypfer and Rand256 vacuum data formats
14
+ - Renders comprehensive map visualizations including:
15
+ - Walls and obstacles
16
+ - Robot position and cleaning path
17
+ - Room segments and boundaries
18
+ - Cleaning zones
19
+ - Virtual restrictions
20
+ - LiDAR data
21
+ - Provides auto-cropping and dynamic zooming
22
+ - Supports image rotation and aspect ratio management
23
+ - Enables custom color schemes
24
+ - Handles multilingual labels
25
+ - Implements thread-safe data sharing
26
+
27
+ ### Installation:
28
+ ```bash
29
+ pip install valetudo_map_parser
30
+ ```
31
+
32
+ ### Requirements:
33
+ - Python 3.12 or higher
34
+ - Dependencies:
35
+ - Pillow (PIL) for image processing
36
+ - NumPy for array operations
37
+
38
+ ### Usage:
39
+ The library is configured using a dictionary format. See our [sample code](https://github.com/sca075/Python-package-valetudo-map-parser/blob/main/tests/test.py) for implementation examples.
40
+
41
+ Key functionalities:
42
+ - Decodes raw data from Rand256 format
43
+ - Processes JSON data from compatible vacuums
44
+ - Returns Pillow PNG images
45
+ - Provides calibration and room property extraction
46
+ - Supports asynchronous operations
47
+
48
+ ### Development Status:
49
+ Current version: 0.1.9.b41
50
+ - Full functionality available in versions >= 0.1.9
51
+ - Actively maintained and enhanced
52
+ - Uses Poetry for dependency management
53
+ - Implements comprehensive testing
54
+ - Enforces code quality through ruff, isort, and pylint
55
+
56
+ ### Contributing:
57
+ Contributions are welcome! You can help by:
58
+ - Submitting code improvements
59
+ - Enhancing documentation
60
+ - Reporting issues
61
+ - Suggesting new features
62
+
63
+ ### Disclaimer:
64
+ This project is provided "as is" without warranty of any kind. Users assume all risks associated with its use.
65
+
66
+ ### License:
67
+ Apache-2.0
68
+
69
+ ---
70
+ For more information about Valetudo, visit [valetudo.cloud](https://valetudo.cloud)
71
+ Integration with Home Assistant: [MQTT Vacuum Camera](https://github.com/sca075/mqtt_vacuum_camera)
@@ -1,8 +1,10 @@
1
1
  """Valetudo map parser.
2
- Version: 0.1.8"""
2
+ Version: 0.1.9"""
3
3
 
4
4
  from .config.colors import ColorsManagment
5
5
  from .config.drawable import Drawable
6
+ from .config.drawable_elements import DrawableElement, DrawingConfig
7
+ from .config.enhanced_drawable import EnhancedDrawable
6
8
  from .config.rand25_parser import RRMapParser
7
9
  from .config.shared import CameraShared, CameraSharedManager
8
10
  from .config.types import (
@@ -25,10 +27,11 @@ __all__ = [
25
27
  "CameraSharedManager",
26
28
  "ColorsManagment",
27
29
  "Drawable",
30
+ "DrawableElement",
31
+ "DrawingConfig",
32
+ "EnhancedDrawable",
28
33
  "SnapshotStore",
29
34
  "UserLanguageStore",
30
- "UserLanguageStore",
31
- "SnapshotStore",
32
35
  "RoomStore",
33
36
  "RoomsProperties",
34
37
  "TrimCropData",
@@ -10,14 +10,20 @@ Refactored for clarity, consistency, and optimized parameter usage.
10
10
  from __future__ import annotations
11
11
 
12
12
  import asyncio
13
+ import logging
13
14
  import math
14
15
 
16
+ # cv2 is imported but not used directly in this file
17
+ # It's needed for other modules that import from here
15
18
  import numpy as np
16
19
  from PIL import ImageDraw, ImageFont
17
20
 
18
21
  from .types import Color, NumpyArray, PilPNG, Point, Tuple, Union
19
22
 
20
23
 
24
+ _LOGGER = logging.getLogger(__name__)
25
+
26
+
21
27
  class Drawable:
22
28
  """
23
29
  Collection of drawing utility functions for the image handlers.
@@ -47,16 +53,30 @@ class Drawable:
47
53
  ) -> NumpyArray:
48
54
  """Draw the layers (rooms) from the vacuum JSON data onto the image array."""
49
55
  image_array = layer
56
+ # Extract alpha from color
57
+ alpha = color[3] if len(color) == 4 else 255
58
+
59
+ # For debugging
60
+ _LOGGER.debug("Drawing with color %s and alpha %s", color, alpha)
61
+
62
+ # Create the full color with alpha
63
+ full_color = color if len(color) == 4 else (*color, 255)
64
+
50
65
  # Loop through pixels to find min and max coordinates
51
66
  for x, y, z in pixels:
52
67
  col = x * pixel_size
53
68
  row = y * pixel_size
54
69
  # Draw pixels as blocks
55
70
  for i in range(z):
56
- image_array[
71
+ # Get the region to update
72
+ region = image_array[
57
73
  row : row + pixel_size,
58
74
  col + i * pixel_size : col + (i + 1) * pixel_size,
59
- ] = color
75
+ ]
76
+
77
+ # Simple direct assignment - ignore alpha for now to ensure visibility
78
+ region[:] = full_color
79
+
60
80
  return image_array
61
81
 
62
82
  @staticmethod
@@ -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
+ )