hyperion mit OpenWRT

Bei mir steht ein TP-Link TL-WR1043N (v1) WLAN Router im Wohnzimmer neben dem Fernseher. Er hat einen USB Port und läuft mit OpenWRT – beide waren die Kaufkriterien vor ein paar Jahren für mich und werden wohl auch für künftige Router sein. Am USB Port ist eine 2,5 Zoll Festplatte angeschlossen, welche problemlos vom Router mit Strom versorgt wird und als Netzlaufwerk dient. Seitdem ich mich mit hyperion beschäftigt habe, kam mir immer wieder die Idee in den Sinn, dass der Router auch die Ansteuerung der LEDs übernehmen kann und für Raumbeleuchtung sorgen kann – ist ja sowieso immer an. So ist das Projekt zur Portierung von hyperion auf OpenWRT entstanden…

Das Problem…

Die Schwierigkeit hyperion auf anderen Systemen laufen zu lassen, liegt in seiner Implementierung. Die Software baut auf der Bibliothek Qt4 auf und macht die Umsetzung einiger Paradigmen (wie Beobachter Entwurfsmuster mittels Signal-Slot) denkbar einfach. Qt4 kann jedoch einiges mehr, vor allem im Bereich der User-Interaktion und grafischer Darstellung – hyperion benötigt das alles aber nicht. Durch diese enge Abhängigkeit kommt es dann auch zum anderen Problem: Qt4 ist nicht überall verfügbar (z.B. OpenELEC) und muss dann kompliziert über Installationsskripte in der richtigen Version nachinstalliert werden. Ein weiteres Problem ist die Effekt-Engine, die auf Python Bindings setzt. Die Engine erlaubt es zwar, die Effekte sehr einfach in Python zu schreiben, setzt aber auch die komplette Python Laufzeitumgebung auf dem Zielsystem voraus.

Der Lösungsansatz

Also war mein Ansatz: Benutze das, was überall da ist, kompiliere mit hyperion und liefere aus alles andere zusammen. Der zweite wichtige Punkt: Alle Plattform-Versionen müssen primär Cross-kompilierbar sein. Ich habe mir einige C++ Frameworks  angeschaut, die das Signal-Slot Prinzip ersetzen könnten und gleichzeitig die Umsetzung der Netzwerkkommunikation vereinfachen würden. Aus unterschiedlichen Gründen bin ich bei der Poco C++ Library gelandet und habe LUA als Ersatz für Python genommen. So ausgerüstet habe ich angefangen, hyperion zu portieren.

Letztendlich habe ich einige Teile von hyperion komplett umgeschrieben, sodass diese Version nicht mehr mit dem Original kompatibel ist. Auch die Konfigurationsdatei kann nicht mit dem HyperCon Tool generiert werden – langfristig habe ich ein eigenes Config Tool geplant, welches komplett im Browser läuft,  aber wie immer scheitert es meistens an der fehlenden Zeit für die Umsetzung. Momentan muss also per Hand editiert werden. Was komplett aus einer HyperCon generierten Datei übernommen werden kann ist die LED Konfiguration – da hat sich momentan noch nichts geändert. Der JSON Server unterstützt nur WebSocket Kommunikation, was auch dazu führt, dass so gut wie alle hyperion-remote Anwendungen damit nicht funktionieren, bis auf meine eigene 🙂

Der Code ist auf GitHub abgelegt, als separater Branch. Binaries sind nicht im Repository enthalten – sie haben im eigentlichen Code Repository auch nichts zu suchen und werden evtl. künftig auf der GitHub Projekt-Web-Seite zum Download angeboten. Ich empfehle jedoch die Binaries für eigenen Zusammenbau selbst zu bauen, da in meiner Version jedes LED Gerät und jeder Grabber optional ist und im Basisbuild nur Test-Ausgabegerät enthalten ist. Zu bedenken ist, dass der Code hoch experimentell ist und weit von der kompletten Portierung entfernt ist. Die meisten Screen Grabber wurden getestet, externe V4L2 Grabber dagegen gar nicht mangels passender Hardware. Protobuf wurde vorerst komplett entfernt.

Für meinen erwähnten Router mit OpenWRT gab es dann diese Eckpunkte für die Umsetzung mit hyperion:

  • LED Player S – lässt sich einfach an den vorhandenen USB Port anschließen
  • kein Screen Grabber notwendig, da nur zu Beleuchtungszwecken
  • JSON Server zur Steuerung über hyperion-remote
  • Effekt Engine

hyperion Bauen

Das Bauen von hyperion ist relativ einfach und auch recht simpel erweiterbar um zusätzliche Plattformen.

Gebaut wird im Falle von meinem Router auf Debian Jessie x64 – aus einfachem Grund, weil es dafür eine fertige Cross-Compile Toolchain gibt, und diese eben ein 64-bit Linux voraussetzt. Falls eine eigene Toolchain bereits auf dem System vorhanden ist, kann auch diese verwendet werden. Dazu muss die Umgebungsvariable TOOLCHAIN_DIR mit dem Pfad zu der Toolchain gesetzt werden.

`git clone https://github.com/Gamadril/hyperion.git
cd hyperion
./build.sh openwrt_ar71xx -DENABLE_LED_SERIAL_TPM2=ON -DENABLE_EFFECT_ENGINE=ON -DENABLE_SERVER_JSON=ON`

Der erste Parameter openwrt_ar71xx legt die Plattform fest, für welche hyperion gebaut werden soll. Für jede Plattform muss unter platforms ein gleichnamiger Ordner liegen mit zwei cmake Dateien (s. openwrt_ar71xx als Referenz). Alle nachfolgenden Parameter werden zur Konfiguration des hyperion Builds weitergeleitet. In diesem Fall wird die Unterstützung der seriellen Geräte mit TPM2 Protokoll aktiviert. Desweiteren die Effekt Engine und der JSON Server für die Fernbedienung.

Sollte alles gut gehen, wird im build Unterordner die hyperion.zip Datei liegen. Diese muss nun auf den Router  kopiert werden und dort installiert/entpackt werden. Das hat bei mir nicht geklappt, da trotz der kleineren Größe der Platz im Flash nicht ausreicht. Also wurde die Datei auf der USB Festplatte abgelegt (gemountet unter /media) und entpackt. Da sie bei mir mit FAT32 formatiert ist, ist die Erstellung der Links fehlgeschlagen, was beim ersten Start zu einer Fehlermeldung geführt hat. Als Lösung habe ich die Datei einfach umbenannt und dann gestartet.

`mv hyperion/lib/libPocoFoundation.so.1.6.1 hyperion/lib/libPocoFoundation.so.31
cd hyperion
LD_LIBRARY_PATH=/media/hyperion/lib ./hyperiond`

Normalerweise sollte beim Kompilieren der Suchpfad der Libraries als „./lib“ in hyperiond enthalten sein. Das hat beim Cross-kompilieren hier aus irgendeinem Grund nicht geklappt und ich hatte noch keine Zeit die Ursache dafür zu suchen. Evtl. sind in CMake die entsprechenden Parameter falsch vorgegeben. Deswegen wird beim Start der Ordner für die Bibliotheken per LD_LIBRARY_PATH mit angegeben.

Der Dienst sollte idealerweise beim Start automatisch starten und eine Konfigurationsseite in LuCI wäre auch sehr hilfreich. Darum habe ich mich aber auch nicht gekümmert. Ich starte hyperion von der Konsole und es läuft dann im Hintergrund.

`LD_LIBRARY_PATH=/media/hyperion/lib start-stop-daemon -S -b -x /media/hyperion/hyperiond`

Feedback und Vorschläge hier oder auf der GitHub Projektseite posten. 🙂

P.S. Der Player S gibt sich als ACM (USB Modem) Gerät aus und wird von OpenWRT wahrscheinlich nicht auf Anhieb erkannt (`/dev/ttyACM0` fehlt). Abhilfe schafft die Installation vom kmod-usb-acm Kernel Modul über die Web-Oberfläche oder die Kommandozeile.

6 Gedanken zu „hyperion mit OpenWRT

  1. Hallo Gamadril,
    vielen Dank für dieses howto und die damit verbundene Arbeit. Ich habe mich natürlich sofort darauf gestürzt: Debian Jessie x64 mit Cross-Compile-Umgebung und openWRT-ToolChain installiert – leider hakts dann auch gleich: in Deinem hyperion-git gibt es die build.sh nicht – ich bin jetzt nicht der Profi-Compiler – muss die erstellt werden?
    viele Grüße

  2. alles klar – in der zip ist die Datei auch drin gewesen – damit läuft es. Habe hyperion für das Ausgabegerät adalight gebaut. Die erstellte „libPocoFoundation.so.31“ ist aber nicht funktionsfähig (ist nur 1k gross) daher habe ich die „libPocoFoundation.so.1.6.1“ entsprechend umbenannt. Den hyperiond muss ich jetzt noch mit meiner Umgebung testen (adalight – also Arduino als Ausgabe und einen v4l2-Fushicai-Grabber). Ich werde berichten. Vielen Dank noch einmal für die Portierung auf OpenWRT!!!

  3. wieder etwas weiter… hyperiond läuft und steuert den arduino korrekt an. Eine kleine Stolperfalle in der „hyperion.config.json“ – beim Start meldet hyperion:
    „Not found delayAfterConnect“ und bricht ab.
    Lösung:
    in der hyperion.config.json den Parameter wie folgt einfügen
    „device“ :
    {
    „name“ : „MyPi“,
    „type“ : „adalight“,
    „output“ : „/dev/ttyACM0“,
    „rate“ : 115200,
    „colorOrder“ : „rgb“
    „delayAfterConnect“ : 1000
    },
    Als nächstes werde ich den Fushicai-Grabber einbinden.

Schreibe einen Kommentar