sphings-dev.de

Bluetooth-LED-Pixelpanels in Home Assistant: BLE LED Pixel Display

Diese Panels werden als Spielzeug verkauft: Man stellt per Handy-App über Bluetooth eine Nachricht ein, und das war es. BLE LED Pixel Display macht sie zu einem vollwertigen Ausgabegerät für Home Assistant. Es gibt eine text-Entität, in die jede Automation schreiben kann, und Aktionen für Bilder, GIFs, Icons und Layouts aus mehreren Elementen. Gemeint sind Panels, die das iPIXEL-Color-Protokoll sprechen, etwa BGLight oder das „LED pixel board“ von Action (B.K. Light). Alles läuft lokal über Bluetooth LE, ohne Cloud, ohne Hersteller-App und ohne Konto.

Animation: Ein 64×16-Panel zeigt abwechselnd H 99M 62, PV 2400W, SoC 78 % und B 1557W, daneben ein 32×32-Panel mit Herz, Sonne, Batterie und Blitz
Links Text auf einem 64×16-Panel, rechts Bilder auf einem 32×32-Panel, beides aus Home Assistant gesteuert.

Ein Fork mit neuer Domain

Die Integration setzt ha-ipixel-color von Christian Grund fort, das seit Dezember 2025 keine Commits mehr hatte, während Pull Requests und Issues liegen blieben. Sie übernimmt die Arbeit von tigers75 an Bildern, MDI-Icons und Layouts samt ordentlicher Dienstregistrierung sowie sechs nie gemergte Upstream-Pull-Requests (Schriftmetriken, Wiederholung beim Abruf der Geräteinfo, Zeitzone der Uhr, Schriftgröße im Textmodus, show_emoji und eine Überschreibung der Panelgröße). Die Domain heißt ble_led_pixel statt ipixel_color; beide Integrationen lassen sich daher nebeneinander installieren, und man kann Panel für Panel umziehen. Gleichzeitig mit demselben Panel sollten sie nicht verbunden sein.

Die Versionsnummern beginnen bei 1.0.0, weil Upstream v0.1.0 und v0.2.0 verwendet hatte; eine Fortsetzung dieser Folge hätte Releases beider Projekte schwer unterscheidbar gemacht. Zwei weitere Upstream-PRs hat der Fork bewusst nicht übernommen: einen, der die 244-Byte-Schreibvorgänge durch ACKs mit 20-Byte-Blöcken und festen Pausen ersetzt hätte, und einen mit 1.424 ungeprüften Zeilen für 96×16-Panels.

Was die Integration anbietet

Pro Panel entstehen Entitäten für Text (text), Textfarbe und Hintergrundfarbe (light), Helligkeit, Modus (textimage, text oder clock), Schrift, Schriftgröße, Zeilenabstand, Textgeschwindigkeit, Uhrstil sowie Schalter für 24-Stunden-Uhr, Datum, Antialiasing und Auto-Update. Dazu kommen Tasten zum Aktualisieren der Anzeige und zum Synchronisieren der Zeit sowie Diagnosesensoren für Gerätetyp, Breite und Höhe. Die Aktionen sind send_text, send_image_file, send_mdi_icon, send_layout, send_test_pattern und show_emoji. Bei Icons werden MDI-Namen nach Bedarf geladen, jeder Name funktioniert also, ohne den Iconsatz mitzuliefern.

Die fünf Aktionen der Integration: send_text, send_image_file, send_mdi_icon, send_layout und send_test_pattern

Der Textmodus unterscheidet sich vom Bildmodus grundlegend. Im Modus text rendert das Panel selbst, das ist der geringste Bluetooth-Verkehr und die flüssigste Animation. Im Modus textimage rendert Home Assistant den Text mit Pillow zu einem Bild und schickt dieses, was eigene TTF-Schriften, präzise Größen, Antialiasing und mehrzeiligen Text mit \n erlaubt.

Flackern vermeiden

Ein Detail, das für den Dauerbetrieb zählt: Mit eingeschaltetem „Auto Update“ rendert jede Änderung sofort. Text setzen ist ein Bluetooth-Schreibvorgang, Farbe setzen ein zweiter; dazwischen zeigt das Panel kurz den alten Wert in der neuen Farbe oder umgekehrt. Auf einer langsamen Verbindung sieht man die Lücke deutlich. Bei ausgeschaltetem Auto-Update speichern text.set_value und light.turn_on nur, und erst die Taste „Update Display“ schickt Text und Farbe zusammen in einem Schreibvorgang. Das ist auch schneller, weil ein Bluetooth-Roundtrip drei ersetzt. Der Preis: Änderungen von Hand in der Oberfläche bleiben bis zum Tastendruck unsichtbar.

Hardware-Eigenheiten, die die ersten Versionen klärten

Weil die Panels unbekannte Befehle ohne Fehler bestätigen, fallen Fehler oft nicht auf. Viele der frühen Versionen sind Korrekturen dieser Art.

  • Schrift im Textmodus (1.0.0): Die Auswahl hatte keinen Effekt, weil Schriften nur im Ordner der Integration gesucht wurden, der Selektor aber drei Orte anbot. Alles löst jetzt zu absoluten Dateipfaden auf. pypixelcolor ist auf >=0.4.0,<0.5 gepinnt.
  • Namen und Hersteller (1.0.1, 1.0.2): Das Rename von 1.0.0 hatte die Oberfläche nicht erfasst; Dialoge hießen weiter „iPIXEL“. Die Geräteinfo behauptet keinen Hersteller mehr – die Panels laufen unter mehreren Marken, und das Protokoll meldet keinen. Außerdem wurden blockierende Dateizugriffe im Event-Loop beim Schriften-Scan beseitigt.
  • Automatische Wiederverbindung (1.1.0, 1.1.1): Eine verlorene Verbindung blieb verloren, bis der Config-Eintrag von Hand neu geladen wurde. Jetzt stellt ein Wächter die Verbindung her, sobald das Panel wieder funkt, mit wachsender Wartezeit von 5 bis 30 Sekunden. Die Grundlage ist ein PR von arcdrake22 für das Original, der zurückgezogen wurde; er wurde auf die Client-Architektur dieses Forks neu gebaut. Das Setup bricht nicht mehr ab, wenn das Panel kurz außer Reichweite ist, und die Schleife blockiert den Home-Assistant-Start nicht mehr.
  • Gerätetypen und Marken (1.2.0 bis 1.3.4): Aus statischer Analyse der Hersteller-App stammt eine vollständige Gerätetyptabelle. pypixelcolor kannte 20 LED-Typen für die Gerätetypen 128 bis 147; es gibt Typen bis 159 und 36 LED-Typen. Zwölf Modelle – alle mit 64 Pixeln Höhe – hatten vorher keine Abmessungen. Ein 32×32-Panel braucht 12.288 Byte Framebuffer, nicht die 4.096 des Standards. Product-ID und Marke werden aus der Werbung des Panels gelesen; erkannt sind HYPERLITE, EZYEVY und B.K. Light (000702), das „LED pixel board“ von Action (32×32, Artikel ACT1026) und der „LED fun screen“ (64×16, ACT1025).
  • Speicherplätze (1.3.0): Panels speichern Bilder intern. Ein gespeichertes Bild anzuzeigen kostet sieben Byte, dasselbe Bild neu zu senden einen kompletten Framebuffer – 12.288 Byte auf einem 32×32-Panel. show_slot und delete_slot rufen sie ab und löschen sie.
  • Firmware-Funktionen (1.4.0): show_preset (eine von 20 im Panel gespeicherten Animationen), set_scoreboard, set_countdown und set_stopwatch. Welches Panel was kann, steht in einer aus dem App-Code übertragenen Tabelle; ein Diagnosesensor „Supported features“ zeigt, was das Panel annimmt. Nicht unterstützte Aktionen schlagen mit einer Erklärung fehl, denn ein stilles Ignorieren sähe von außen aus wie Erfolg.

Passwortgeschützte Panels

Ein Panel, das in der Hersteller-App mit einem Passwort gesperrt wurde, verbindet sich normal und verwirft dann alles, was man ihm schickt, ohne Fehler. Das ist kaum zu diagnostizieren. Seit 1.5.0 trägt man das Passwort in den Optionen ein; es wird nach jedem Verbindungsaufbau gesendet, denn das Panel vergisst die Entsperrung, sobald die Verbindung abreißt. Sechs Ziffern bei den meisten Modellen, vier bei den zwei Ausnahmen, gewählt nach der Product-ID. Ein Diagnosesensor „Password protection“ zeigt none, locked, password set oder locked, no password set.

Mit 2.2.0 kam die Aktion set_password zum Setzen und Entfernen. Sie war bewusst zurückgehalten worden, weil man sich leicht aussperrt – der Weg zurück ohne Passwort ist ein Power-Cycle-Reset am Gerät. Den Ausschlag gab, dass die Hersteller-App unmaintained und der einzige Weg ist, überhaupt ein Passwort zu setzen. Die Aktion ist absichtlich keine Schalter-Entität, damit sie nicht versehentlich ausgelöst wird; sie schreibt das Passwort im selben Schritt in die Optionen, damit die Integration das Panel weiter erreicht. Das Passwort sollte man zusätzlich anderswo notieren. Dass docs/password_reset.md das Passwort-Flag zuerst falsch herum beschrieb (255 heißt „nicht gemeldet“, nicht „kein Passwort“), wurde in 1.5.0 korrigiert.

Text, Effekte, Verläufe

In 2.0.0 ersetzte select.<panel>_text_effect die Zahl text_animation. Der Effekt ließ sich zuvor nur als nackte Zahl von 0 bis 7 setzen, nun heißen die Optionen Fixed, Scroll left, Scroll right, Blinking, Breathing, Snowflake und Laser. Laser (Code 8) war vorher nicht erreichbar, weil jede aus Mitschnitten rekonstruierte Tabelle bei 7 endete. Die Codes 3 und 4 werden absichtlich nicht angeboten: pypixelcolor lehnt sie außer auf 32×32-Panels ab, weil sie ein Gerät in eine Boot-Schleife schicken können. Ähnlich ersetzte 2.1.0 den Regler text_rainbow durch select.<panel>_text_gradient mit acht benannten Verläufen von „Spectrum“ bis „Warm wheel, wide“. Die App nennt sie nur GRADIENT_COLOR_01 bis _08, die Namen sind also eigene, aus den Farbverläufen abgeleitet; die Nummer bleibt im Label. Automationen, die die alten Entitäten schreiben, müssen angepasst werden, der bestehende Wert wird beim ersten Start migriert.

Schriftgröße und Zeilenabstand bedeuten je nach Modus Verschiedenes, wie 2.1.1 dokumentiert: Im Modus textimage zählt 0 als automatische Anpassung und Halbschritte werden eingehalten, der Zeilenabstand (0–20 px) wirkt. Im Modus text legt die Firmware den Text in ganzen 16-Pixel-Zeilen aus: Die Größe wird auf die Panelhöhe begrenzt und auf ein Vielfaches von 16 abgerundet, und der Zeilenabstand hat gar keine Wirkung. Auf einem 32-Pixel-Panel bleiben also 16 und 32. Beide Einstellungen bleiben sichtbar; das Log meldet unbrauchbare Werte einmal pro Änderung.

Entdeckung, Firmware, Uhr

Seit 2.1.0 werden Panels so gefunden wie von der App: Die App sucht LED_BLE irgendwo im Namen und akzeptiert auch Panels ohne diesen Namen, solange die Werbung die Herstellerdaten enthält. Vorher musste der Name mit LED_BLE_ beginnen, sodass ein Panel namens LED_BLE1234 oder ein vollständig umbenanntes für Home Assistant unsichtbar war. Seit 1.6.0 zeigen MCU- und WiFi-Version echte Werte, per zweitem Lesebefehl (Opcode 0x8005), den bisher keine aus Mitschnitten abgeleitete Implementierung nutzte, weil sichtbar nichts passiert. Ein Sensor „MCU build“ liefert die Version als Ganzzahl, wie sie die Firmware-Suche des Herstellers verwendet (4.06 wird 406). Die Auswahl der Uhrstile passt sich der Hardware an: acht Ziffernblätter auf den meisten Panels, neun auf 32×32, zehn auf 32×16 und sechs auf 144×16.

Zwei Fehler aus dem Dauerbetrieb: In 2.2.1 war der Modus textimage nie beim Panel angekommen, weil display_text ein SendPlan wie eine Liste von Frames durchlief – bei einem per Automation gefütterten Panel hieß das bei jedem Update eine Ausnahme. Und in 2.3.0 schlief der Wiederverbindungs-Wächter während der Wartezeit durch genau die Werbepakete, auf die er wartete; jetzt wartet die Schleife auf die Werbung und versucht es sofort.

Installation

  1. In HACS unter „Benutzerdefinierte Repositories“ https://github.com/sphings79/ha-ble-led-pixel-display mit der Kategorie „Integration“ hinzufügen.
  2. Nach „BLE LED Pixel Display“ suchen, installieren, Home Assistant neu starten.
  3. Panel einschalten und sicherstellen, dass kein Handy verbunden ist – ein mit der App verbundenes Panel funkt nicht mehr und wird nicht gefunden. Home Assistant bietet es meist selbst unter Geräte & Dienste an.

Voraussetzung ist Home Assistant 2024.1 oder neuer; Bluetooth-Proxys werden unterstützt. Das Netzteil des Panels sollte laut Anleitung des Herstellers 5 V / 2 A liefern – bei einem schwachen Netzteil verbindet sich ein sichtbares Panel nicht. Die Integration steht unter GPL-3.0, sie ist inoffiziell und steht in keiner Verbindung zu den Herstellern.

Tags

Zum Projekt

Unterstützen

Diese Tools entstehen in meiner Freizeit und bleiben kostenlos, offen und cloud-frei. Wenn dir eins davon einen Nachmittag gespart hat, freue ich mich über einen Kaffee oder ein Stück Pizza.

Kaffee oder Pizza

Weitere Beiträge