Überblick¶
Eine weitere Spielerei: Ich wollte einen LED Streifen hinter das TV-Board kleben. Ziel war es, dass es einerseits ein schönes Ambiente im Wonzimmer erzeugt, aber auch auf bestimmte Signale von dem TV reagiert. Daher war es sofort von Anfang an ausgeschlossen, einen fertigen LED Streifen zB von Govee zu kaufen.
Das Ziel¶
Der Streifen sollte folgende Features haben: - LEDs müssen individuell ansteuerbar sein, um Effekte abspielen zu können - Der Streifen soll verschiedene Effekte und Animationen bereithalten - Der LED-Streifen soll sich direkt in Home Assistant einbinden lassen - Home Assistant soll den streifen durch Automationen steuern können, inkl Effekte
Hardware¶
Da ich bereits einige Erfahrung durch meine anderen Projekte wie eine Wortuhr mit LED Streifen gesammelt habe, kam ich schnell zu dem Entschluss, folgende Hardware zu nutzen:
- Raspberry Pi Pico W
- USB-C Adapter für Pico
- WS281X LED Streifen
- 45W, 5A Netzteil
- Aluprofil 2m
Raspberry Pico¶
Der Pico wurde mit MicroPython in VSCode programmiert. Grundsätzlich hat dieser eine einfache Architektur. Da der Pico zwei Kerne besitzt, läuft auf Kern 0 ein Webserver, der bestimmte Kommandos entgegen nimmt. Auf Kern 1 läuft ein Animations-Loop mit neopixel, der sich um die Ansteuerung der einzelnen LEDs kümmert. Somit war es möglich, dass eine Animation immer flüssig bleibt, obwohl gerade ein neues Kommando verarbeitet wird.
- Kern 0 kümmert sich um die Kommunikation: Er empfängt Befehle über WLAN (z. B. „mach die LEDs rot” oder „starte den Regenbogen-Effekt”).
- Kern 1 ist der Maler: Er zeichnet 60 Mal pro Sekunde das aktuelle Bild auf den LED-Streifen.
Die beiden Kerne reden nicht direkt miteinander. Stattdessen setzt Kern 0 einfach Variablen (z. B. current_effect = "rainbow"), und Kern 1 liest diese Variablen bei jedem Durchlauf aus. So gibt es keine Konflikte.
Webserver¶
Der Webserver ist ein einfacher WebSocket Server, welcher im Hintergrund läuft:
class APIServer:
def __init__(self, neopixel_controller, device_info, port=80, network_mgr=None):
"""Initialize API server"""
self.controller = neopixel_controller
self.device_info = device_info
self.port = port
self.network_mgr = network_mgr
self.socket = None
self.running = False
def start(self):
"""Start the API server"""
try:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(('0.0.0.0', self.port))
self.socket.listen(5)
self.socket.setblocking(False) # Non-blocking mode
self.running = True
logger.info("API server started on port {}".format(self.port))
return True
except Exception as e:
logger.error("Failed to start API server: {}".format(e))
return False
Somit kann der Server nun mehrere Sachen abfangen: - Geräteidentifizierung für das automatische Setup in Home Assistant - Periodische Statusabrufe - Einzelne Kommandos
LED Controller¶
Auf Kern 1 läuft eine Schleife in einem neuen Thread mit _thread.start_new_thread(self._animation_loop, ()), welche die LEDs ansteuert und auf Kommandos vom Webserver wartet.
Wiederhole endlos:
- Ist der Streifen aus? → Nichts tun, kurz warten
- Position um einen kleinen Schritt weiter bewegen
- Aktuellen Effekt zeichnen (jede LED einzeln berechnen)
- 16 Millisekunden warten (~60 FPS)
┌─────────────────────────────────────────┐
│ Home Assistant │
│ (sendet Befehle) │
└──────────────┬──────────────────────────┘
│ WLAN
┌──────────────▼──────────────────────────┐
│ Pico W – Kern 0 │
│ Empfängt Befehle, setzt Variablen │
│ (Farbe, Effekt, Helligkeit, Speed) │
└──────────────┬──────────────────────────┘
│ Gemeinsame Variablen
┌──────────────▼──────────────────────────┐
│ Pico W – Kern 1 │
│ Liest Variablen, berechnet 60×/s │
│ jede LED, schreibt auf den Streifen │
└──────────────┬──────────────────────────┘
│ Datensignal
┌──────────────▼──────────────────────────┐
│ WS2812B LED-Streifen │
│ Jede LED leuchtet individuell │
└─────────────────────────────────────────┘
Effekte – wie entstehen die Animationen?¶
Jeder Effekt ist eine eigene Funktion, die für jede einzelne LED berechnet, welche Farbe sie haben soll. Ein paar Beispiele:
Statisch¶
Einfach: Alle LEDs bekommen die gleiche Farbe. Fertig.
Rainbow (Regenbogen)¶
Jede LED bekommt eine andere Farbe aus dem Farbkreis. Die Position verschiebt sich jedes Frame ein Stück, sodass der Regenbogen über den Streifen „wandert”.
Chase (Lauflicht)¶
Ein leuchtender Punkt wandert über den Streifen. Hinter ihm wird es dunkler – wie ein Schweif. Je weiter eine LED vom „Kopf” entfernt ist, desto dunkler wird sie.
Breathing (Atmen)¶
Alle LEDs haben die gleiche Farbe, aber die Helligkeit pulsiert sanft auf und ab – wie ein ruhiger Atemzug. Dahinter steckt eine Sinuswelle.
Twinkle (Funkeln)¶
Zufällige LEDs blitzen kurz auf und verblassen dann langsam. Das erzeugt einen Sternenhimmel-Effekt.
Comet (Komet)¶
Ähnlich wie Chase, aber mit einem langen, verblassenden Schweif. Bei langsamerer Geschwindigkeit ist der Schweif länger sichtbar.
One-Shot-Animationen – einmal abspielen, dann zurück¶
Manche Animationen sollen nur einmal durchlaufen – z. B. ein Lauflicht als Benachrichtigung. Dafür gibt es den One-Shot-Modus:
- Der aktuelle Zustand wird gespeichert (Farbe, Effekt, Helligkeit)
- Die Animation wird abgespielt
- Sobald sie fertig ist, wird der alte Zustand wiederhergestellt
Es gibt drei Varianten, wie der alte Zustand wiederhergestellt wird: - Fill-Effekte (z. B. von der Mitte nach außen füllen): Die LEDs bleiben an – der Streifen wechselt zu „statisch” in der neuen Farbe - Unfill-Effekte (LEDs ausschalten): Die LEDs bleiben aus - Alle anderen: Der exakt vorherige Zustand wird wiederhergestellt
Beispiel: Rot (255, 0, 0) bei 50 % Helligkeit → (127, 0, 0).
Fortschrittsbalken¶
Ein spezieller Effekt zeigt einen Fortschrittsbalken an (0–100 %). Die LEDs füllen sich von links nach rechts. Auch hier wird Sub-Pixel-Rendering eingesetzt: Die letzte LED am Rand leuchtet anteilig, damit der Übergang nicht abgehackt wirkt.
Der angezeigte Wert bewegt sich sanft zum Zielwert hin (~30 % pro Sekunde), damit Sprünge weich animiert werden.
Home Assistant¶
Die Integration ist auf Home Assistant mittels HACS verfügbar und kann über den Store direkt installiert werden. Diese erkennt einen verbundenen Pico automatisch, fragt den Status ab und sendet Befehle. Mit Automationen lassen sich nun verschiedene Szenarien ansteuern, zB: - Schalte die LED an, wenn der TV angeht mit einer Animation - Wechlse die Farbe auf Blau mit Animation, wenn der Kanal zu PlayStation gewechselt wird. - Schalte zu Twinkel Animation, wenn die Sonos Musik spielt und der TV aus ist
Ergebnis¶
To be continued..