tech·nic

LED-Matrix-Rahmen für Homelab-Status

16 × 16 WS2812B hinter einem matt diffusem PETG-Rahmen. ESP32 läuft WLED, Daten kommen per MQTT aus dem Homelab — Wetter links, Frigate-Personencounter rechts.

LED-Matrix-Rahmen für Homelab-Status

Techniken

3D-Druck Löten Elektronik

Material

WS2812B 5V, 60 LEDs/m ESP32 DevKit V4 PETG (matt, Diffusor) PLA-Black (Rahmen) 5V/4A Netzteil

Im Homelab-Raum hängt mittlerweile ein 16 × 16-Pixel-Display an der Wand. Die linke Hälfte zeigt die Außentemperatur und ob es regnet (kommt aus Home Assistant über MQTT), die rechte Hälfte zählt, wie viele Personen Frigate im Garagenbereich gerade detektiert. Beides Sachen, die ich vorher in einem Dashboard-Tab offen hatte — jetzt schaue ich kurz hin.

Was drinsteckt

Kein Hexenwerk, aber ein paar bewusste Entscheidungen, die ich beim ersten Anlauf falsch gemacht hatte:

  • WS2812B, 5V, einzeln adressierbar. NICHT die 12V-Variante — die schluckt bei kleinen Matrix-Größen einfach unnötig Strom in der Spannungswandlung.
  • ESP32 statt ESP8266, weil WLED auf dem ESP32 deutlich stabiler bei mehr als 100 LEDs läuft und das WiFi-Reconnect-Verhalten sauberer ist.
  • 5V/4A-Netzteil, nicht weiter. Die 256 LEDs ziehen maximal 256 × 20 mA × 3 Kanäle = 15.36 A bei Vollweiß — was im Alltag nie passiert. Mit 4 A und WLED-Limit bei 60 % komme ich auf realistische ~2.5 A Peak.
  • 3-D-gedruckter Rahmen aus PLA-Black, 4 mm dick. Innen mit T-Profil, an dem der LED-Streifen schlangenförmig mit Doppelklebeband sitzt.
  • Diffusor aus mattem PETG, 1.6 mm dick, im Vase-Mode gedruckt (0.4 mm Wand, durchscheinend). Macht aus harten Pixel-Punkten weiche Quadrate.

Software: WLED + MQTT

WLED auf dem ESP32 ist Standard. Die Trick-Frage ist, wie man Daten aus Home Assistant aufs Display bekommt, ohne dass jedes Update einen ganzen Effekt-Reset triggert.

Lösung über das WLED-JSON-API per MQTT-Bridge (HA → MQTT → ESP32):

# Home Assistant configuration.yaml (Auszug)
mqtt:
  publish:
    topic: "wled/matrix/api"
    payload: >
      {"seg":[{"id":0,"i":[{{ states('sensor.outdoor_temp_pixels') }}]}]}

Der Trick ist seg[].i[] direkt mit Pixel-Werten zu füllen, statt einen Effekt zu wechseln. Das hält den Refresh bei < 50 ms und flackert nicht.

Was ich beim nächsten Build anders machen würde

  • Rahmen breiter als 8 mm. Der aktuelle Rand wirkt im Betrieb fast verschwunden, was hübsch aussieht, aber den Diffusor an den Rändern leicht heller macht. 10–12 mm Rand würde das gleichmäßiger machen.
  • Spannungsversorgung an beiden Enden. Bei 16 × 16 noch unkritisch, aber ab 24 × 24 bekommt man Helligkeitsunterschiede zwischen Pixel 1 und Pixel 200, wenn nur eine Seite einspeist.

Tutorial mit Druckdateien und WLED-Config-Snippet folgt im Blog, sobald ich es ein zweites Mal aufgebaut habe — das erste Mal war zu chaotisch für eine saubere Anleitung.