Halloween-Fensterprojektion per MQTT steuern

Halloween-Fensterprojektion per MQTT steuern

Für Halloween wollte ich mehrere Fensterprojektionen zentral und genau im richtigen Moment starten können. Die Player sollen selbstständig auf Raspberry Pis laufen, sich per MQTT ansteuern lassen und nach jedem Effekt wieder in ihre Idle-Schleife zurückkehren.

MQTT übernimmt die Regie

Die Befehle kommen bei mir aus Home Assistant. Dort verknüpfe ich Bewegungsmelder oder Zeitpläne mit Automationen, die MQTT-Nachrichten an einen einzelnen Player oder an alle Player veröffentlichen. Jeder Pi hat dafür eine eigene ID; über halloween/all/cmd lässt sich die ganze Gruppe ansprechen.

Ein Befehl kann neben der Video-ID einen absoluten Unix-Zeitstempel enthalten. So können mehrere Player auf denselben Startzeitpunkt zielen, auch wenn die MQTT-Nachrichten nicht exakt gleichzeitig eintreffen. Kommt ein Befehl verspätet an, steigt der Player an der passenden Stelle in den Clip ein. Voraussetzung dafür sind per NTP synchronisierte Uhren; zwei bis drei Sekunden Vorlauf haben sich bewährt.

Home-Assistant-Automationen veröffentlichen MQTT-Befehle. Jeder Player startet beim Boot, wartet auf init, spielt den Effekt zum gesetzten Zeitpunkt ab und fällt danach in die Idle-Schleife zurück.

Der Player startet mit dem Raspberry Pi

Auf jedem Pi läuft der Player als systemd-Dienst, also als automatisch verwalteter Linux-Dienst. Beim Einschalten startet er selbstständig und gibt das Bild direkt über KMS/DRM aus – ohne Desktop, Mauszeiger oder Konsolentext.

Nach dem Start zeigt der Player zunächst Schwarz und wartet auf init. Erst dieser Befehl schaltet ihn frei und startet die Idle-Schleife. Standardmäßig ist das ein schwarzer Endlosclip; in der Konfiguration lässt sich auch ein anderer Clip verwenden. Die Freigabe ist bewusst nötig: Nach einem Stromausfall soll die Show nicht ungefragt wieder anlaufen.

Kein schwarzes Aufblitzen zwischen den Clips

Der Player startet mpv nur einmal und lässt den Prozess dauerhaft laufen; zwischen den Videos wird lediglich die Datei gewechselt. Beim Umschalten zeigt mpv das bisherige Bild weiter, bis der erste Frame des neuen Clips dekodiert ist.

Heikel ist der Rücksprung am Clipende. Normalerweise entlädt mpv eine Datei, sobald sie zu Ende ist, und zeigt dann seinen schwarzen Hintergrund. Bis der Player davon erfährt und die Idle-Schleife geladen und dekodiert ist, vergehen auf einem Pi 3 einige hundert Millisekunden – sichtbar als kurzes schwarzes Aufblitzen. Mit --keep-open=yes bleibt stattdessen der letzte Frame des Clips stehen und überbrückt diese Lücke, bis die Idle-Schleife läuft. Weil mpv in diesem Modus am Clipende kein eof-Ereignis mehr meldet, beobachtet der Player die Eigenschaft eof-reached und löst darüber den Rücksprung aus.

Überblendungen gibt es nicht; auf dem Pi 3 lassen sie sich mit mpv nicht umsetzen. Alle Übergänge sind harte Schnitte, die bei einer schwarzen Idle-Schleife nicht auffallen.

Nach einem normalen Effekt kehrt der Player selbstständig in die Idle-Schleife zurück. Ein stop-Befehl kann ebenfalls sofort dorthin wechseln. Den aktuellen Zustand – waiting, idle oder playing – sowie die Verfügbarkeit meldet jeder Player über weitere MQTT-Topics. Eine Home-Assistant-Automation kann damit zum Beispiel prüfen, ob ein Player gerade idle ist, bevor sie durch Bewegung einen Clip startet.

Home Assistant sendet die MQTT-Befehle

Nach jedem Neustart muss der Player zuerst mit init freigegeben werden. Das kann Home Assistant zum Beispiel zum Beginn der Show erledigen:

action: mqtt.publish
data:
  topic: halloween/all/cmd
  payload: '{"action": "init"}'

Ein Effekt lässt sich gezielt oder für die ganze Gruppe starten. In diesem Beispiel wird der Kurzname raven drei Sekunden in die Zukunft geplant:

action: mqtt.publish
data:
  topic: halloween/all/cmd
  payload: >-
    {"video": "raven", "at": {{ (now().timestamp() + 3) | int }}}

Für einen einzelnen Player wird halloween/all/cmd durch halloween/<beamer_id>/cmd ersetzt. Kurznamen wie raven werden in der Konfiguration einem lokalen Dateinamen zugeordnet; so müssen lange Videonamen nicht in jeder Automation stehen.

In meiner Bewegungsautomation löst der Zustands- oder Attributwechsel des Bewegungsmelders Halloween – Bewegung den MQTT-Aufruf aus. Er veröffentlicht den Clip scare-unison an halloween/beamer1/cmd – also gezielt an Player 1, ohne Zeitplanung oder Gruppenstart.

Home-Assistant-Automation: Bewegungsmelder startet den Clip scare-unison auf beamer1

Bei Änderung des Bewegungsmelders veröffentlicht Home Assistant {"video": "scare-unison"} auf halloween/beamer1/cmd.

Eine weitere Automation kann einen Zeitplan nutzen, etwa um die Player zum Beginn des Abends mit init freizugeben. Bewegung und Zeitplan lösen also unterschiedliche Teile derselben MQTT-Steuerung aus.

Was für den Nachbau nötig ist

  • Raspberry Pi 3 oder neuer mit Raspberry Pi OS Lite (64 Bit, ohne Desktop)
  • Beamer mit HDMI-Eingang
  • Home Assistant mit MQTT-Integration und ein erreichbarer MQTT-Broker
  • Eigene MP4-Effektvideos; sie werden lokal auf den Playern gespeichert und sind nicht Teil des Repositories

Einen Player einrichten

  1. Raspberry Pi OS Lite (64 Bit) mit dem Raspberry Pi Imager auf die SD-Karte schreiben und WLAN sowie SSH einrichten.

  2. Per SSH verbinden, Git installieren und das öffentliche Projekt herunterladen:

    sudo apt update && sudo apt install -y git
    git clone https://github.com/digitaldex/halloween-projection.git ~/halloween
  3. Den Installer starten:

    bash ~/halloween/deploy/install_pi.sh

    Er installiert die benötigten Pakete, richtet die Grafikgruppen und den systemd-Dienst ein, erzeugt den schwarzen Idle-Clip und fragt nach dem MQTT-Passwort. Eine vorhandene Konfiguration oder ein schon gespeichertes Passwort wird nicht überschrieben.

  4. Den Pi einmal neu starten, damit die Gruppen für die direkte Bildausgabe wirksam werden. Danach ~/halloween/config/settings.yaml öffnen und Broker-Adresse sowie eine eindeutige client.beamer_id eintragen.

  5. Die eigenen Videos nach ~/halloween/media/ kopieren. Mit --list-videos lassen sich die erkannten Namen prüfen; kurze Aliase wie raven können in der Konfiguration ergänzt werden. Für Videodateien muss man selbst die nötigen Nutzungsrechte besitzen.

  6. Den Dienst starten und den Player aus Home Assistant mit init freigeben:

    sudo systemctl start halloween-beamer

Für jeden zusätzlichen Beamer wird die Einrichtung wiederholt und eine eigene ID vergeben. Die betreffenden Clips müssen auf jedem Player lokal vorhanden sein. Nachfolgende Neustarts starten den Dienst automatisch; nach einem Stromausfall wartet er trotzdem erneut auf init.

Praxiserfahrung

Der Aufbau wurde auf einem Raspberry Pi 3 mit 1080p30-Material getestet. Bei einem 60-Sekunden-Clip mit 9 Mbit/s wurden mit Software-Decoding und dem mpv-Profil fast keine verworfenen Frames gemessen. Auf diesem Pi war der Hardware-Decoder langsamer. Das ist ein Messwert für genau diesen Clip und Aufbau, keine Garantie für beliebiges Material; 4K oder höhere Bildraten überfordern einen Pi 3.

Fazit und Ressourcen

Home Assistant entscheidet, wann welcher Effekt startet; jeder Raspberry Pi übernimmt die Wiedergabe selbstständig. Das MQTT-Protokoll hält die Steuerung einfach, während die Idle-Schleife nach jedem Clip einen definierten Zustand herstellt.

Zum Beitrag →

~ $ ls ältere-beiträge/ 11 Einträge

Software

Obsidian + Web MCP + Claude.ai – DAS Trio für perfekte Notizen

Den Obsidian-Vault geräteneutral und sicher für Claude erreichbar machen — via headless Obsidian, obsidian-web-mcp und Reverse Proxy.

Claude KI MCP
Smart Home

DAKboard Display per HomeKit / MQTT schalten

Das Wanddisplay leuchtet nur noch, wenn jemand davorsteht — via Bewegungsmelder, MQTT und Python auf dem Raspberry Pi.

Raspberry Pi Python MQTT
3D-Druck

Gewürzeinsatz für die Küchenschublade

Kein passendes Teil gefunden — also selbst in Fusion 360 konstruiert und gedruckt. Modular, je vier Gläser pro Modul.

Fusion 360 3D-Druck STL
Aquascaping

Aquascaping

Ein ADA 60f im Wohnzimmer, bepflanzt und besetzt mit Zwerggarnelen, Schnecken und zwei Zwergfadenfischen.

ADA 60f Wabikusa Naturaquarium
Elektronik

New Frontend for Opensource Smartmeter

Die piMeter-Software verschlankt: Visualisierung raus aus hartkodiertem JavaScript, rein in Grafana und InfluxDB.

piMeter Grafana InfluxDB
Elektronik

Opensource Raspberry Pi Smartmeter

Ein selbst entwickelter Energiemonitor als Raspberry-Pi-Aufsatz auf Basis des ADE9000 — misst Strom, Spannung und Leistung über drei Phasen.

Raspberry Pi ADE9000 Energiemonitor
Smart Home

Modbus IP Weather Library

Eine kleine C++-Bibliothek, die aktuelle Wetterdaten von OpenWeatherMap holt und per Modbus IP im Netzwerk bereitstellt.

C++ Modbus OpenWeatherMap
Elektronik

Atmel Mega 128 USB Eval Board

Ein doppelseitiges SMD-Board mit ATmega128 und FTDI UART→USB-Bridge — als DIY-Eagle-Projekt zum Nachbauen.

AVR Eagle PCB
Software

Android Modder v1

Ein Tool auf Basis des Android-SDK, das direkte Datei-Zugriffe über die ADB-Shell erlaubt — ein kleiner Vorgeschmack auf v1.

Android ADB Tool
Security

Passwort-Sniffing mit Ettercap und Wireshark

Wie leicht sich in einem lokalen Netz Passwörter mitlesen lassen — und warum man in öffentlichen Netzen besser einen VPN-Tunnel nutzt.

Ettercap Wireshark MITM
Security

Ettercap-Tutorial

Grundlagen zu Man-in-the-Middle-Angriffen: ARP-Poisoning und DNS-Spoofing mit Ettercap Schritt für Schritt erklärt.

Ettercap ARP-Poisoning DNS-Spoofing