From ec3a0738fe519818bf915aeae00688eeb09cb23d Mon Sep 17 00:00:00 2001 From: Andrei Buzera Date: Mon, 26 Oct 2026 22:13:20 +0200 Subject: [PATCH] Add integration icon Home Assistant 2026.3+ shows custom integrations' own brand images from custom_components//brand/. Add a radiator with a forecast curve (solid past, "now" marker, dashed prediction) as icon.png/icon@2x.png (256/512 px, transparent) plus dark-theme variants, so the integration is easy to spot in Devices & services. Older HA versions ignore the folder and show the generic placeholder; the integration is unaffected. scripts/make_brand_icons.py regenerates the images with Pillow from the test requirements; the package check verifies sizes and transparency. Listed under 0.2.3, which has not been deployed yet. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 3 + README.md | 6 + .../heating_mpc/brand/dark_icon.png | Bin 0 -> 10549 bytes .../heating_mpc/brand/dark_icon@2x.png | Bin 0 -> 21379 bytes custom_components/heating_mpc/brand/icon.png | Bin 0 -> 10249 bytes .../heating_mpc/brand/icon@2x.png | Bin 0 -> 21099 bytes scripts/make_brand_icons.py | 104 ++++++++++++++++++ scripts/validate_package.py | 11 +- 8 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 custom_components/heating_mpc/brand/dark_icon.png create mode 100644 custom_components/heating_mpc/brand/dark_icon@2x.png create mode 100644 custom_components/heating_mpc/brand/icon.png create mode 100644 custom_components/heating_mpc/brand/icon@2x.png create mode 100644 scripts/make_brand_icons.py diff --git a/CHANGELOG.md b/CHANGELOG.md index acbcee2..a884cb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ A stale or failed room sensor no longer pauses the whole integration. Still - Status attributes `excluded_rooms` and `weight_coverage` (share of the total comfort weight covered by the rooms used), and a per-room `used` flag in `input_quality`. +- Integration icon (a radiator with a forecast curve) in **Settings → Devices & + services**, with a dark-theme variant. Needs Home Assistant 2026.3 or newer; + older versions show the generic placeholder. ### Upgrade notes diff --git a/README.md b/README.md index fb14bc8..4ccae6d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ This project targets Home Assistant OS on a Raspberry Pi 5, with one existing ON 6. Choose *ordered lists* of **outdoor sensor entity IDs**. First valid sensor is active; if missing, unavailable, nonnumeric or outside reasonable bounds, the next valid sensor is used automatically. 7. Assign a relative comfort weight (0.1–10) to each selected room. +On Home Assistant 2026.3 or newer the integration shows its own icon (a radiator with a forecast curve) in **Devices & services**; older versions show a generic placeholder. + **No entity IDs are hard-coded.** Every room and outdoor measurement can be changed later via **Configure**, without editing YAML or Python. ## Reconfigurable weather inputs @@ -155,6 +157,10 @@ run without Home Assistant installed: python -m unittest discover -s tests -v ``` +The brand icons in `custom_components/heating_mpc/brand/` are drawn by +`python scripts/make_brand_icons.py` (uses Pillow from the test requirements); +the package check verifies their sizes and transparency. + HA tests cover setup, config/options forms, migration, reload and entity cleanup, scheduled sampling and poll cancellation, the relay listener, stored model restoration, retention and deletion, missing inputs, manual off/presets, optimizer diff --git a/custom_components/heating_mpc/brand/dark_icon.png b/custom_components/heating_mpc/brand/dark_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1e4711e362c754d500b22fa2a01ad49a281f27f5 GIT binary patch literal 10549 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 literal 0 HcmV?d00001 diff --git a/custom_components/heating_mpc/brand/dark_icon@2x.png b/custom_components/heating_mpc/brand/dark_icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5a4b07f54450d7b666f8cbae8917019dd5b72689 GIT binary patch literal 21379 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 GVr2m6>Q~Z9oyX~)RolS4vS>j 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 Q<(j|&L(}~a@s7d&0}t(13IG5A literal 0 HcmV?d00001 diff --git a/custom_components/heating_mpc/brand/icon.png b/custom_components/heating_mpc/brand/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9a4e919b030f722f75d27ca51df165ce62409980 GIT binary patch literal 10249 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 literal 0 HcmV?d00001 diff --git a/custom_components/heating_mpc/brand/icon@2x.png b/custom_components/heating_mpc/brand/icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..31143acbb33553fead24f09ac5f355b8e20aa2d1 GIT binary patch literal 21099 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/brand/ images in +Settings -> Devices & services. Development-only: needs Pillow, which the HA test +requirements already install. Run: python scripts/make_brand_icons.py +""" +from math import hypot +from pathlib import Path + +from PIL import Image, ImageDraw + +OUT = Path(__file__).resolve().parents[1] / "custom_components" / "heating_mpc" / "brand" +DESIGN = 512 # coordinates below are in a 512x512 design space +SUPERSAMPLE = 8 +THEMES = { + "": {"radiator": "#F4511E", "forecast": "#1E88E5"}, # for light backgrounds + "dark_": {"radiator": "#FF7043", "forecast": "#64B5F6"}, # for dark backgrounds +} + + +def bezier(p0, p1, p2, p3, steps=400): + points = [] + for i in range(steps + 1): + t = i / steps + u = 1 - t + points.append(tuple(u**3 * a + 3 * u * u * t * b + 3 * u * t * t * c + t**3 * d + for a, b, c, d in zip(p0, p1, p2, p3))) + return points + + +def stroke(draw, points, width, color): + """Smooth round-capped stroke: overlapping discs along the path. + + Pillow's wide polylines show seams between many short segments. + """ + r = width / 2 + for (x0, y0), (x1, y1) in zip(points, points[1:]): + steps = max(1, int(hypot(x1 - x0, y1 - y0) / (r / 8))) + for i in range(steps + 1): + x, y = x0 + (x1 - x0) * i / steps, y0 + (y1 - y0) * i / steps + draw.ellipse((x - r, y - r, x + r, y + r), fill=color) + + +def split_dashes(points, dash, gap): + """Cut a polyline into dash polylines of the given arc lengths.""" + dashes, current, travelled, drawing = [], [points[0]], 0.0, True + for (x0, y0), (x1, y1) in zip(points, points[1:]): + travelled += hypot(x1 - x0, y1 - y0) + if drawing: + current.append((x1, y1)) + limit = dash if drawing else gap + if travelled >= limit: + if drawing and len(current) > 1: + dashes.append(current) + current, travelled, drawing = [(x1, y1)], 0.0, not drawing + if drawing and len(current) > 1: + dashes.append(current) + return dashes + + +def render(colors): + s = SUPERSAMPLE + image = Image.new("RGBA", (DESIGN * s, DESIGN * s), (0, 0, 0, 0)) + draw = ImageDraw.Draw(image) + scale = lambda pts: [(x * s, y * s) for x, y in pts] + + # Radiator: five rounded columns joined by two headers. + fins, left, right, top, bottom = 5, 12, 500, 250, 500 + gap = 22 + width = (right - left - gap * (fins - 1)) / fins + for i in range(fins): + x0 = left + i * (width + gap) + draw.rounded_rectangle((x0 * s, top * s, (x0 + width) * s, bottom * s), + radius=width / 2 * s, fill=colors["radiator"]) + for y in (296, 420): + draw.rectangle(((left + width / 2) * s, y * s, (right - width / 2) * s, (y + 34) * s), + fill=colors["radiator"]) + + # Forecast: measured past (solid), "now" marker, predicted future (dashed). + line = 40 + curve = bezier((32, 192), (170, 192), (300, 146), (480, 32)) + now = next(i for i, (x, _) in enumerate(curve) if x >= 220) + stroke(draw, scale(curve[:now + 1]), line * s, colors["forecast"]) + for dash in split_dashes(curve[now:], 64, 44)[1:]: + stroke(draw, scale(dash), line * s, colors["forecast"]) + x, y = curve[now] + radius = 40 + draw.ellipse(((x - radius) * s, (y - radius) * s, (x + radius) * s, (y + radius) * s), + fill=colors["forecast"]) + return image + + +def main(): + OUT.mkdir(exist_ok=True) + for prefix, colors in THEMES.items(): + image = render(colors) + for suffix, size in (("", 256), ("@2x", 512)): + path = OUT / f"{prefix}icon{suffix}.png" + image.resize((size, size), Image.LANCZOS).save(path, optimize=True) + print(f"wrote {path.relative_to(OUT.parents[2])}") + + +if __name__ == "__main__": + main() diff --git a/scripts/validate_package.py b/scripts/validate_package.py index 30923e1..a5c3217 100644 --- a/scripts/validate_package.py +++ b/scripts/validate_package.py @@ -1,6 +1,7 @@ """Small local packaging and translation checks; not a replacement for hassfest.""" import json from pathlib import Path +import struct import subprocess root = Path(__file__).resolve().parents[1] @@ -26,6 +27,14 @@ strings = json.loads((component / "strings.json").read_text()) for language in ("en", "ro"): translated = json.loads((component / "translations" / f"{language}.json").read_text()) assert keys(strings) == keys(translated), f"Translation keys differ: {language}" +# Brand icons (HA 2026.3+): square transparent PNGs; see scripts/make_brand_icons.py. +for name, size in (("icon.png", 256), ("icon@2x.png", 512), + ("dark_icon.png", 256), ("dark_icon@2x.png", 512)): + png = (component / "brand" / name).read_bytes() + assert png[:8] == b"\x89PNG\r\n\x1a\n" and png[12:16] == b"IHDR", f"{name} is not a PNG" + width, height, _depth, color_type = struct.unpack(">IIBB", png[16:26]) + assert (width, height) == (size, size), f"{name} is {width}x{height}, expected {size}x{size}" + assert color_type == 6, f"{name} needs an alpha channel" tracked = subprocess.check_output(["git", "ls-files", "custom_components"], cwd=root, text=True).splitlines() assert not any("__pycache__" in path or path.endswith((".pyc", ".pyo")) for path in tracked) -print("Package metadata, translations and tracked component files passed") +print("Package metadata, translations, brand icons and tracked component files passed")