Neues Namensschema für MQTT

Das Thema wurde hier schon öfter andiskutiert - ich wollte es jetzt final endlich mal umsetzen.

Aktuell sieht das Namensschema wie folgt aus:

constexpr const char topicSleepCmnd = „Cmnd/ESPuino/Sleep“;
constexpr const char topicSleepState = „State/ESPuino/Sleep“;
constexpr const char topicRfidCmnd = „Cmnd/ESPuino/Rfid“;
constexpr const char topicRfidState = „State/ESPuino/Rfid“;

Eigentlich wäre es besser, ESPuino ganz vorne zu haben. Dazu kommt noch, dass in einigen Haushalten mehr als ein ESPuino vorhanden ist. Insofern wäre es auf jeden Fall sinnig, hier zusätzlich auch einen zusätzlichen Namen mit reinzubringen. Der Einfachheit halber könnte dies derjenige sein, der in DEVICE_HOSTNAME steht.

D.h. das Namensschema wäre dann:

{DEVICE_HOSTNAME}/{Cmnd/State}/{Aktion}

Frage1: Passt das so für euch?
Frage2: (vielleicht an @laszloh): Wie konkatteniert man am besten constexpr?

Ergänzend zieht man das alles zusätzlich ins Webinterface, da wir die Kladde für MQTT dort eh schon haben. D.h. man braucht eine grundsätzliche Initialisierung, die erstmal auf Basis dessen, was wir in der settings.h haben, die MQTT-Channels anlegt und als JSON(?) im NVS speichert. Vom Webinterface aus kann man diese Pfade dann abweichend konfigurieren und bei einem Neustart wird’s entsprechend geladen. Man müsste es auch nicht unbedingt als JSON machen, aber vermutlich wäre es so am saubersten.
Vielleicht lässt man das jedoch auch weg und bläht den Code nicht zusätzlich auf, da man MQTT-Channels für gewöhnlich eigentlich nicht ständig ändert.

Meinungen sind erwünscht!

1 „Gefällt mir“

Hi,

wäre es nicht sinnvoll sich an die Spezifikationen von Homie zu halten, wenn es ohnehin komplett angepasst werden soll?

https://homieiot.github.io/

Ich habe mich damit selbst noch nicht beschäftigt, weiß nur, dass es von vielen genutzt und auch erkannt wird, bspw. von OpenHab.

Viele Grüße
Sven

Ich werfe da auch die Auto Discovery für Home Assistant in den Raum.

Homie wird von OpenHab nativ und in HomeAssistant mit PlugIn unterstützt. Das HomeAssistant Schema wird dort nativ und in OpenyHab mit PlugIn unterstützt.

Es scheint also vollkommen egal, was wir nehmen…

Ist das dann immer der atuell eingestellete Hostname? oder das feste DEFINE?

  1. würde ich bevorzugen

Hallo,

ich fände das gut, dann muss man bei zwei ESPuinos nicht den Namen in der settings.h immer anpassen bei einer neuen Firmware und kann sich somit dann auch nicht vertippen :slight_smile:

Ich hoffe es ist nicht zu off topic. Kann es sein, dass wenn man den ESPuino startet und zu früh einen Tag auflegt, dieser nicht per MQTT gesendet wird ? Es ist bei mir sogar so, dass ein erneutes aufstellen des gleichen Tags nicht hilft. Man muss erst einen anderen aufstellen und dann wird auch der erste wieder korrekt übermittelt. In der aktuellen DEV.

Noch keine WLAN Verbindung? Das Problem tritt auch beim Auflegen einer Karte mit Webradio auf und ist hier bereits Thema.

Ja das ist so. Oder wenn die Verbindung gerade erst hergestellt wurde und noch nicht lange besteht. (Also led schon weiß).

Hi,
Ich würde folgendes Namensschema vorschlage: ESPuino/<DeviceID>/<function></set> (also zB ESPuino/02DEFA/sleep zum abfragen und ESPuino/02DEFA/sleep/set zum schreiben).

Damit könnte man zB folgende Hierarchie für den Sleep Befehl machen:

ESPuino/02DEFA/sleep:       Gibt ein JSON mit den aktuellen modus + timeout und optional verbleibende zeit zurück
ESPuino/02DEFA/sleep[/set]: Empfängt ein JSON und setzte den Sleep System entsprechend

oder ein komplexere Struktur:

ESPuino/02DEFA/sleep/mode[/set]:     Gibt/Setzte den Sleep mode (also [OFF|TIMER|PLAYLIST])
ESPuino/02DEFA/sleep/timer[/set]:    Gibt/Setzt den Timeout für den Schlafmodus (zB verbleibende Minuten)
ESPuino/02DEFA/sleep/playmode[/set]: Gibt/Setzt bis welchem Playlist-Eintrag gespielt wird

Meine Überlegung hinter der Struktur ist, dass wenn man MQTT mit Handler macht, nur zB bis ESPuino/02DEFA/Sleep vergleichen muss um zu wissen an wen die Nachricht geht (dieser wiederum schaut danach nur an das nächste Stück, zB Mode/Cmd, Timeout/Cmd (oder nur Cmd wenn wir JSON verwenden wollen).


Als ID würde ich die MAC-Adresse mit XOR reduziert vorschlagen (bzw das es auch vom User dann über NVS geändert werden kann).
Wir würden hierbei das constexpr verlieren, da es keine Möglichkeit gibt zur Compilezeit die MAC/ID zu kennen. Es scheint auch, dass in C++17 constexpr string concat nicht ganz trivial ist (hab es selber noch nicht verwendet).


Wegen der HA Auto Discovery, ich denke dass das machbar ist. Wenn ich das richtig gelesen habe, schickt man „einfach“ für jeden unterstützten logische Einheit / Componente in der MQTT eine standardisierte Nachricht an HA. Ich spiele mich gerade mit der Frage wie man das elegant lösen kann und wie viel zusätzlicher Code das ist. Grundsätzlich geht das sehr einfach oder sehr extensiv, wie alles im Leben :smiley:.


Eine Frage an euch, wie steht ihr dazu die MQTT Library zu wechseln? Ich habe da den Fork von AsyncMqttClient für esphome im Auge. Vorteil ist, dass der MQTT Loop hier nicht aufgerufen werden muss, sondern (analog zu dem AsyncWebserver) ein AsyncTCP thread. Es ist hier relativ einfach ein Callback-System (so in etwa: MqttPubSub.h) da rauf zu setzten, womit dann im Haupt-Code man nur noch ein Handler registrieren muss.
Auch ist der PubSubClient ist halt seit 4 Jahren nicht mehr angerührt worden, mit ein paar offenen Bugreports.

Ich bin aber auch für alternativen offen :wink:

Gruß,
Laszlo


edit: Habe die mqtt Pfade ein wenig geändert (in Anlehnung an homie). Grundsätzlich schaut auch er recht interessant aus. Muss mich noch spielen :slight_smile:

Warum nicht den Hostname als ID?
Ich gebe meinen Kindern Namen also sollte ich das für einen ESP auch schaffen :wink:

1 „Gefällt mir“

Das war jetzt einfach die perfekte Vorlage für:

:smile:

2 „Gefällt mir“

Also wie die Struktur im Detail genau aussieht, ist mir persönlich nicht sonderlich wichtig, da ich damit eh nur einmal bei der Einrichtung zu tun habe. Bei der aktuellen Struktur gefällt mir inzwischen auch nicht mehr, dass wir cmnd/state vorne stehen haben - da habe ich mich damals von Tasmota glaube ich leiten lassen.

Also wenn wir nen einheitlichen Standard wie Homie als gemeinsamen Nenner nehmen, dann soll mir das recht sein. Aber da speziell für HA jetzt Sonderlocken zu machen, da habe ich ehrlich gesagt ein bisschen ein Problem mit. Also ja, das ist aktuell der heiße Scheiss, aber vielleicht sieht das in paar Jahren auch anders aus und nicht zuletzt kommen dann sicherlich nach und nach weitere User und wollen für weitere Systeme ebenfalls direkten Support. Also ich bin da (sage ich ganz ehrlich) einfach nicht bereit, mir neben OpenHAB weitere Systeme zu installieren, um dann zu testen. Ich meine laufen tut das ja so oder so mit MQTT als einheitlicher Schnittstelle.

Für den dynamischen Anteil im MQTT-Pfad schlage ich vor, dass man den Hostname verwendet und gleichzeitig aber bei der initialien Festlegung des Hostname (im AP-Modus) einen dynamischen Anteil reinbringt und direkt im Feld einfügt. An dieser Stelle kennt ESPuino auch die MAC-Adresse und man könnte dann einen Hostname alà ESPuino-{mac} nehmen.

Da bin ich voll bei dir. Soweit mir bekannt ist, gab’s damals, als ich mit ESPuino angefangen habe, für den ESP32 keine Alternativen. Inzwischen gibt es wohl mehrere. Also da wäre ich offen für Veränderungen, habe jedoch auch keinen „Marktüberblick“.

Weil ich nicht daran gedacht habe :astonished:. Hostname ist eine 1A Idee und ja, ich musste auch an xkcd denken :wink: . ESPuino-{mac} gefällt mir auch gut. Ich zB setzte nie die Hostname extra, womit ich schon öfters 3 Espunio gleichzeitig mit den gleichen Hostname in Netzwerk hatte. Mit dem dynamischen Anteil haben wir auch dann eine einzigartige ID und damit beide Lager bedient.

Ich würde auch nicht beide Supporten wollen, wir wählen eines der Beiden und bleiben bei diesem. Die Nutzer der anderen Heimautomatisation müssen (wenn sie die Discovery nutzten wollen) dann halt ein Plugin installieren, oder händisch die Endpunkte eintragen.
Sowohl für HA-Discovery als auch openHAB gibt es Arduino Libraries, somit denke ich dass das recht leicht zu implementieren ist. Homie gefällt mir nach längerem Lesen der Spezifikation auch besser (da es ein Wenig einfacher ist als das von HA).


Für die Endpunkte würde ich folgende Struktur vorschlagen. Diese sollten die aktuellen Features von MQTT in der Homie-Spezifikation (1 Endpunkt pro Node und darunter 1 Endpunkt / Property) abdecken. Das ist wahrscheinlich nicht ganz vollständig:

  • sleep ( ← Node )
    • mode [set]: enum <OFF|TIMER|PLAYLIST> ( ← Property )
    • timer [set]: duration
    • playmode [set]: enum <OFF|EOT|EOP|A5T> (end of track, end of playlist, after 5 tracks)
  • rfid: number [set]
  • playlist
    • playlist-tracks: number
    • type: enum <music|webstream|m3u|audiobook>
    • folder: string
  • playback
    • path: string
    • track-title: string
    • cover: boolean (true if the track has a cover → server responsible to load it only once)
    • track-number: number
    • action [set]: enum <PLAY|PAUSE|TOGGLE|STOP|NEXT|PREV|FIRST|LAST>
    • volume [set]: percent (statt number [0-21], in der GUI kann man auch nicht höher als „max“ machen)
    • position [set]: percent (für seeking)
    • repeat [set]: enum <OFF|TRACK|PLAYLIST|BOTH>
  • button
    • lock [set]: boolean
  • led
    • brightness [set]: number [0-255] (wobei percent wäre logischer)
    • nightmode [set]: boolean
    • night-brightness [set]: number [0-255] (wobei percent wäre logischer)
  • wifi
    • ssid: string
    • localip: string
    • rssi: number
    • quality: percent
  • battery
    • voltage: number
    • charge: percent
    • charging: boolean (nur wenn wir es auch auslesen können)
  • state
    • uptime: number
    • playtime: number
    • firmware: string

Für die Device Attributes: The Homie convention

Was ich hier noch nicht drin habe:

  • Bluetooth
  • NVS (zB RFID Tags auslesen / setzten)
  • SD-Karte browsen (ka ob / wie das über MQTT aussehen könnte)
  • Playback von einzelnen Tracks
  • FTP

Wie immer, Ideen und Kritik willkommen :slight_smile:

1 „Gefällt mir“