Metainformationen zur Seite
MQTT Gateway - Subscriptions und Topics
Bei MQTT dreht sich alles um Topics - hier eine Erklärung, was Topics und Subscriptions sind, wie diese zusammenhängen, und wie man bei Subscriptions Wildcards verwendet.
Topics
Topics sind eine hierarchische Struktur, die die MQTT-Geräte nutzen, um ihre Daten an den Broker mitzuteilen. Obwohl das MQTT-Protokoll eine strikte Protokolldefinition hat, ist die verwendete Struktur selbst nicht standardisiert. Jedoch empfehlen Automatisierungsprogramme wie HomeAssistant eine MQTT-Struktur, um eine automatische Erkennung von MQTT-Geräten zu vereinfachen bzw. zu ermöglichen.
Die Topic-Hierarchie stellt man sich wie eine Ordnerstruktur vor - bei MQTT werden die Hierarchie-Ebenen mit einem Schrägstrich / getrennt. Einen Unterschied gibt es im Vergleich zum Dateisystem: Vorne ist kein Schrägstrich (wenn ein Gerät einen Schrägstrich am Beginn verlangt, hat es der Entwickler nicht besser gewusst).
Beispiele:
- shellies/shellyswitch-12345/relay/0
- shellies/shellyswitch-12345/power
- sensor1/bath/temperature
- sensor1/state
- sensor2/livingroom/temperature
- sensor2/state
Die Topic-Hierarchie gibt das jeweilige MQTT-Gerät vor, und findet man dann in der MQTT-Dokumentation des jeweiligen Geräts. Oft kann man die Topic-Basis eines Gerätes auch selbst konfigurieren.
Im Topic selbst stehen dann die Daten - beispielsweise liefert shellies/shellyswitch-12345/power die aktuelle Leistung in Watt. Diese Nutzdaten können einfache Werte sein, aber auch beliebige Texte. Viele Geräte liefern den aktuellen Verbindungsstatus mit "Connected" oder "Active".
Einige Geräte senden die Daten nicht als reine Werte, sondern als JSON-Datensatz. JSON ist ein standardisiertes Datenaustauschformat, man erkennt einen JSON-Datensatz an seine geschweiften Klammern um die Daten, z.B.
{ "state": "Connected", "power": 25.3 }
Status-Topics und Command-Topics
Fast alle MQTT-Geräte verwenden Topics, um ihren Status zu senden, und zusätzlich ein eigenes Topic, um selbst Schaltbefehle zu empfangen. Shelly2 verwendet beispielsweise shellies/shellyswitch-12345/relay/0
für den Status, und shellies/shellyswitch-12345/relay/0/command
, um dort einen Steuerbefehl zu empfangen. Tasmota leitet seine Command-Topics mit cmnd/ ein.
Eingebürgert haben sich zur Unterscheidung die Bezeichnungen Status-Topics ( = senden ihren Status) und Command-Topics ( = empfangen Befehle), es kann aber auch anders heißen.
Subscriptions
Eine Subscription ist im Prinzip nichts anderes als ein Daten-Abo.
Die MQTT-Geräte liefern ihre Daten beim Broker ein, und Clients verbinden sich zum Broker, um von dort Daten zu erhalten. Da möglicherweise nicht jeder Client alle Daten benötigt, definiert der Client beim Verbinden mit den Subscriptions, welche Daten an ihn weitergeleitet werden sollen.
Bei den Subscriptions gibt man die Topics an, die der Client erhalten soll. Um nicht jedes einzelne Topic abonnieren zu müssen, gibt es Wildcards.
Subscription Wildcards
Es gibt im MQTT-Umfeld genau zwei Wildcards: # (Raute) und + (Plus).
Es gibt keinen Wildcard bzw. Filter, um Topicbezeichnungen abzukürzen (z.B. NICHT möglich: ein *room
um livingroom zu abonnieren)
Der Hash-Wildcard #
Der Hash in einer Subscription bedeutet, dass alle untergeordneten Topics abonniert werden.
Geräte-Topics unseres Beispiel von oben:
- shellies/shellyswitch-12345/relay/0
- shellies/shellyswitch-12345/power
Mögliche Subscriptions:
shellies/#
→ Abonniert alle Daten, die unter shellies/ und dessen Unterstrukturen eintreffen.shellies/shellyswitch-12345/#
→ Abonniert alle Daten, die unter shellies/shellyswitch-12345/ und dessen Unterstrukturen eintreffen.#
→ Abonniert komplett alles
Falsche Subscriptions:
- shellies/#/power
- shellies/##
- shellies#
- she#/#
Regeln: Es darf nur ein Hash vorkommen. Ein Hash muss immer am Ende stehen. Ein Hash muss immer einen Topictrenner / davor haben, außer der Hash ist das erste Zeichen der Subscription.
Der Plus-Wildcard +
Manchmal möchte man nicht alle Daten mit dem # abonnieren, sondern nur ein Wildcard für eine Struktur-Ebene einsetzen. Dafür ist der + Wildcard.
Geräte-Topics unseres Beispiels von oben:
- sensor1/bath/temperature
- sensor1/state
- sensor2/livingroom/temperature
- sensor2/state
Mögliche Subscriptions:
- +/livingroom/# → Abonniert, unabhängig vom ersten Level, alle Daten aus livingroom.
- +/+/temperature → Abonniert alle Temperaturwerte, egal wie der erste und zweite Level heißen.
- +/state → Abonniert den state, unabhängig vom ersten Level
- sensor1/+ → Abonniert von sensor1 nur Topics mit einem weiteren Level, im obigen Beispiel wird sensor1/bath/temperature nicht abonniert, sondern nur sensor1/state
Falsche Subscriptions:
- sensor+/#
- sensor1/+room
- +/livingroom/temp+
Regeln: Das +-Zeichen darf nicht in Kombination mit anderen Zeichen innerhalb eines Levels verwendet werden (es dürfen aber mehrere + in unterschiedlichen Leveln verwendet werden)
Publish und Retain
Bei MQTT gibt es zwei Formen der Übertragung:
- publish → Flüchtig: Es wird übertragen, aber nicht gespeichert.
- retain → Persistent: Es wird übertragen und am Broker gespeichert.
Publish-Nachrichten werden verwendet, um kurzzeitig eine Nachricht zu übermitteln, die aber nicht für längere Zeit relevant ist. In der Regel werden für Command-Topics, also Schaltbefehle, einfache Publish-Nachrichten gesendet.
Retain-Nachrichten werden verwendet, um einen Status zu übermitteln, der längere Zeit gültig bleibt (bis er sich wieder ändert). Meist werden Statusnachrichten wie Temperatur, aktueller Stromverbrauch, verbunden oder nicht verbunden, als Retain-Nachricht gesendet. Diese Nachrichten werden dann am Broker gespeichert.
Der Unterschied ist: Wenn ein sich Client später anmeldet, erhält er bei der Subscription automatisch alle gespeicherten Retain-Nachrichten. Publish-Nachrichten hingegen verfallen nach dem Senden, und der Client erhält deren Zustand nicht.
Wenn das MQTT-Gerät wie z.B. Shelly eine Option besitzt, dass Nachrichten mit dem Retain-Flag gesendet werden sollen, dann solltest du das aktivieren. So ist sichergestellt, dass ein neu verbundener Client sofort den letztgültigen Status erhält. Andernfalls wüsste der Client nicht, wie der Status ist, bis dieser bei der nächsten Statusänderung übertragen wird.
Eigenes Topics des Gateways
Das MQTT-Gateway betreibt selbst ein eigenes Topic:
<hostname>/mqttgateway/#
(z.B. loxberry/mqttgateway/#)
Dieses Topic wird automatisch abonniert und an den oder die Miniserver weitergeleitet, ohne dass einen Eintrag unter Subscriptions notwendig wäre.
loxberry/mqttgateway/status enthält 'Disconnected', 'Joining', 'Connected'. Dieses Topic ist auch als Last Will And Testament hinterlegt.
loxberry/mqttgateway/keepaliveepoch sendet im Minutentakt die aktuelle Zeit in Unix epoch.
Mit dem keepaliveepoch Topic kann man eine Überwachung auf Werteänderung machen: https://loxwiki.atlassian.net/wiki/x/OoLmWg
Da der Wert zum Broker, und vom Broker zurück zum Gateway und MS kommt, kann damit sowohl der Broker als auch das Gateway überwacht werden. Wenn sich der Timestamp länger nicht ändert, ist etwas nicht in Ordnung.
Es kann aber auch die Loxone-interne Funktion der Validierung des Virtuellen Eingangs ("Zeitüberschreitung Empfang") zur Überwachung verwendet werden.
Nichts verstanden?
Hier ein zweiter Erklärungsversuch von Topics und Subscriptions: LoxForum Thread