In Home Assistant liessen sich nur Szenen und Helligkeit stellen, keine Farben - device/state traegt naemlich keine. Die steht je Segment, und die Segmente hat der Koordinator bisher gar nicht gelesen. Jetzt holt er device/segments mit (fuenfte Anfrage je Zyklus), und die Lichtentitaet bietet rgb_color und color_temp_kelvin an: * Setzen schreibt in ALLE Segmente, aber nur die Farbfelder - Grenzen, Namen und Helligkeit bleiben stehen. Die Einteilung eines Strips ist von Hand gemacht, die reisst eine Farbwahl nicht ein. Geschrieben wird die ganze Liste auf einmal, danach zurueckgelesen statt angenommen. * Angezeigt wird nur, worauf sich alle Segmente einigen. Zwei Farben und eine Entitaet - da waere jede Angabe gelogen, also gibt es keine. * Farbtemperatur nur, wenn alle auf "white" stehen; sonst RGB, sonst blendete HA den Farbkreis aus, sobald ein Segment einen Effekt faehrt. * Die Farbe geht VOR dem Einschalten raus, sonst leuchtet der Strip kurz in der alten auf. Die Spanne 2700-6500 K ist die, die die Firmware auf die Weisskanaele umrechnet (nl_ct.h); ohne Weisskanaele naehert sie sie in RGB an. Dazu: das Markenbild ist jetzt dasselbe wie bei ninlight - Michaels Wunsch, die beiden Integrationen gehoeren zusammen. Das Skript fuer ein eigenes Motiv bleibt als Ausgangspunkt liegen.
70 lines
2.4 KiB
Python
70 lines
2.4 KiB
Python
"""Erzeugt die Markenbilder, die HA aus custom_components/ninstrip/brand/ ausliefert.
|
|
|
|
Ab Home Assistant 2026.3 nimmt HA fuer eine eigene Integration die Bilder aus
|
|
diesem Ordner - ohne sie bleibt in der Geraeteuebersicht ein Platzhalter.
|
|
**Nicht mehr in Gebrauch.** Michael wollte am 23.09.2026 dasselbe Bild wie
|
|
bei ninlight - die beiden Integrationen gehoeren zusammen, und zwei
|
|
verschiedene Motive in derselben Geraeteuebersicht stiften nur Verwirrung.
|
|
Die Bilder in brand/ sind deshalb aus ha-ninlight uebernommen.
|
|
|
|
Das Skript bleibt als Ausgangspunkt liegen, falls doch einmal ein eigenes
|
|
Motiv gewuenscht ist: ein dunkles Band mit fuenf leuchtenden Pixeln.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from PIL import Image, ImageDraw, ImageFilter
|
|
|
|
OUT = Path(__file__).parents[1] / "custom_components" / "ninstrip" / "brand"
|
|
DUNKEL = (38, 38, 46, 255)
|
|
# Rot, Gelb, Gruen, Cyan, Blau - eine Reihe, wie sie ein Lauflicht zeigt.
|
|
PIXEL = [
|
|
(255, 64, 64, 255),
|
|
(255, 176, 46, 255),
|
|
(64, 224, 96, 255),
|
|
(64, 208, 232, 255),
|
|
(96, 112, 255, 255),
|
|
]
|
|
|
|
|
|
def strip(size: int) -> Image.Image:
|
|
s = size / 256
|
|
bild = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
|
|
|
# Der Schein liegt unter dem Band und wird geweichzeichnet - sonst sehen
|
|
# die Pixel aus wie aufgemalte Punkte statt wie Licht.
|
|
schein = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
|
male = ImageDraw.Draw(schein)
|
|
for i, farbe in enumerate(PIXEL):
|
|
x = (40 + i * 44) * s
|
|
male.ellipse((x - 30 * s, 90 * s, x + 30 * s, 166 * s), fill=(*farbe[:3], 130))
|
|
schein = schein.filter(ImageFilter.GaussianBlur(radius=max(1.0, 9 * s)))
|
|
bild.alpha_composite(schein)
|
|
|
|
male = ImageDraw.Draw(bild)
|
|
male.rounded_rectangle((12 * s, 92 * s, 244 * s, 164 * s), radius=22 * s, fill=DUNKEL)
|
|
for i, farbe in enumerate(PIXEL):
|
|
x = (40 + i * 44) * s
|
|
male.ellipse((x - 19 * s, 109 * s, x + 19 * s, 147 * s), fill=farbe)
|
|
# Kleines Glanzlicht, damit die Pixel gewoelbt wirken.
|
|
male.ellipse((x - 8 * s, 115 * s, x + 1 * s, 124 * s), fill=(255, 255, 255, 110))
|
|
return bild
|
|
|
|
|
|
def main() -> None:
|
|
OUT.mkdir(parents=True, exist_ok=True)
|
|
for name, size in (
|
|
("icon.png", 256),
|
|
("icon@2x.png", 512),
|
|
("logo.png", 256),
|
|
("logo@2x.png", 512),
|
|
):
|
|
strip(size).save(OUT / name)
|
|
print(OUT / name)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|