Skip to content

Commit cd4213c

Browse files
authored
Merge pull request #7 from sca075/dev
Robot Size Configurable
2 parents a41b1c1 + 9c85cdc commit cd4213c

29 files changed

+1442
-825
lines changed

.github/workflows/code_quality.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
uses: actions/setup-python@v6
2727
id: python
2828
with:
29-
python-version: "3.12"
29+
python-version: "3.13"
3030

3131
- name: Install Poetry
3232
run: pip install poetry

.github/workflows/release.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313
- uses: actions/checkout@v5
1414

1515
# Step 2: Set up Python
16-
- name: Set up Python 3.12
16+
- name: Set up Python 3.13
1717
uses: actions/setup-python@v6
1818
with:
19-
python-version: "3.12"
19+
python-version: "3.13"
2020

2121
# Step 3: Install Poetry
2222
- name: Install Poetry

SCR/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""Valetudo map parser.
2-
Version: 0.1.9"""
2+
Version: 0.1.10"""

SCR/valetudo_map_parser/__init__.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Valetudo map parser.
2-
Version: 0.1.9"""
2+
Version: 0.1.10"""
3+
4+
from pathlib import Path
35

46
from .config.colors import ColorsManagement
57
from .config.drawable import Drawable
@@ -19,14 +21,27 @@
1921
NumpyArray,
2022
ImageSize,
2123
)
24+
from .config.status_text.status_text import StatusText
25+
from .config.status_text.translations import translations as STATUS_TEXT_TRANSLATIONS
2226
from .hypfer_handler import HypferMapImageHandler
2327
from .rand256_handler import ReImageHandler
2428
from .rooms_handler import RoomsHandler, RandRoomsHandler
29+
from .map_data import HyperMapData
30+
31+
32+
def get_default_font_path() -> str:
33+
"""Return the absolute path to the bundled default font directory.
34+
35+
This returns the path to the fonts folder; the caller can join a specific font file
36+
to avoid hard-coding a particular font here.
37+
"""
38+
return str((Path(__file__).resolve().parent / "config" / "fonts").resolve())
2539

2640

2741
__all__ = [
2842
"RoomsHandler",
2943
"RandRoomsHandler",
44+
"HyperMapData",
3045
"HypferMapImageHandler",
3146
"ReImageHandler",
3247
"RRMapParser",
@@ -47,4 +62,7 @@
4762
"PilPNG",
4863
"NumpyArray",
4964
"ImageSize",
65+
"StatusText",
66+
"STATUS_TEXT_TRANSLATIONS",
67+
"get_default_font_path",
5068
]

SCR/valetudo_map_parser/config/auto_crop.py

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
import logging
77

88
import numpy as np
9-
from numpy import rot90
109
from scipy import ndimage
1110

12-
from .async_utils import AsyncNumPy, make_async
11+
from .async_utils import AsyncNumPy
1312
from .types import Color, NumpyArray, TrimCropData, TrimsData
1413
from .utils import BaseHandler
1514

@@ -91,7 +90,6 @@ def _calculate_trimmed_dimensions(self):
9190

9291
async def _async_auto_crop_data(self, tdata: TrimsData): # , tdata=None
9392
"""Load the auto crop data from the Camera config."""
94-
_LOGGER.debug("Auto Crop init data: %s, %s", str(tdata), str(self.auto_crop))
9593
if not self.auto_crop:
9694
trims_data = TrimCropData.from_dict(dict(tdata.to_dict())).to_list()
9795
(
@@ -100,7 +98,6 @@ async def _async_auto_crop_data(self, tdata: TrimsData): # , tdata=None
10098
self.trim_right,
10199
self.trim_down,
102100
) = trims_data
103-
_LOGGER.debug("Auto Crop trims data: %s", trims_data)
104101
if trims_data != [0, 0, 0, 0]:
105102
self._calculate_trimmed_dimensions()
106103
else:
@@ -118,10 +115,6 @@ def auto_crop_offset(self):
118115

119116
async def _init_auto_crop(self):
120117
"""Initialize the auto crop data."""
121-
_LOGGER.debug("Auto Crop Init data: %s", str(self.auto_crop))
122-
_LOGGER.debug(
123-
"Auto Crop Init trims data: %r", self.handler.shared.trims.to_dict()
124-
)
125118
if not self.auto_crop: # and self.handler.shared.vacuum_state == "docked":
126119
self.auto_crop = await self._async_auto_crop_data(self.handler.shared.trims)
127120
if self.auto_crop:
@@ -131,7 +124,6 @@ async def _init_auto_crop(self):
131124

132125
# Fallback: Ensure auto_crop is valid
133126
if not self.auto_crop or any(v < 0 for v in self.auto_crop):
134-
_LOGGER.debug("Auto-crop data unavailable. Scanning full image.")
135127
self.auto_crop = None
136128

137129
return self.auto_crop
@@ -164,14 +156,6 @@ async def async_image_margins(
164156
min_y, max_y = y_slice.start, y_slice.stop - 1
165157
min_x, max_x = x_slice.start, x_slice.stop - 1
166158

167-
_LOGGER.debug(
168-
"%s: Found trims max and min values (y,x) (%s, %s) (%s, %s)...",
169-
self.handler.file_name,
170-
int(max_y),
171-
int(max_x),
172-
int(min_y),
173-
int(min_x),
174-
)
175159
return min_y, min_x, max_x, max_y
176160

177161
async def async_get_room_bounding_box(
@@ -247,7 +231,7 @@ async def async_get_room_bounding_box(
247231
return None
248232

249233
except Exception as e:
250-
_LOGGER.error(
234+
_LOGGER.warning(
251235
"%s: Error calculating room bounding box for '%s': %s",
252236
self.handler.file_name,
253237
room_name,
@@ -403,7 +387,6 @@ async def async_auto_trim_and_zoom_image(
403387
try:
404388
self.auto_crop = await self._init_auto_crop()
405389
if (self.auto_crop is None) or (self.auto_crop == [0, 0, 0, 0]):
406-
_LOGGER.debug("%s: Calculating auto trim box", self.handler.file_name)
407390
# Find the coordinates of the first occurrence of a non-background color
408391
min_y, min_x, max_x, max_y = await self.async_image_margins(
409392
image_array, detect_colour
@@ -456,15 +439,7 @@ async def async_auto_trim_and_zoom_image(
456439
# Rotate the cropped image based on the given angle
457440
rotated = await self.async_rotate_the_image(trimmed, rotate)
458441
del trimmed # Free memory.
459-
_LOGGER.debug(
460-
"%s: Auto Trim Box data: %s", self.handler.file_name, self.crop_area
461-
)
462442
self.handler.crop_img_size = [rotated.shape[1], rotated.shape[0]]
463-
_LOGGER.debug(
464-
"%s: Auto Trimmed image size: %s",
465-
self.handler.file_name,
466-
self.handler.crop_img_size,
467-
)
468443

469444
except RuntimeError as e:
470445
_LOGGER.warning(

SCR/valetudo_map_parser/config/colors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ def add_alpha_to_rgb(alpha_channels, rgb_colors):
250250
List[Tuple[int, int, int, int]]: List of RGBA colors with alpha channel added.
251251
"""
252252
if len(alpha_channels) != len(rgb_colors):
253-
LOGGER.error("Input lists must have the same length.")
253+
LOGGER.warning("Input lists must have the same length.")
254254
return []
255255

256256
# Fast path for empty lists
@@ -357,7 +357,7 @@ def set_initial_colours(self, device_info: dict) -> None:
357357
self.color_cache.clear()
358358

359359
except (ValueError, IndexError, UnboundLocalError) as e:
360-
LOGGER.error("Error while populating colors: %s", e)
360+
LOGGER.warning("Error while populating colors: %s", e)
361361

362362
def initialize_user_colors(self, device_info: dict) -> List[Color]:
363363
"""

SCR/valetudo_map_parser/config/drawable.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from __future__ import annotations
1212

1313
import logging
14+
from pathlib import Path
1415

1516
import numpy as np
1617
from PIL import Image, ImageDraw, ImageFont
@@ -874,11 +875,25 @@ def status_text(
874875
position: bool,
875876
) -> None:
876877
"""Draw the status text on the image."""
877-
path_default_font = (
878-
"custom_components/mqtt_vacuum_camera/utils/fonts/FiraSans.ttf"
879-
)
880-
default_font = ImageFont.truetype(path_default_font, size)
881-
user_font = ImageFont.truetype(path_font, size)
878+
module_dir = Path(__file__).resolve().parent
879+
default_font_path = module_dir / "fonts" / "FiraSans.ttf"
880+
# Load default font with safety fallback to PIL's built-in if missing
881+
try:
882+
default_font = ImageFont.truetype(str(default_font_path), size)
883+
except OSError:
884+
_LOGGER.warning(
885+
"Default font not found at %s; using PIL default font",
886+
default_font_path,
887+
)
888+
default_font = ImageFont.load_default()
889+
890+
# Use provided font directly if available; else fall back to default
891+
user_font = default_font
892+
if path_font:
893+
try:
894+
user_font = ImageFont.truetype(str(path_font), size)
895+
except OSError:
896+
user_font = default_font
882897
if position:
883898
x, y = 10, 10
884899
else:
431 KB
Binary file not shown.
786 KB
Binary file not shown.
73.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)