MQTT Topic Tree Design - bewährte Verfahren, Tipps und Beispiele
Generischer MQTT-Hintergrund
Bei MQTT wissen Sender und Empfänger nichts voneinander - der Broker übernimmt die Nachrichtenübermittlung. Dadurch können die Nachrichten räumlich, zeitlich und in ihrer Intensität voneinander getrennt werden. Der Sender kann mit der von ihm gewünschten Geschwindigkeit und zum gewünschten Zeitpunkt senden. Der Empfänger kann die Nachrichten in der von ihm gewünschten Geschwindigkeit und zum gewünschten Zeitpunkt abrufen. Sender und Empfänger müssen sich nicht kennen, und es muss keine direkte Verbindung zwischen ihnen bestehen (wie z. B. bei einer Telefonleitung). MQTT ermöglicht den einfachen Aufbau von Multicast-Konfigurationen, bei denen ein Sender an viele abonnierte Empfänger senden kann.
- Die Clients wissen nicht, wer die Nachricht ursprünglich veröffentlicht hat - es sei denn, dies geht aus dem Thema (und möglicherweise durch ACLs beim Broker erzwungen) oder aus dem Inhalt der Nachricht (möglicherweise mit HMAC signiert) hervor.
- MQTT ist für die Kommunikation mit geringem Stromverbrauch und niedriger Latenzzeit konzipiert (HMAC usw. kann teuer sein)
- Sie können keine Liste aller Themen von einem Broker erhalten. Der Broker verwirft Nachrichten (und Themen), die niemand abonniert hat (möglicherweise nur dann vollständig wahr, wenn das Retain-Flag nicht gesetzt ist)
- Sie wissen nicht, wer ein Thema abonniert hat (verwenden Sie ACLs, um Abonnements von nicht autorisierten Clients zu begrenzen)
letzter Wille und Testament / am Leben erhalten
Die Clients können eine Verbindung herstellen, eine Nachricht veröffentlichen und die Verbindung beenden oder eine dauerhafte Verbindung zum Server aufrechterhalten. Im Falle einer dauerhaften Verbindung werden Keepalives gesendet. Wenn der Client innerhalb des beim Verbindungsaufbau vereinbarten Zeitrahmens keine Keepalives sendet, kann der Server (Broker) eine so genannte Last-Will-and-Testament-Nachricht senden, die der Client beim Verbindungsaufbau übermittelt hat. Diese Nachricht kann beliebig sein und kann veröffentlicht werden an ein einziges Thema pro Verbindung. Der Broker sendet sie an alle Kunden, die sich für dieses Thema angemeldet haben.
Wenn der Kunde die Verbindung ordnungsgemäß beendet, wird das Testament nicht veröffentlicht.
Die Funktion "Keep Alive" ist vor allem für mobile Clients nützlich, bei denen die Verbindung unterbrochen werden kann (z. B. bei schlechten Netzwerken, Tunneln usw.).
Siehe auch:
http://www.steves-internet-guide.com/checking-active-mqtt-client-connections/
http://www.steves-internet-guide.com/mqtt-last-will-example/
https://owntracks.org/booklet/tech/mqtt/
Kunden-ID / Kundenübernahme
Jeder Client, der sich mit einem MQTT-Broker verbindet, sollte eine eindeutige Client-ID haben. Clients, die sich mit der gleichen Client-ID verbinden, beenden die vorherige Verbindung und übernehmen die neue. Wenn Sie zwei Clients mit der gleichen Client-ID haben, kann dies zu einem Ping-Pong von getrennten Verbindungen führen.
Zurückbehaltene Nachrichten
Die zuletzt Eine erhaltene Nachricht an ein Thema wird gespeichert und an alle neuen Abonnenten dieses Themas zugestellt. Dies kann für die Kommunikation von Gerätestatus / Konfiguration / etc. verwendet werden.
Sie setzen den Aufbewahrungszustand als Kennzeichen pro Nachricht.
Zurückgehaltene Nachrichten können für viele interessante Dinge verwendet werden, z. B. zur Erleichterung der automatischen Suche (siehe Vorschlag 4 unten).
Dienstgüte / QoS
Es gibt drei Stufen der Dienstgüte, die bestimmen, wie viel Overhead bei der Verarbeitung einer Nachricht anfällt. Je höher die Stufe, desto mehr Overhead.
- 0: keine Garantien jeglicher Art
- 1: die Nachricht wird mindestens einmal gesendet (Duplikate möglich)
- 2: die Nachricht wird genau einmal gesendet (keine Duplikate möglich)
Die QoS kann für jede an den Broker gesendete Nachricht und während des Abonnements festgelegt werden. Der niedrigere der beiden Werte wird für die tatsächliche Zustellung der Nachricht verwendet.
Weitere Einzelheiten finden Sie hier:
https://www.eclipse.org/paho/files/mqttdoc/MQTTClient/html/qos.html
Themen
Fakten zu den Themen
Bei Themennamen wird zwischen Groß- und Kleinschreibung unterschieden, und es handelt sich um UTF-8-Strings. Es ist ratsam, sich auf druckbare ASCII-Zeichen zu beschränken, um die Fehlersuche zu erleichtern.
Themennamen müssen aus mindestens einem Zeichen bestehen, um gültig zu sein.
/
ist bereits ein Themenname
Die $SYS ist für die Broker-Nutzung/Statistik gedacht.
Sie haben die Wahl, ob Sie die Informationen in der Themenstruktur oder in der Nachricht unterbringen. Eine JSON-Struktur für die Nachricht hilft Ihnen dabei, sie mit weiteren Daten zu erweitern.
Bedenken Sie, dass bei jedem Aufruf des Brokers das Topic in der Nutzlast des MQTT-Pakets mitgeschickt wird - versuchen Sie daher, unnötige Längen zu vermeiden.
Verwendung von Platzhaltern berücksichtigen
- # stimmt mit allem überein, was für eine beliebige Stufentiefe ab der aktuellen Stufe gilt (mehrstufiger Platzhalter, kann nur am Ende eingefügt werden)
- + passt zu allem auf der aktuellen Ebene (einstufiger Platzhalter)
Wenn Sie z. B. mehrere Temperatursensoren haben, können Sie problemlos Nachrichten für alle von ihnen abonnieren, wenn Sie Ihren Themenbaum richtig gestalten.
Wild Cards sind nur für Abonnenten gedacht, sie sind nicht zur Veröffentlichung zugelassen.
Sie können alle Themen abonnieren mit #
mit Ausnahme des Themas $SYS. Verwenden Sie $SYS/#, um alle Themen für $SYS zu abonnieren
Möglicherweise können Sie durch die Verwendung des Teils "Funktion" vor der Gerätekennung bestimmte Kanäle leichter abonnieren.
Wenn Sie zum Beispiel Ihre Pfade wie folgt definieren tele/room1/sensorname1 tele/room2/sensorname2 usw. und stat/room1/sensorname1 stat/room1/sensorname2 Abonnements sind möglich auf:
tele/#
stat/#
Wenn Sie es andersherum machen, mit Sensor1/Stat und sensor2/statusw. können Sie verwenden
+/stat
um Statistiken zu abonnieren, aber nicht in beliebiger Tiefe wie im vorherigen Beispiel. Das heißt, der Pfad zu Ihrem Sensor muss aus genau einer Komponente bestehen.
Wenn Sie die Aktion vorwegnehmen, werden Ihre Pfade konsistenter sein.
Siehe zum Beispiel https://stevessmarthomeguide.com/setting-up-the-sonoff-tasmota-mqtt-switch/
Nicht
- Verwenden Sie keinen vorangestellten Schrägstrich (z. B. /mytopics ), um Ihren Themenbaum zu beginnen - das ist ein zusätzlicher Aufwand, der keinen Wert hat.
- Nicht verwenden $SYS als Startthema, dies ist dem Makler vorbehalten
- Verwenden Sie keine Leerzeichen im Thema
- Verwenden Sie keine nicht druckbaren Zeichen im Thema
- ein MQTT-Topic für Nachrichten mit unterschiedlicher Bedeutung verwenden - verschiedene Topics für sie erstellen
Vorschläge / Tun
- Client-ID in den Themenbaum einbetten
- spezifische Themen für die individuelle Adressierung (z.B. von Sensoren) erstellen, anstatt alle Werte über ein Thema zu senden - dadurch wird vermieden, dass Nachrichten an Empfänger gesendet werden, die sie nicht benötigen
- Versuchen Sie, die Themennamen kurz zu halten (da sie bei jeder Veröffentlichung und Nachricht gesendet werden)
- überlegen, welche Daten wie oft gesendet werden müssen
o z.B. erwägen, Metadaten in ein eigenes Thema auszugliedern und mit einem "Retain"-Flag zu veröffentlichen
- Befehls-/Cmd- und Statusthemen für ein Gerät trennen - auf diese Weise wird eine bidirektionale Kommunikation möglich, und das Gerät muss seine eigenen Nachrichten nicht filtern.
- eine testamentarische Nachricht verwenden, um auf eine unerwartete Trennung des Kunden hinzuweisen
Mehrmandantenfähigkeit und Bridging berücksichtigen
Müssen Sie mehrere Kunden / Organisationen / unabhängige Anwendungen unterstützen? Es gibt die Möglichkeit, z. B. mit VerneMQ, verschiedene Mountpoints zu verwenden. Eine weitere Alternative besteht darin, die Mehrmandantenfähigkeit in Ihren Themenbaum aufzunehmen (durch Verwendung eines entsprechenden Präfixes am Anfang des Themenbaums).
Ich bevorzuge den ersten Weg, da er eine zusätzliche Ebene der ACL-Trennung bietet - und weniger Möglichkeiten, etwas zu "vermasseln".
Außerdem möchten Sie vielleicht mehrere MQTT-Broker miteinander verbinden und einen Teil ihrer Themenbäume (wie durch ihre ACLs definiert) gemeinsam nutzen.
Weitere Informationen zur Überbrückung finden Sie unter https://owntracks.org/booklet/guide/bridge/.
Verschlüsselung erwägen
MQTT kann über verschlüsselte Netzwerke (z.B. über Websockets / TLS verschlüsselt) oder über unverschlüsselte Kanäle betrieben werden. Zusätzlich können Sie die Nutzlast Ihrer Daten verschlüsseln und/oder signieren.
Auffindbarkeit berücksichtigen
Erwägen Sie, Themen einzubauen, die die Auffindbarkeit von Diensten und Fähigkeiten Ihrer Geräte erleichtern, z. B. durch die Verwendung gespeicherter Nachrichten.
Rückmeldungen über Befehle berücksichtigen
Wenn Sie einen Befehl veröffentlichen, haben Sie keinen unmittelbaren Rückkanal. Daher könnte es sinnvoll sein, eine Hierarchie für spezifische Rückmeldungen zu bestimmten Befehlen einzurichten - ob das Gerät den Befehl erhalten hat und ausführen konnte, um dem Benutzer eine Rückmeldung geben zu können.
Ein Muster, das ich hier anzuwenden gedachte, war die Vergabe eindeutiger Befehlskennungen als Teil der Nutzlast der Nachricht, die im Rückkanal mit einem Statuscode referenziert werden.
Multicast-Szenarien berücksichtigen
Möchten Sie, dass mehrere Geräte auf eine einzige von Ihnen veröffentlichte Nachricht reagieren? Denken Sie daran, dass Sie keine Platzhalterthemen veröffentlichen können - Sie können sie nur abonnieren. In diesem Fall sollten zusätzliche Themen erstellt werden, die es den Clients ermöglichen, auf Multicast-Szenarien zu reagieren. Alle Clients / alle Clients einer bestimmten Gruppe würden das Multicast-Thema abonnieren und auf die Nachrichten reagieren.
Kombiniert man dies mit meinem obigen Vorschlag zur Rückmeldung / Bezugnahme auf die Befehls-ID, wird eine neue Anforderung an die Client-ID als Nutzlast im (generischen) Rückmeldekanal eingeführt. Eine andere Möglichkeit ist, die Geräte auf ihren individuellen Rückmeldekanälen antworten zu lassen - wobei die Geräte-ID bereits Teil des Pfades ist. (Das heißt, sie empfangen einen Befehl auf dem Multicast-Pfad, antworten aber in ihrer eigenen exklusiven Nachrichtenhierarchie).
Berücksichtigung von Verkehr und Datenschutz, Sensortypen
Wenn Sie ein kommerzielles System betreiben, das z. B. Sensordaten für Benutzer sammelt, möchten diese vielleicht genau steuern können, welche Sensorwerte überhaupt veröffentlicht werden.
Außerdem erhöht die automatische Veröffentlichung aller Sensormesswerte den Datenverkehr und die Belastung Ihres Servers bzw. Ihrer Server.
Daher ist es möglicherweise nicht die beste Wahl, einfach alle verfügbaren Sensorwerte an Ihren MQTT-Broker zu senden. Eine Möglichkeit besteht darin, ein "Retained Topic" mit einer Konfiguration zu erstellen, die der Client abonnieren kann. Wenn der Client eine Verbindung herstellt, empfängt er automatisch die Konfiguration im Retained Topic und kann die Werte, die er veröffentlicht, entsprechend der Konfiguration anpassen. Außerdem kann er auf Konfigurationsänderungen reagieren, indem er auf alle zusätzlichen Nachrichten reagiert, die in diesem Konfigurationsthema eingehen.
Außerdem ist es wichtig zu berücksichtigen, dass es verschiedene Arten von Sensoren gibt. Bei einem Türsensor wären Sie beispielsweise an einer Statusänderung (geschlossen vs. offen) interessiert, während Sie bei einem Temperatursensor vielleicht kontinuierliche Messwerte erhalten möchten. Es ist wichtig, dass Sie bei Ihrem Entwurf berücksichtigen, welche Art von Werten die Teilnehmer erhalten, wenn der für die Sensormesswerte zuständige Client die Verbindung trennt. Denken Sie daran, dass Sie einen letzten Willen nur für ein Thema festlegen können (bei Multisensorgeräten). Im Falle einer Verbindungsunterbrechung könnten zurückbehaltene Nachrichten einen falschen Eindruck vermitteln (z. B. dass die Tür offen ist, obwohl sie in Wirklichkeit geschlossen ist, aber nicht aktualisiert wurde usw.).
Wenn jedoch beispielsweise Ihr Webinterface, das den Client steuert, erst verbunden wird, nachdem der Türsensor-Client bereits eine Weile verbunden war, und Sie nicht gespeicherte Nachrichten verwenden, wird die Nachricht über die letzte Aktualisierung des Türstatus verpasst;
Hier gibt es zwei Möglichkeiten:
- aktiv eine Aktualisierung des Türstatus anzufordern (z. B. durch Verwendung eines eigenen Get-Themas)
- Verwendung von aufbewahrten Nachrichten und Verwendung der clientseitigen Logik der Webschnittstelle, um den letzten Wert zu verwerfen, falls der Client selbst nicht verbunden ist / als veraltet markieren
In jedem Fall sollte der Benutzer darauf hingewiesen werden, ob einem Sensormesswert vertraut werden kann oder ob er möglicherweise aufgrund eines nicht verbundenen Sensor-Clients falsch ist.
Siehe auch http://www.steves-internet-guide.com/mqtt-sensors-traffic-observations/
- Steve merkt an, dass die Kombination von Sensordaten mehrerer Sensoren in einer JSON-kodierten Nutzlast den Datenverkehr nicht verringert, sondern ihn sogar leicht erhöhen kann (im Vergleich zu einer nicht kodierten Nutzlast!)
semantischer vs. physischer Themenpfad
Dinge, die für einen Menschen von Bedeutung sind, bilden die Themenstruktur: ("semantischer Ansatz")
Haus/Bad/Luftfeuchtigkeit
Gerätepfade (an welche Geräte sind die Sensoren angeschlossen, wie werden sie angesprochen?) erstellen die Themenstruktur: ("physikalischer Ansatz")
pi/00000234898324734/i2c/10/pressure
(die Zahlen symbolisieren die BCM-Seriennummer bzw. die I2C-Adresse).
Neuveröffentlichung
Bei dieser Idee würden Sie beide Ansätze kombinieren und einen zusätzlichen Dienst schaffen, der zwischen den beiden Welten vermittelt.
Siehe: https://tinkerman.cat/post/mqtt-topic-naming-convention
Übersicht der Online-Designvorschläge
Vorschlag 1: Himbeer-Tal
von: https://raspberry-valley.azurewebsites.net/MQTT-Topic-Trees/
gerätekategorie/geräte-id/zahllast-kontext/zahllast-differentiator
- Gerätekategorie: z. B. "pi", "arduino", usw.
- Geräte-ID: z. B. BCM seriell
- Nutzlast-Kontext: z.B. Temperatur
- Nutzlast-Unterscheidungsmerkmal: z. B. vorne/hinten (Hinzufügen einer Messebene für einen bestimmten Kontext)
Beachten Sie die Symmetrie zwischen Gerätekategorie/Geräte-ID und Nutzlast-Kontext/Nutzlast-Unterscheidungsmerkmal (allgemein-> spezifisch; allgemein-> spezifisch)
Vorschlag 2: Steve
(Von Steve): http://www.steves-internet-guide.com/mqtt-topic-payload-design-notes/
Sie können die folgenden Elemente in Ihren Themenbaum aufnehmen:
- Vorrichtungen zur Gruppierung von Themen auf hoher Ebene
- zugewiesener Sensorname
- Funktion (z.B. set / status / get / cmd )
Steves Ansatz:
- Verwendung des Themennamens für ein einzelnes Gerät (z. B. einen Sensor)
- Nutzdaten / JSON-Daten für Attribute dieses Sensors verwenden
- getrennte Bereiche für Daten und Befehle verwenden
Vorschlag 3: MQTT-Smarthome
MQTT Smarthome Vorschlag
https://github.com/mqtt-smarthome/mqtt-smarthome
Ein Pfad sieht in diesem Vorschlag wie folgt aus:
toplevelname/funktion/item
knxgateway1/status/Küche/Lichter/Vorne links
- erste Ebene (knxgateway1) = Toplevelname, das konkrete Gateway, das angesprochen wird
- bei mehreren ähnlichen Gateways muss dieser Name einstellbar sein, um Kollisionen im Namensraum zu vermeiden
- zweite Ebene (Status) = Funktion
- dritte Ebene, und weitere Ebenen -> individuelle Adresshierarchie des jeweiligen Gateways (Item)
Das Interessante sind die Funktionen und ihre Position vor die tieferen Pfade (beachten Sie die Platzhalter für das Abonnement - auf diese Weise können Sie alle Gerätestatusberichte einfach abonnieren!)
Verfügbare / definierte Funktionen in diesem Vorschlag:
- status - zum Abrufen von Statusberichten
- set - für die Anforderung von Zustandsänderungen
- get - (optional) für die aktive Anforderung einer Statusaktualisierung (für Gateways, die dies unterstützen)
- wird das Ergebnis des Lesevorgangs im Internet veröffentlicht. Status Hierarchie.
Die nachfolgenden Hierarchien für die einzelnen Verben sollten einander entsprechen, so dass Sie dasselbe Gerät / denselben Knoten / Parameter ansprechen würden.
Es gibt ein spezielles Thema "verbunden" pro Gateway, das es dem Kunden erlaubt, eine testamentarische Nachricht zu setzen
toplevelname/verbunden
sind für dieses Thema einfache Werte definiert:
- 0 = nicht mit dem Makler verbunden (als letzter Wille eingestellt)
- 1 = mit MQTT verbunden, von der Hardware abgekoppelt
- 2 = verbunden mit MQTT und Hardware (voll funktionsfähig)
Beachten Sie, dass der Wert 0 nicht zwischen freiwilligen Verbindungsabbrüchen oder einem Verbindungsabbruch (bei dem die Keepalives eine Zeitüberschreitung aufweisen) unterscheidet.
Es gibt auch Vorschläge für die Nutzlast:
Die JSON-Kodierung der Nutzdaten ist optional.
Im Falle der JSON-Kodierung befindet sich der Wert immer im Schlüssel "val". Zusätzlich,
ts : Zeitstempel (Zeitstempel, Millisekunden seit Epoch)
lc : letzte Änderung des Wertes (Zeitstempel, Millisekunden seit Epoch)
Vorschlag 4: Tinkerman
https://tinkerman.cat/post/mqtt-topic-naming-convention
Überlegen Sie, ob Sie einen "semantischen" Ansatz (z. B. Dinge, die für den Menschen von Bedeutung sind) oder einen "physischen" Ansatz (z. B. tatsächliche Gerätepfade, an die Ihr System angeschlossen ist) wählen.
Der physische Ansatz ist maschinenfreundlicher.
(Bitte beachten Sie, dass Tinkermans und mein Verständnis von Mountpoints und deren Verwendung voneinander abweichen - für mich sind Mountpoints komplett getrennte Themenbäume, z.B. für Multi-Tenancy)
Metadaten können als Postfix-Pfade kodiert werden.
z.B..
/home/schlafzimmer/temperatur -> 21
/home/Schlafzimmer/Temperatur/Einheiten -> °C
/home/bedroom/temperature/timestamp -> 2012-12-10T12:47:00+01:00
Hinweis: Da es unwahrscheinlich ist, dass sich die Einheiten und einige andere Metadaten ändern, können sie als beibehaltene Themen gesendet werden.
Ein interessanter Teil dieses Vorschlags ist auch die Aggregation (Geräteseite):
/home/bedroom/temperature/last -> letzter Temperaturwert
/home/schlafzimmer/temperatur/letzter/zeitstempel
/home/bedroom/temperature/last24h/max -> Höchstwert in den letzten 24h
/home/bedroom/temperature/last24h/max/timestamp -> Zeitstempel, an dem die Temperatur so hoch war
/home/schlafzimmer/temperatur/last24h/min
/home/bedroom/temperature/ever/max -> die absolut höchste jemals gemessene Temperatur
Auch diese Werte könnten als beibehaltene Themen eingestellt werden (insbesondere "immer"), um Netzwerkverkehr zu sparen - das empfangende System könnte ältere beibehaltene Werte verwerfen (wenn der Sensor nicht mehr angeschlossen ist, was durch ein anderes Thema ersichtlich sein sollte - möglicherweise durch Testament & Testament eingestellt), oder das System könnte sie als "veraltete" Werte anzeigen.
Dies ist ein interessantes Design (für die Aggregation) und könnte als Inspiration dienen, um diese Art von Flexibilität zu ermöglichen.
Vorschlag 5: Homie IoT Convention
Home IoT konzentriert sich auf die Auffindbarkeit von Knoten in der IoT-Heimautomatisierungsumgebung. Homie verwendet keine JSON-kodierten Nachrichten, sondern eine direkte Darstellung der Nutzdaten für jeden Knoten. Siehe dieses Beispiel:
Homie definiert einen strengen Zeichensatz, den Sie für die Benennung Ihrer Knoten verwenden dürfen, da Sonderzeichen (z.B. $ und der Unterstrich _) für besondere Zwecke verwendet werden.
Sie definiert Datentypen, die als (beibehaltene) Metadaten ("Attribute") zu $datatype der einzelnen Eigenschaft veröffentlicht werden (siehe unten für die Definition von Eigenschaft):
- Zeichenfolge
- Integer
- Schwimmer
- Boolesche
- Enum
- Farbe
(beachten Sie die Verwendung des $ zur Kennzeichnung besonderer Themen).
Letzter Wille wird verwendet, um das Gerät als verloren zu markieren:
Homie/deviceID/$state -> verloren
Homie definiert 6 mögliche Staaten für das Gerät:
- init -> das Gerät hat sich mit MQTT verbunden, aber noch nicht alle notwendigen Homie-Nachrichten veröffentlicht
- bereit -> das Gerät ist angeschlossen und hat die Einrichtung abgeschlossen - alle erforderlichen Nachrichten wurden gesendet
- abgetrennt -> das Gerät wurde auf saubere Weise abgetrennt
- Schlafen -> selbstbeschreibend
- verloren -> das Gerät hat sich unerwartet abgemeldet (testamentarisch festgelegt)
- Alarm -> das Gerät ist verbunden, aber etwas stimmt nicht, ein menschliches Eingreifen ist erforderlich
Homie empfiehlt die Verwendung von QoS 1 (da die Natur von Homie es sicher für doppelte Nachrichten macht).
Eine Rückstellung für Erweiterungen wird mit einer umgekehrten Domänennamensyntax erstellt, z. B. org.mycompany.homie-extension
Knotenpunkte und Geräte
In Homie-parlance, einem Gerät ist die grundlegende Hardware-Einheit. Zum Beispiel ein Raspberry Pi, eine Kaffeemaschine, ein Auto.
A Knoten ist eine logische, unabhängige Einheit des Geräts. Ein Auto kann beispielsweise einen Knoten "Räder", einen Knoten "Motor" und einen Knoten "Beleuchtung" haben.
Eigenschaften stellen grundlegende Eigenschaften des Knotens/Geräts dar. Ein Auto könnte z. B. eine Eigenschaft "Geschwindigkeit" und eine Eigenschaft "Temperatur" für den Motorknoten haben. Eigenschaften können beibehalten werden und/oder einstellbar sein.
- beibehalten + nicht einstellbar: z. B. Temperatursensor
- retained + settable: Knoten kann eine Eigenschaft veröffentlichen und Befehle für die Eigenschaft empfangen (z.B. Lampenleistung)
- nicht festgehalten + nicht einstellbar: z. B. eine Türklingel (momentane Ereignisse)
- non-retained + settable: Knoten kann Befehle für die Eigenschaft empfangen, z.B. Kaffee brühen
Attribute:
die Attribute sind wichtig für die Homie-Autodiscovery, sie sind spezifiziert und beginnen mit einem $, um ihre besondere Bedeutung anzuzeigen / Kollisionen zu vermeiden. Sie werden zum Speichern und Aktualisieren von Metadaten verwendet.
Zum Beispiel veröffentlicht das Gerät eine zurückgehaltene Nachricht auf
homie/Geräte-ID/$nodes
mit einer kommagetrennten Liste der Knoten. Um anzugeben, dass es sich bei einem Knoten um ein Array handelt (kann verwendet werden, um z. B. die Vorder- und Rücklichter eines Autos zu gruppieren), wird der Name mit eckigen Klammern am Ende angegeben, z. B.
Lichter[]
Ein Beispiel für den Teilbaum device id:
Homie gibt standardmäßig verschiedene Statistiken für das Gerät an, die meisten davon optional (außer der Betriebszeit). Zum Beispiel:
Bei Knoten wird wiederum die automatische Erkennung von Eigenschaften ermöglicht, indem diese im Attribut $properties angegeben werden:
Auf diese Weise müssen Sie als Abonnent nicht alle Ereignisse erraten/abonnieren, sondern können selektiv die Ereignisse abonnieren, die Sie interessieren.
In Homie werden die Metadaten (Attribute) als Suffix zum Pfad veröffentlicht. Z.B. für eine bestimmte Eigenschaft:
Kontrolle in Homie
Homie ist zustandsbasiert. Das bedeutet, dass Sie nicht "das Licht einschalten", sondern den Stromstatus eines Geräts auf "ein" setzen.
dann aktualisiert das Gerät seinen Stromversorgungszustand, um mitzuteilen, dass der Befehl ausgeführt wurde:
Sendung
Alarm ist eine willkürliche Wahl - die Übertragung kann zu jedem anderen Thema erfolgen, nach dem die Geräte filtern können. Die Nachrichten werden an alle Geräte gesendet - die Geräte können darauf reagieren, wenn sie dies wollen.
Dies ist die vollständigste Spezifikation, die ich bei meiner Online-Recherche finden konnte. Ich persönlich finde, dass er sehr elegant konstruiert ist.
Lesen Sie mehr:
https://homieiot.github.io/specification/
Vorschlag 6: Eigene Tracks
https://owntracks.org/booklet/tech/json/
http://owntracks.org/booklet/guide/topics/
Owntracks ist eine Open-Source-Anwendung, mit der Sie Ihren eigenen Standort verfolgen und mit Freunden teilen können. Der Standort wird über HTTP oder MQTT veröffentlicht, idealerweise zu Ihrem eigenen Makler.
" Es kann auch erkennen, wenn Sie eine bestimmte Region betreten oder verlassen, für die Sie einen so genannten Wegpunkt festgelegt haben. Damit kann man z. B. einen Aspekt des Hausautomationssystems steuern. (Alle haben das Haus verlassen? Wir können das Licht ausschalten.)"
Wenn Sie mehr über OwnTracks erfahren möchten, besuchen Sie diese Website: https://owntracks.org/booklet/
Über das owntracks-Thema Design:
https://owntracks.org/booklet/guide/topics/
"Die Grundsätze bei der Entwicklung des OwnTracks-Themenbenennungssystems waren
- menschliche Lesbarkeit
- Verkehrsminimierung
- granulare Zugangskontrolle
“
Name des Basisthemas (andere sind möglich):
owntracks/peter/iPhone
hier ist owntracks ein Präfix, um anderen Anwendungen kollisionsfreie Zugriffe auf den MQTT-Broker zu ermöglichen.
peter ist der Besitzer von Ortungsgeräten, und das iPhone ist eines seiner Geräte.
Befehle an Geräte werden gesendet an: owntracks/peter/iPhone/cmd
die Ausgabe der Befehle wird z.B. in relativen Themennamen veröffentlicht Schritt, abladen usw.
einige andere Themen werden definiert (Info, Wegpunkt, Ereignis). Ereignisse werden z. B. veröffentlicht, wenn ein Benutzer einen bestimmten Bereich betritt.
Auf diese Weise können Sie durch das Abonnieren von owntracks/+/+/event sehen (für Benutzer, für die Sie berechtigt sind, sie zu sehen), wann sie einen bestimmten Bereich betreten oder verlassen.
Owntracks veröffentlicht seine Nachrichten im JSON-Format:
https://owntracks.org/booklet/tech/json/
wie Sie sehen können, sind die Funktionen nach das Gerät.
Da es eine feste "Tiefe" für Benutzer/Geräte gibt, die im Voraus bekannt ist, kann das Abonnement für mehrere Benutzer und Geräte mit Platzhaltern erfolgen:
In der JSON-Datei wird die Typ des jeweiligen JSON wird in der Nachricht mitgegeben:
Das ist eine gute Idee! Auf diese Weise können Sie überprüfen, ob Ihre Anwendung das Ereignis richtig versteht, Typprüfungen durchführen kann usw.
Die einzelnen Elemente werden in nicht-verbaler Form angegeben. Dies hilft, Datenverkehr zu sparen, insbesondere bei Nachrichten, die häufig veröffentlicht werden.
z.B.:
- acc: Genauigkeit der gemeldeten Position in Metern (ohne Einheit)
viele der Elemente sind fakultativ.
Interessanterweise ist der Ortstyp für verschiedene Geräte definiert, die unterschiedliche Elemente unterstützen.
Eine einfache testamentarische Nachricht wird veröffentlicht. Sie enthält lediglich den Zeitstempel tst, zu dem das Gerät erstmals verbunden wurde.
tst ist ein Unix-Epochen-Zeitstempel.
Ein interessanter Aspekt dieses Ereignistyps/Nutzlasttyps ist, dass mehrere Zeitstempel angegeben sind:
- wtst: Zeitstempel der Wegpunkt-Erstellung
- tst: Zeitstempel, zu dem das Ereignis eingetreten ist.
Ein Wegpunkt ist ein Punkt von Interesse, z. B. Ihre Garage - wenn Sie Ihre Garage betreten oder verlassen, wird ein Übergangsereignis ausgelöst:
- Ereignis: (Eintritt|Austritt)
Ein Konfigurationsereignis. Wenn diese Option aktiviert ist, akzeptieren die Anwendungen auch Fernkonfigurationsmeldungen.
Dieses Ereignis enthält viele mögliche Elemente, die ausführlicher sind (z.B. validatecertificatechain) - dies ist sinnvoll, da die Konfiguration als JSON gespeichert werden kann (! -> dies kann als MQTT-Nachricht weitergegeben und gespeichert werden!), und auch, da es nicht oft gesendet wird, ist Ausführlichkeit kein großes Problem, sondern eher ein Vorteil für die Benutzer.
z.B. wird eine Aktion mit der "action": "dump" eine Veröffentlichung der Konfigurationsnachricht unter dem relativen Pfad dump auslösen
Für eine Aktion können optionale Unterparameter angegeben werden, z. B. ein zu betrachtender Zeitrahmen:
Eine weitere interessante Design-Idee ist, dass durch eine bestimmte Variation dieser cmd-Meldung ein Browser zu einer bestimmten URL geöffnet werden kann. Wenn man z.B. die Garage betritt, könnte eine Garagenkontrollseite geöffnet werden, ...
eine Array eines anderen Nachrichtentyps kann / muss hier als Parameter übergeben werden.
Das Interessante an dieser Nachricht ist, dass sie auch ein Feld für ein Base64-kodiertes PNG-Bild enthält:
Die interessante Idee dabei ist, dass eine optionale Ersteller mitgegeben werden, das die Entität identifiziert, die diese Wegpunkte erstellt hat.
Beachten Sie auch, dass owntracks den Unterstrich _ für "spezielle" Parameter verwendet.
Optional können alle diese Meldungen verschlüsselt für den Transport mit einem gemeinsamen symmetrischen Schlüssel.
Die verschlüsselte Nutzlast (die ursprüngliche Nachricht) befindet sich im Element "data", Base64-kodiert.
Nachrichten
Die Nutzdaten der Nachrichten sind binär und können beliebig sein, es ist nicht erforderlich, dass die Nachrichten in UTF-8 gültig sind.
Daher können Sie auch digitale Daten, z.B. Bilder, als Nutzlast zu bestimmten Themen veröffentlichen.
Viele aktuelle IoT-Dashboards verarbeiten Daten, die als JSON kodiert sind.
Im Allgemeinen scheint es zwei Denkrichtungen zu geben: Nachrichten sind eigentlich Rohwerte, und Metadaten werden im Themenbaum kodiert, und JSON-kodierte Werte, die Metadaten als Nutzdaten enthalten.
Vorschläge
- Verwendung des JSON-Formats für die Nutzdaten der Nachricht
- Attribute in Nachrichten bündeln, anstatt einzelne Themen für sie zu erstellen
- umfassen:
- Nutzlastdaten
- Sensor-/Geräte-ID (falls nicht Teil des Themenbaums)
- Funktion
- Zeitstempel
Interessante Ressourcen
Awesome MQTT: Sammlung von MQTT-bezogenen Links:
- https://github.com/hobbyquaker/awesome-mqtt
einzelne Projekte:
twitter-to-mqtt - Ein Python-Daemon, der die Twitter Streaming API nutzt, um auf Tweets zuzugreifen und sie in einem MQTT-Topic zu veröffentlichen.
fritz2mqtt - FRITZ!Box mit MQTT verbinden.
Ref:
- https://raspberry-valley.azurewebsites.net/MQTT-Topic-Trees/
- https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
- https://homieiot.github.io/
- https://github.com/homieiot/convention
- https://github.com/mqtt-smarthome/mqtt-smarthome
- http://www.steves-internet-guide.com/mqtt/
- http://www.steves-internet-guide.com/understanding-mqtt-topics/
- http://www.steves-internet-guide.com/mqtt-topic-payload-design-notes/
- https://stevessmarthomeguide.com/setting-up-the-sonoff-tasmota-mqtt-switch
- https://tinkerman.cat/post/mqtt-topic-naming-convention
- https://github.com/mqtt-smarthome/mqtt-smarthome/blob/master/howtos/homematic.md (zeigt den Fluss mit Node RED)
- https://owntracks.org/booklet/tech/json/
Wiederveröffentlichung:
- https://lodge.glasgownet.com/2012/09/23/mqtt-republishing-itch/
- https://github.com/kylegordon/mqtt-republisher