ESPuno und nymea Homeautomation

Hallo zusammen,

ich gehöre seit einigen Tagen auch zum illustren Kreis der ESPuino Besitzer. Nach dem Aufbau und 3D Druck des Gehäuses (hierzu bei Gelegenheit mal ein eigener Post) habe mich mich dran gesetzt um die Box in das Homeautomation System meiner Wahl - nymea - einzubinden.

Ich könnte mir vorstellen, dass das für den ein oder anderen interessant ist, daher hier eine kurze Projekt Vorstellung.

nymea

nymea hat aktuell nicht den Bekanntheitsgrad von Home Assistant, FHEM oder OpenHAB, daher zunächst ein paar Infos. Der große Vorteil von nymea liegt meines Erachtens darin, dass die Software recht Einsteiger freundlich ist. Während man bei anderen Lösungen vielfach Dinge in Konfigurationsdateien einrichten muss, läuft hier alles über die UI / App die es für alle möglichen Betriebssysteme kostenlos gibt. Beim Einrichten von Geräten macht sich nymea Netzwerk Discovery zunutze, so dass Geräte super einfach eingerichtet werden können. Ein MQTT Broker ist ebenfalls enthalten und man braucht keine zusätzliche Software wie Mosquitto.

Selbstredend ist nymea open source und kann recht einfach auf einem Raspberry PI installiert werden.

ESPuino Plugin

Ich habe mich nun dran gesetzt ein Plugin für nymea zu schreiben, welches einen ESPunio per MQTT verbindet. Man kann dann den aktuellen Status in der UI sehen, die Lautstärke ändern, die Buttons sperren, den Schlafmodus aktivieren, usw. Des weiteren macht sich das Plugin die REST API zunutze um den Inhalt der SD Karte anzuzeigen, so dass man auch direkt über die UI Dateien abspielen kann.

Ich habe ein kurzes Video aufgenommen um die Einrichtung und die aktuellen Funktionen zu zeigen:

Das Einrichten läuft hierbei wie folgt ab:

  • nymea findet ESPuino über mDNS.
  • Hat man den gefundenen ESPuino ausgewählt, dann erstellt nymea einen MQTT channel im internen broker (samt Benutzer Account für den ESPuino).
  • Das Plugin nutzt nun die Websocket API um die MQTT Einstellungen (hostname, port, username, password) direkt auf dem ESPuino zu setzen.
  • Danach startet das Plugin den ESPuino neu um die Einstellungen zu übernehmen.
  • Damit ist die Einrichtung abgeschlossen. Von nun an verbindet sich der ESPuino nach dem Einschalten immer automatisch mit nymea.

Magie

Regel basierte Automatisierungen werden in nymea Magie genannt. Hier noch eine kleine Spielerei, um zu Zeigen was mit Homeautomation möglich ist. In diesem Video habe ich eine ‚Schlafen‘ Magie erstellt. Diese fährt die Rolläden runter, sobald Abends per Karte etwas abgespielt wird. Hat man Zigbee Lampen verbunden, dann könnte man jetzt auch noch das Nachtlicht einschalten.

Status und Code

Wie ihr sehen könnt funktioniert das ganze schon recht gut. Es gibt aber noch ein paar Kleinigkeiten, die ich noch beheben will, bevor ich einen Pull Request für nymea erstelle. Falls Interesse besteht: der Plugin code findet sich hier.

Zudem habe ich gesehen, dass ja auch gerade ein Refactoring des Webinterfaces stattfindet. Vermutlich macht es Sinn die Änderungen auch noch abzuwarten.

Feedback MQTT in ESPuino

Zu guter Letzt sind mir auch noch ein paar Kleinigkeiten in der ESPuino Software aufgefallen. Ich hoffe es ist ok diese hier zu erwähnen. Vielleicht kann @biologist mir ja sagen, welche der Änderungen akzeptabel sind? Einen Teil davon kann ich vermutlich selbst implementieren und einen PR stellen.

  • [ ] mDNS: Aktuell fehlt ein Mechanismus um per mDNS zu erkennen, dass es sich auch wirklich um einen ESPuino handelt. Hier könnten zusätzliche Einträge (addServiceTxt) Abhilfe schaffen.
    • Also etwa: app=espuino.
    • Eine eindeutige ID wäre hier auch hilfreich, um mehrere Geräte auseinander zu halten (id=<uuid>). Aktuell nutze ich den hostnamen zur Identifizierung. Das führt jedoch dazu, dass man das Gerät aus nymea löschen und neu hinzufügen muss, wenn man den Hostnamen über das Webinterface ändert. UPDATE: Mit Arduino-ESP32 1.0.6 aktuell nicht möglich. Da ist leider ein deutliches Ruckeln zu hören. In 2.x ist das behoben.
  • [x] ClientId: MQTT Broker erwarten normalerweise eine eindeutige ClientId. Aktuell ist jedoch DEVICE_HOSTNAME auf ESP32-ESPuino gesetzt. Würde es nicht Sinn machen, hier einfach den WLAN hostnamen zu nehmen? Oder auch die generierte Id?
    Seit Version 20221014-2 kann man die ClientId in der WebUI konfigurieren.
  • [ ] Es gibt keine MQTT State Nachricht für den Play/Pause.
  • [x] Cover: Es gibt keine MQTT Nachricht für eine Änderung vom Coverbild. Aktuell aktualisiere ich das Coverbild nur wenn sich die abgespielte Datei ändert. Das klappt aber leider nicht zuverlässig, ich habe den Eindruck das Coverbild ist da oft noch nicht fertig geladen. Über das Websocket gibt es so ein „coverimg“ event, welches an allen möglichen Stellen verschickt wird. Das wäre für MQTT auch schön zu haben.
    Seit Version 20221019-1 wird eine leere Nachricht topicStateCoverChanged verschickt.
  • [x] Restart: Wenn man den MQTT broker neustartet und sich ESPuino verbindet, dann sind erst mal Dinge wie der aktuelle Track auf initiale Werte (hier „—“) gesetzt. Erst wenn die nächste Datei abgespielt wird versendet ESPuino ein Update über MQTT mit den korrekten neuen Werten. Klar, das ist keine große Sache, normalerweise läuft der MQTT broker ja dauerhaft.
    Seit Version 20221019-1 wird der Status richtig initialisiert.

Freue mich auf euer Feedback,
Viele Grüße Christian

1 „Gefällt mir“

Kannst in die Wlan.cpp gerne im Rahmen vom PR einfügen. Ich brauch’s nicht, aber mich stört’s auch nicht.

Änderst du den Hostnamen regelmäßig? :slight_smile:
Wie auch immer: Schlage was vor, wie man die generiert.

Da bin ich emotionslos. Letztlich ist das für mich ein technischer Bezeichner, der nur irgendwo in einem Broker-Log auftaucht. Wenn wir das mit Hostname besser taugt, dann kannst es gerne auf NVS umbauen. Ich selbst kodiere ab DEVICE_HOSTNAME hinter dem String „ESPuino“ immer noch „-“ ein. Damit ist das alles unique und so heißen die Geräte hier auch im WLAN.

Das stimmt nicht. In topicTrackControlCmnd ist das die 3.

In die WebGUI hat @tueddy das Ganze einbaut. Es hat jedoch auch Bauchweh gemacht wenn die Coverarts größer waren, denn dann hat das Ganze en bloc zu viel Rechenzeit benötigt und daher für Ruckler beim Start gesorgt.
Im Zweifelsfalle jongliert man da mit größeren Strings und muss austesten, ob das zu irgendwelchen Problemen (Timing/Rechenzeit, Speicher/Heap-Fragmentierung) führt. Und dabei darf man dann auch nicht vergessen, dass der WLAN-Empfang kacke sein könnte. Ne WebGUI rufst du halt aktiv auf und wenn sich das irgendwie zäh aufbaut, dann hast vielleicht ne Vermutung, dass der WLAN-Empfang nicht so gut ist. Bei MQTT läuft das halt ständig im Hintergrund. Wenn es da Probleme gibt dann musst erstmal drauf kommen, dass es an MQTT liegen könnte. Initial umgesetzt, da mache ich keinen Hehl draus, habe ich es schon deswegen nicht, weil ich selbst keine Coverarts pflege. Aber davon ab habe ich so meine Bedenken, ob das ne gute Idee ist, ständig mehr oder weniger große MQTT-Nachrichten zu versenden.
Aber ja, ich glaube die Frage wurde mir schonmal gestellt.

Habe das Problem nicht verstanden.
Aber (falls das was hilft): Ich persönlich arbeite mit dem Zustand online/offline. Weil bei mir ist die Anzeige in openHAB dynamisch und die ganzen Steuerungs- und Infoelemente werden nur angezeigt, wenn im Topic online steht. Da man jedoch auch einfach den Stecker aus dem ESPuino rausziehen kann und dann kein geordneter MQTT-Shutdown stattfindet, wird das Topic mit online/offline zyklisch aktualisiert und timed bei mir in openHAB aus, wenn das nicht der Fall ist. Auch dann klappe ich das Menü ein.

Ansonsten: Coole Sache - Nymea kannte ich tatsächlich nicht. Ich versuche mich schon ewig dazu aufzuraffen OH2 (welches „nativ“ auf einem Raspi3 läuft) durch ein OH3 (welches schon seit Monaten halb-migriert in einem Docker-Container auf einem Raspi4 läuft) komplett abzulösen. Aber bei OH ist man groß darin, Dinge nicht wirklich (oder nur teilweise) abwärtskompatibel zu machen.
Naja, dieses Jahr vielleicht noch :rofl:.

Hier hatte ich tatsächlich einige Probleme. Sobald ich app=espuino mittels addServiceTxt hinzufüge, bekomme ich leichte Audio Ruckler. Wenn ich dann auch noch mac=<WLAN-MAC-ADDRESS> dazunehme, ruckelt es wirklich stark. Ich kann mir das ganze ehrlich gesagt nicht wirklich erklären.

Das habe ich nun in MQTT improvements by fetzerch · Pull Request #160 · biologist79/ESPuino · GitHub umgesetzt.

Sorry, da habe ich mich falsch ausgedrückt. Es gibt keine state Nachricht für Pause. D.h. wenn ich auf der Box pause drücke wird nichts versendet und die Home automation kann nicht erkennen, dass gerade pausiert wird. Denke hier würde eine neue Nachricht topicTrackControlState Sinn machen. Vorschlag: 0=Stopped, 1=Playing, 2=Paused?

Moment, also meine Idee war nicht das Cover Bild über MQTT zu verschicken. Mein Vorschlag wäre eine MQTT state Nachricht an den Stellen zu verschicken, an denen sich das Bild geändert haben könne. Also dort wo Web_SendWebsocketData(0, 40); aufgerufen wird. Im Prinzip nur eine ‚leere‘ State Nachricht.

Die Probleme mit den Rucklern kann ich natürlich nachvollziehen. Allerdings verhält sich Nymea hier genau wie das Webfrontend. Das Bild wird von der App nur dann geladen, wenn diese auch geöffnet ist. Ich kann natürlich nicht für andere Home Automation Systeme sprechen, aber es liegt meiner Meinung nach dort auch in der Verantwortung der Plugin/Integrationsunterstütztung das Covers nur bei Bedarf zu laden.

Hier habe ich mich vielleicht auch nicht korrekt ausgedrückt. Was ich meinte ist ESPuino/Mqtt.cpp at d5828e42210eab3f8d694c45f031d1a3d6e88838 · biologist79/ESPuino · GitHub. Wenn die Verbindung zum Broker erst klappt, nachdem bereits etwas abgespielt wird, dann erhält der Broker nur „—“. Die anderen States habe ich in MQTT improvements by fetzerch · Pull Request #160 · biologist79/ESPuino · GitHub gefixt. Der Titel ist leider tatsächlich schwieriger.

Vielen Dank! :slight_smile: Das kommt mir sehr bekannt vor :wink:

Tja, da hatten wir hier schon diverse Bugs, die ganz plötzlich aufgetreten sind und dann irgendwann auch wieder weg waren.

Ist ok für mich.

Auch ok für mich.

Der ist halt im Endeffekt beliebig lang und ggf auch nicht gesetzt. Ich hab’s mir einfach gemacht und halt den Pfad genommen.

Ansonsten danke für die PRs. Vor allem, dass auch beschrieben ist, was genau sie bezwecken :+1:
Ich schaue mir das an.

Das Plugin kann nun in nymea direkt installiert werden. Aktuell muss dazu noch ‚experimental‘ aktiviert werden. Mit dem nächsten offiziellen nymea release sollte es dann auch im stabilen Zweig enthalten sein.

In die eben erschienene Nymea Version 1.6 ist die Unterstützung für den ESPuino nun als Plugin eingeflossen: Nymea 1.6 release notes - Releases - nymea:forum

2 „Gefällt mir“