MQTT: Unterschied zwischen den Versionen

Aus FHEMWiki
K (Tippfehler)
 
(37 dazwischenliegende Versionen von 7 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
MQTT ist ein Protokoll ("Message Queue Telemetry Transport"), mit dem Daten und Befehle zwischen verschiedenen Geräten ausgetauscht werden. Die Kommunikation erfolgt dabei über einen Serverdienst, den so genannten MQTT-Broker.
[[MQTT]] ist ein Protokoll ("Message Queue Telemetry Transport"), mit dem Daten und Befehle zwischen verschiedenen Geräten ausgetauscht werden. Die Kommunikation erfolgt dabei über einen zentralen MQTT-Server, in alter Nomenklatur auch ''Broker'' genannt.


MQTT wurde entwickelt, um möglichst effizient, sicher und mit wenig Datenlast zu kommunizieren.  
MQTT wurde entwickelt, um möglichst effizient, sicher und mit wenig Datenlast zu kommunizieren. MQTT ist nachrichtenorientiert, daher muss ein Client nicht beständig beim Server anfragen, ob neue Daten vorliegen. Heute findet sich MQTT vor allem im Bereich des ''Internet of Things'' (IoT). MQTT kann leicht mit FHEM verbunden werden, ohne dass dabei größerer CPU- oder Datenverbrauch entsteht.
 
== Schnellstart für Ungeduldige ==
define m2s MQTT2_SERVER 1883 global
 
Am MQTT-Endgerät den FHEM-Server angeben wie in der Dokumentation des Endgeräts angegeben, danach das Endgerät neu starten.
Das Endgerät ist dann im Raum ''MQTT2_DEVICE'' zu finden.
 
Schau mal in attrTemplate des neu angelegten MQTT2_DEVICE, ob was passendes für Dich dabei ist.
 
Für die meisten ggf. hierzu auftretenden Fragen sollten Hinweise in den [[MQTT2-Module - Praxisbeispiele|Praxisbeispielen zu den MQTT2-Modulen]] enthalten sein.


== Eine sehr kurze Einführung in MQTT ==
== Eine sehr kurze Einführung in MQTT ==
MQTT wird ausführlich auf diesen [https://github.com/mqtt/mqtt.github.io/wiki diesen Wikiseiten] erklärt. Eine FHEM-orientierte Einführung findet man [[MQTT Einführung#Eine sehr kurze Einführung in MQTT|auf dieser Seite]].
Die folgende Einführung kann eine vollwertige Einleitung wie beispielsweise [https://github.com/mqtt/mqtt.github.io/wiki diese Wikieinträge] nicht ersetzen.  


== FHEM und MQTT ==
Bei MQTT findet die nachrichtenbasierte Kommunikation zwischen einzelnen Teilnehmern<ref>Teilnehmer in diesem Sinne kann ein Stück Hardware mit einer MQTT-fähigen firmware sein, ein auf einem Computer laufendes Script (einschließlich eines MQTT-Server-Dienstes wie ''mosquitto'' oder ''MQTT2_SERVER'', kurz: alles mögliche sein. Dadurch kann auch ein einzelner Computer unter mehreren ClientID's am MQTT-Datenaustausch beteiligt sein.</ref> in der Regel nicht direkt statt. Stattdessen werden alle Nachrichten von einem Teilnehmer an einen Serverdienst, den MQTT-Server (früher ''Broker'' genannt) übergeben, der dann dafür sorgt, dass die Nachricht an alle (berechtigten) anderen Teilnehmer verteilt wird, die sich für derartige Nachrichten "interessieren". Wenn also ein Teilnehmer ohne Server-Funktion (Client) Daten von einem bestimmten anderen Teilnehmer (anderer Client) empfangen will, muss es vorher dem MQTT-Server (Broker) mitteilen, dass er die Nachrichten dieses anderen Teilnehmers abonniert (deshalb wird dieser Vorgang als ''subscribe'' bezeichnet). Im IoT ist besonders interessant, dass Sender und Empfänger von Nachrichten durch den MQTT-Server vollständig entkoppelt werden können - jemand, der Daten bereit stellt, muss sich also nicht darum kümmern, wer diese Daten empfängt<ref>Aufgrund dieser Funktionsweise sollte allerdings darauf geachtet werden, die Möglichkeiten des jeweiligen Servers zur Sicherung der Daten gegen unberechtigten Zugriff zu nutzen, insbesondere wenn die Art der Daten oder die sich hierdurch ergebenden Möglichkeiten, z.B. Schaltvorgänge in der realen Welt auszulösen, dies notwendig macht!</ref>.
MQTT benötigt für den Betrieb einen (und nur einen) zentralen Server, der formal ''Broker'' genannt wurde. Ein solcher Server kann extern (also außerhalb von FHEM, zum Beispiel mosquitto) als auch durch FHEM selbst bereitgestellt werden. Wer MQTT jetzt nutzen will, sollte keinen externen Server installieren, sondern FHEM als Server nutzen.  


Damit FHEM als Server für MQTT funktioniert, muss ein Modul installiert werden, das die Aufgabe des Brokers übernimmt. Es handelt sich um das Modul {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}}.<ref>Die Zahl 2 an FHEM bedeutet nicht, dass es sich um eine neuere Protokollversion für FHEM handelt (also nicht so etwas wie MQTT 2.0), sondern das erst kürzlich MQTT in FHEM integriert wurde.</ref> Dieser FHEM-eigene Server bietet weniger Optionen als ein vollwertiger MQTT-Server wie mosquitto, ist jedoch für kleinere Installationen völlig ausreichend. Ein MQTT-Server kann mehrere FHEM-Installationen bedienen<ref>Dies gilt sowohl für einen klassischen Broker wie für einen MQTT2_SERVER.</ref>.
Eine Nachricht besteht im Wesentlichen aus den folgenden Elementen:
*'''ClientID''' -  das ist die Kennung des Senders einer Nachricht<ref>Diese kann sich bei der Weitergabe der Nachricht ändern: Zunächst sendet ein Client eine Nachricht unter seiner ClientID, der MQTT-Server wird diese dann in der Regel durch seine Kennung ersetzten, wenn er die Nachricht an einen Abonnenten - der auch ein weiterer MQTT-Server sein kann - weitergibt.</ref>
*Topic - das ist die Adresse, an die eine Nachricht gesendet wird, bzw. von wo sie abgeholt werden kann (so ähnlich wie ein Postfach in der realen Welt). Topics sind einfache Strings, die mit Schrägstrichen getrennt werden (keine Leerzeichen und nur sehr wenige Sonderzeichen erlaubt). Ein Topic könnte beispielhaft so lauten: <code>zuHause/1OG/Kueche/Licht/state</code>. Diese Topics beinhalten also eine Hierarchie der Objekte - hier im Beispiel sind sie zuerst danach sortiert, ob sie sich zu Haus befinden, dann wird nach Stockwerken sortiert und im ersten Stock schaut man auf die Küche sowie das dort vorhandene Licht. 
*'''Payload''' - das ist der Inhalt der Nachricht, oft handelt es sich um Befehle oder Daten, gelegentlich auch ''message'' genannt.
*'''Quality of Service''' - soll geprüft werden, ob die Nachricht zugestellt wurde und wenn ja, mit welcher "Tiefe"?
*'''Retained Message'''.
Details bitte in der oben genannten Einführung nachlesen.


===  Einbindung mit externem Broker ===
Das Protokoll ''MQTT'' kommuniziert üblicherweise über Port 1883, es können aber unter derselben Netzwerkadresse an unterschiedlichen Ports auch mehrere Serverdienste bereitstehen.
Wird in der [[MQTT Einführung]] beschrieben:


Für die Kommunikation zwischen einem MQTT-fähigen Objekt und dem Broker ist der Broker zuständig (außerhalb von FHEM). Die Kommunikation zwischen Broker und FHEM geschieht via dem IO-Modul 00_MQTT.pm (so genannte physikalische Stufe, siehe dazu [https://wiki.fhem.de/wiki/DevelopmentModuleIntro#Zweistufiges_Modell_f.C3.BCr_Module|diese Erläuterung zum Zwei-Stufen-Modell]). Damit innerhalb von FHEM das Objekt angesprochen werden kann, muss es weiter in FHEM ein Gerät vom  Typ MQTT_DEVICE geben, das die Befehle vom Objekt entgegennimmt bzw. an das Objekt sendet.
== Installation in FHEM ==
Um ''MQTT'' in FHEM zu nutzen, benötigt man (mindestens) einen MQTT-Server. Es gibt zwei Möglichkeiten: man kann FHEM-externe Server-Software (oder auch einen oder mehrere im Internet bereitstehende MQTT-Server) verwenden oder man kann die MQTT-Serverkomponente aktivieren, die mit {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}} in FHEM direkt bereitsteht. Hier werden kurz beide Installationswege erläutert, zwingend ist nur einer, da eben mindestens ein MQTT-Serverdienst aktiv sein muß.


===  Einbindung mit MQTT2 von FHEM ===
Die nachfolgenden Schaubilder zeigen schematisch die in FHEM zur Verfügung stehenden Wege der Einbindung von Hard- und/oder Softwarekomponenten, die über das MQTT-Protokoll Daten austauschen.
Hier gilt das oben gesagte, wobei nun die Kommunikation zwischen dem MQTT-fähigen Objekt und dem Broker durch FHEM selbst bereitgestellt wird. Dazu muss in FHEM ein Gerät z.B. mit dem Namen myBroker
<gallery>
defmod mybroker MQTT2_SERVER 1883 global
Datei:Mqtt2 server.png|Datenaustausch mit MQTT-Geräten, wenn ''MQTT2_SERVER'' als internem MQTT-Serverdienst verwendet wird
angelegt werden (die Zahl 1883 bezieht sich auf den Port, auf dem MQTT arbeitet).
Datei:Mqtt2 client v extern server.png|Datenaustausch mit MQTT-Geräten, wenn ''MQTT2_CLIENT'' iVm. mosquitto als externem MQTT-Serverdienst verwendet wird
Datei:00 mqtt pm.png|Datenaustausch mit MQTT-Geräten, wenn das Modul ''MQTT'' (00_MQTT.pm) iVm. ''mosquitto'' als externem MQTT-Serverdienst verwendet wird
</gallery>
{{Hinweis|Neueinsteigern in das MQTT-Protokoll wird '''dringend empfohlen''', '''''MQTT2_SERVER''''', oder - sofern unbedingt ein externer Server zum Einsatz werden soll - ''MQTT2_CLIENT'' zu verwenden.}}


Seit November 2018 ist es mit [[MQTT2_CLIENT]]<ref>{{Link2CmdRef|Anker=MQTT2_CLIENT|Lang=en|Label=commandref}}</ref> möglich, [[MQTT2 DEVICE]]-Geräte einzurichten, ohne dass MQTT2_SERVER auf derselben Installation vorhanden sein muss. MQTT2_CLIENT kann auch mit einem klassischen Broker wie mosquitto betrieben werden.


Weitere Hinweise zur Verwendung der MQTT2-Module sind in den [[MQTT2-Module - Praxisbeispiele|Praxisbeispielen]] zu finden.
=== FHEM als MQTT-Server ===
Die mit dem Modul {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}} bereitstehende Serverkomponente kann z.B. wie folgt aktiviert werden:
defmod myBroker MQTT2_SERVER 1883 global
Dieses [[Gerät]] übernimmt dann die Kommunikation mit den externen Clients (und wird von diesen behandelt, wie jeder andere MQTT-Server auch<ref>Bitte beachten Sie, dass (Stand: Janar 2021) ''MQTT2_SERVER'' nicht alle features des MQTT-Protokolls unterstützt.</ref>) und verteilt die eingehenden Nachrichten als IO-Device<ref>im Sinne des [[DevelopmentModuleIntro#Zweistufiges Modell für Module|2-stufigen Modulkonzepts]]</ref> für die Client-Module [[MQTT2_DEVICE]]<ref>Die Zahl 2 in den Modulnamen verweist nur darauf, dass es sich um eine neuere Modulfamilie handelt; die Kommunikation mit den externen Komponenten unterscheidet sich nicht zu den älteren Modulen, die vor dem Jahr 2018 genutzt werden konnten.</ref> und [[MQTT_GENERIC_BRIDGE]].
Ein weiterer Vorteil dieser Lösung besteht darin, dass man ein ''MQTT2_SERVER''-Device mit Hilfe von [[allowed]] absichern kann, was auch SSL-verschlüsselte Kommunikation ermöglicht. '''Hinweis:''' In diesem Fall muss User bzw. Passwort auch in den entsprechenden Geräten eingetragen werden.


MQTT2_SERVER und MQTT2_CLIENT ermöglichen - im Unterschied zur klassischen Einbindung - passwortgeschütze Datenübertragungen zwischen den einzelnen Komponenten.
{{Hinweis|Wenn Sie beabsichtigen, diese Variante zu verwenden, sollten Sie als nächstes die [[MQTT2-Module - Praxisbeispiele|Praxisbeispiele zu den MQTT2-Modulen]] lesen, und ggf. später wieder hierher zurückkehren. Dort findet sich auch ein Abschnitt zu dem auf den Grafiken zu den MQTT2-IO-Modulen enthaltenen [[MQTT2-Module_-_Praxisbeispiele#bridgeRegexp|bridgeRegexp]]-Attribut.}}
{{Hinweis|Falls Sie neben Anweisungen aus FHEM selbst heraus andere Software nutzen wollen, um Befehle über den ''MQTT2_SERVER'' an die darüber eingebundenen Geräte zu senden, beachten Sie bitte auch den Abschnitt zum [[MQTT2_CLIENT#ignoreRegexp|ignoreRegexp]]-Attribut bei ''MQTT2_CLIENT''.}}


=== MQTT_GENERIC_BRIDGE ===
=== FHEM-externer Broker ===
Das Modul {{Link2CmdRef|Anker=MQTT_GENERIC_BRIDGE|Lang=en|Label=MQTT_GENERIC_BRIDGE}} kann seit November 2018 mit allen drei IO-Modul-Varianten zusammen eingesetzt werden, also sowohl mit MQTT2_SERVER bzw. MQTT2_CLIENT oder MQTT (00_MQTT.pm).
==== Beispiel: mosquitto ====
Eine gern verwendete MQTT-Server-Software ist [http://mosquitto.org Mosquitto]. Sie kann ohne weiteres auf dem Raspberry Pi, der bereits eine FHEM-Installation besitzt, installiert werden und wird keine größere CPU- oder Netzwerklast verursachen.  


Dabei sollte man jedoch beachten, dass zur Verwendung mit den MQTT2-IO's unbedingt die autocreate-Funktion des betreffenden IOs ausgeschaltet wird und dies auch bleibt<ref>siehe dazu diesen {{Link2Forum|Topic=95341|LinkText=Thread}} zu den technischen Hintergründen</ref>! Weiter wird das Perl-Modul ''libmodule-pluggable-perl'' benötigt<ref>Dieses kann über <code>apt-get install libmodule-pluggable-perl</code> installiert werden</ref>, damit im Hintergrund auch das Modul [[MQTT (Modul)|MQTT]] geladen werden kann.
Im wesentlichen beschränkt sich die Installation eines MQTT Servers aber auf wenige Arbeitsschritte. Seit ''stretch'' ist ''Mosquitto'' bereits in der Distribution enthalten und kann - zusammen mit dem client Befehl ''mosquito_sub'', der weiter unten benötigt wird, wie folgt installiert und getestet werden
<syntaxhighlight lang="bash">
  sudo apt-get install mosquitto mosquitto-clients
# MQTT Server Test
sudo systemctl status mosquitto


# Start / Stop des Servers
sudo systemctl stop mosquitto
sudo systemctl start mosquitto
</syntaxhighlight>
Danach ist der RPi mit <nowiki>shutdown restart</nowiki> neu zu starten.
==== IO-Module für externe MQTT-Server ====
Damit FHEM mit dem MQTT-Server kommuniziert, muss noch ein IO-Device angelegt werden. Dabei stehen zwei Varianten zur Wahl, das Modul [[MQTT (Modul)|MQTT]] oder seit Ende 2018 [[MQTT2_CLIENT]].
Beide Module können auch dazu genutzt werden, um Daten zwischen zwei FHEM-Installationen auszutauschen, insbesondere kann auch 00_MQTT.pm als Client für einen MQTT2_SERVER eingesetzt werden, der '''auf der anderen Installation''' als MQTT-Serverdienst eingerichtet ist. Darüber hinaus bestehen eine Vielzahl von Kombinationsmöglichkeiten der diversen IO-Module, wenn die Installation auf mehrere Server verteilt ist.
Auf einer FHEM-Installation wird jedoch in der Regel nur eines der IO-Module benötigt.
===== MQTT2_CLIENT =====
Ein MQTT2_CLIENT-IO-Device wird z.B. angelegt mit
define myBroker MQTT2_CLIENT 10.0.0.5:1883 ## bitte EIGENE IP-Adresse eintragen
{{Hinweis|Wenn Sie beabsichtigen, MQTT2_CLIENT zu verwenden, sollten Sie zuerst die [[MQTT2-Module - Praxisbeispiele|Praxisbeispiele zu den MQTT2-Modulen]] lesen, und dabei die Hinweise im Artikel [[MQTT2_CLIENT]] beachten.}}
Ein MQTT2_CLIENT-Device kann ebenfals mit Hilfe von [[allowed]] abgesichert werden, um z.B. SSL-verschlüsselte Kommunikation zu ermöglichem. Client-Module zu diesem IO-Typ sind wiederum [[MQTT2_DEVICE]] und [[MQTT_GENERIC_BRIDGE]].
===== MQTT (Modul) =====
Vorab werden für diese Variante weitere Perl-Pakete benötigt:
<syntaxhighlight lang="bash">
# Perl Version ausgeben
perl -v
# Perl MQTT Module nachinstallieren (läuft ein paar Minuten)
sudo cpan install Net::MQTT::Constants
</syntaxhighlight>
Dabei wird neben dem ausdrücklich aufgeführten Modul noch ''Module::Pluggable'' und ''Net::MQTT::Message'' (sowie ein weiteres, nicht für FHEM genutztes Paket) installiert.
Ein IO-Device des Typs MQTT wird z.B. angelegt mit
{{Randnotiz|RNTyp=g|RNText=Sofern der Broker mit FHEM über localhost kommuniziert, kann als IP 127.0.0.1 verwendet werden.}}
define myBroker MQTT 10.0.0.5:1883 ## bitte EIGENE IP-Adresse eintragen
{{Randnotiz|RNTyp=g|RNText=Außerhalb der offiziellen Quellen sind auch einige ältere Varianten des Moduls MQTT_DEVICE verfügbar, die jeweils spezielle Anforderungen (z.B. für Zigbee2mqtt) separat abbilden. Diese werden hier nicht gesondert behandelt, da solche Sonderfälle heute generischer und einfacher durch den Einsatz von MQTT2_DEVICE abzubilden sind.}}Client-Device-Module zum Modul [[MQTT (Modul)|MQTT]] sind [[MQTT_DEVICE]], ''MQTT_BRIDGE'' (veraltet!) und  [[MQTT_GENERIC_BRIDGE]]. Da ''MQTT_DEVICE'' payload im JSON-Format (im Unterschied zu MQTT2_DEVICE) nicht selbst verarbeiten kann wird hier zusätzlich das Modul {{Link2CmdRef|Anker=expandJSON|Lang=de|Label=expandJSON}} benötigt, um den {{Link2Forum|Topic=66761|LinkText=JSON String auszuwerten}}.
===== Auswahl =====
Als Einsteiger sollte man ''MQTT2_CLIENT'' als Interface-Modul wählen. Dies hat folgende Vorteile:
* ''MQTT2_CLIENT'' kann verschlüsselte Verbindungen aufbauen.
* Es sind keine externen Perl-Module erforderlich.
* Als Client-Modul steht u.a. ''MQTT2_DEVICE'' zur Verfügung, das - im Vergleich zu ''MQTT_DEVICE'' direktere Möglichkeiten der Behandlung von heutzutage häufig verbreiteten JSON-Payloads bietet.
=== Performancefragen... ===
...oder was sollte man unter Performance-Gesichtspunkten als Lösung wählen, wenn man in die MQTT-Welt einsteigt<ref>vgl. hierzu diesen {{Link2Forum|Topic=94768|Message=875714|LinkText=Beitrag}} von Rudolf König</ref>?
Grundsätzlich sollte man davon ausgehen, dass innerhalb von FHEM die Verarbeitung derselben Daten näherungsweise denselben Aufwand bedeuten, unabhängig davon, welche der Implementierungen (''MQTT2_CLIENT'', ''MQTT'' oder ''MQTT2_SERVER'') man konkret wählt.
Ein externer Broker hat daher vor allem dann Vorteile, wenn die MQTT Daten überwiegend für was anderes (nicht FHEM) verwendet werden, oder MQTT zweckentfremdet wird (wie z.Bsp. für Musikübertragung). Nutzt man das MQTT-Protokoll dagegen vorwiegend innerhalb von FHEM, ist eher der Einsatz von ''MQTT2_SERVER'' in Betracht zu ziehen. Dieser soll Anfängern die Anbindung von MQTT Geräten in FHEM einfacher machen. Wer später merkt, dass er doch einen externen Broker benötigt, kann dann immer noch auf ''MQTT2_CLIENT'' in Verbindung mit einem anderen Broker wechseln.
Dagegen ist der Weg von ''MQTT_DEVICE'' zu ''MQTT2_DEVICE'' mit erheblich mehr Aufwand verbunden.
=== Kommunikation zu sonstigen FHEM-Geräten über MQTT  ===
Möchte man Daten von einem [[Gerät]] (im FHEM-Sinn), das '''nicht''' vom Typ ''MQTT2_DEVICE'' oder ''MQTT_DEVICE'' (je nach IO-Modul) ist, per MQTT-Protokoll versenden (z.B. für eine andere Visualisierungslösung als FHEMWEB, oder als FHEM2FHEM-Ersatzlösung), oder diese sonstigen Geräte über MQTT-Anweisungen von außen steuern können, hat man mehrere Möglichkeiten:
==== MQTT_GENERIC_BRIDGE ====
===== Allgemeines =====
Das Modul {{Link2CmdRef|Anker=MQTT_GENERIC_BRIDGE|Lang=en|Label=MQTT_GENERIC_BRIDGE}} ermöglicht es, sein jeweiliges IO-Modul-Gerät zu nutzen, um diesen Kommunikationsweg für beliebig viele andere FHEM-Geräte bereitzustellen. Dabei erfolgt am MQTT_GENERIC_BRIDGE-Gerät selbst nur eine Basiskonfiguration, im Übrigen durch Attribute an dem jeweiligen Gerät selbst. So kann z.B. ein Aktor des Typs [[CUL_HM]] an- oder ausgeschaltet werden oder auch einfach nur seinen aktuellen Schaltzustand per MQTT-Protokoll publizieren.
Dieses Modul kann seit November 2018 mit allen drei IO-Modul-Varianten zusammen eingesetzt werden, also sowohl mit ''MQTT2_SERVER'' bzw. ''MQTT2_CLIENT'' oder ''MQTT'' (00_MQTT.pm). Seit Rev. 23514 (Jan. 2021) wird für MQTT_GENERIC_BRIDGE iVm. den MQTT2-IO-Modulen '''keine zusätzliche Software mehr''' benötigt. 
===== MQTT_GENERIC_BRIDGE und autocreate bei MQTT2-IO-Modulen =====
{{Randnotiz|RNTyp=g|RNText=Alternativ kann eine ''bridgeRegexp'' an einem beliebigen ''MQTT2_DEVICE'' existiert, die die betreffenden Nachrichten mit einer leeren CID zurückgibt.
Die technischen Hintergründe bzgl. autocreate sind diesem {{Link2Forum|Topic=95341|LinkText=Thread}} zu entnehmen.
Beispiel für die Erstellung einer passenden ''bridgeRegexp'':
Es existiert ein "Neben-FHEM" namens ''fhem2'', das von einem "Haupt-FHEM" namens ''fhem'' aus Nachrichten empfangen soll, die dann an die an ''fhem2'' angeschlossene Hardware weitergegeben werden. Die Nachrichten kommen über ein MQTT2_CLIENT-IO mit der CID ''fhem2'' in ''fhem2'' an. Das Haupt-FHEM sendet mit der ''$base'' ''fhem/''. Dann wäre in ''fhem2'' folgendes MQTT2_DEVICE anzulegen (der Name kann frei gewählt werden):
define M_G_B_bridgeRegex_device MQTT2_DEVICE fhem2
attr M_G_B_bridgeRegex_device bridgeRegexp [\b]fhem/.*:.* ""}}
Dabei sollte man jedoch beachten, dass eingehende MQTT-Nachrichten von den MQTT2-IO Modulen (''MQTT2_SERVER'' oder ''MQTT2_CLIENT'') nur dann an die ''MQTT_GENERIC_BRIDGE'' zur weiteren Auswertung übergeben werden, wenn
- zum einen '''kein passender readingList-Eintrag''' an irgendeinem ''MQTT2_DEVICE'' exisitert '''und''' die ''autocreate''-Funktion des betreffenden IOs ausgeschaltet wird und bleibt, '''oder'''
- die Priorität bei der Übergabe der Daten an die weiteren Module geändert wird. Hierfür stellen die Module ''MQTT2_SERVER'' oder ''MQTT2_CLIENT'' das Attribut ''clientOrder'' auf ''MQTT_GENERIC_BRIDGE MQTT2_DEVICE'' zu stellen:
attr <mqtt2_server> clientOrder MQTT_GENERIC_BRIDGE MQTT2_DEVICE
Die letztere Methode mit ''clientOrder'' wird zur Vermeidung von späteren Irritationen ausdrücklich empfohlen!
===== Anwendungsbeispiele =====
Anwendungsfälle und -beispiele für das Modul sind diesem {{Link2Forum|Topic=91642|LinkText=Thread}} zu entnehmen.
Anwendungsfälle und -beispiele für das Modul sind diesem {{Link2Forum|Topic=91642|LinkText=Thread}} zu entnehmen.


=== Performancefragen... ===
==== MQTT_BRIDGE ====
...oder was sollte man als Lösung wählen, wenn man in die MQTT-Welt einsteigt<ref>vgl. hierzu diesen {{Link2Forum|Topic=94768|Message=875714|LinkText=Beitrag}} von Rudolf König</ref>?
Dieses früher in FHEM enthaltene Modul kann nur zusammen mit einem IO-Gerät des Typs [[MQTT (Modul)|MQTT]] verwendet werden. Dabei wird pro weiterzuleitendem anderen FHEM-Gerät eine eigene Instanz dieses Moduls verwendet. '''Auf den Einsatz dieser Option sollte in neuen Installationen zugunsten von ''MQTT_GENERIC_BRIDGE'' verzichtet werden!'''
Grundsätzlich sollte man davon ausgehen, dass innerhalb von FHEM die Verarbeitung derselben Daten näherungsweise denselben Aufwand bedeuten, unabhängig davon, welche der Implementierungen (MQTT2_CLIENT, MQTT oder MQTT2_SERVER) man konkret wählt.
{{Hinweis|''MQTT_BRIGE'' wird seit FHEM-Version 6.1 nicht mehr direkt als Modul mit installiert. Es ist bei Bedarf in ''contrib'' zu finden.}}
Ein externer Broker hat daher vor allem dann Vorteile, wenn die MQTT Daten überwiegend für was anderes (nicht FHEM) verwendet werden, oder MQTT zweckentfremdet wird (wie z.Bsp. für Musikübertragung). Nutzt man das MQTT-Protokoll dagegen vorwiegend innerhalb von FHEM, ist eher der Einsatz von MQTT2_SERVER in Betracht zu ziehen. Dieser soll Anfängern die Anbindung von MQTT Geraeten in FHEM einfacher machen. Wer später merkt, dass er doch einen externen Broker benötigt, kann dann immer noch auf MQTT2_CLIENT in Verbindung mit einem anderen Broker wechseln.
 
Dagegen ist der Weg von MQTT_DEVICE zu MQTT2_DEVICE mit erheblich mehr Aufwand verbunden.
==== Per publish-Befehl am IO-Gerät ====
Alle drei IO-Module kennen direkte ''publish''-Anweisungen, mit deren Hilfe beliebige ''payloads'' an beliebige ''topics'' gesendet werden können. Dies kann man z.B. in einem [[notify]] oder [[at]] nutzen, um einzelne Events zu publishen oder Werteanfragen abzusetzen.
 
Hier eine regelmäßige Werteabfrage auf einen [[EBUS-MQTT2|ebus]]:
defmod get_ebus_updates at +*00:15:00 set ebusMQTT publish ebusd/430/Hc1HeatCurve/get;
set ebusMQTT publish ebusd/430/HwcTempDesired/get;
...
 
 
==== RAW-Events am IO-Gerät (MQTT2.*) ====
Bei beiden MQTT2-IO-Modulen (MQTT2_SERVER und MQTT2_CLIENT) kann per [[Regulärer Ausdruck|regulärem Ausdruck]] festgelegt werden, welche Nachrichten ein Event erzeugen sollen, auf das dann wieder z.B. mit einem [[notify]] reagiert werden kann, z.B. um beliebige Schaltaktionen auszulösen.
 
 
== MQTT-Clients (Beispiele) ==
 
===Arduino-library===
Zur Kommunikation mit dem Broker von Seiten eines [[Arduino|Arduinos]] mit selbst erstellten Sketches böte sich der PubSubClient an.
 
===PC-Software===
Um die Funktionalität des Brokers zu testen kann z.B. ein Analyse-Tool wie MQTT.fx verwendet werden, oder die im Paket ''mosquitto-clients'' enthaltenen Linux-Kommandozeilen-Programme ''mosquitto_sub'' und ''mosquitto_pub''. Letzterer könnte z.E. auch aus beliebigen ''shell-scripten'' heraus aufgerufen werden. Als Perl-Bibliothek steht alternativ z.B. [https://metacpan.org/pod/distribution/AnyEvent-MQTT/bin/anyevent-mqtt-pub anyevent-mqtt-pub] zur Verfügung.
 
=== Tasmota ===
Eine derzeit oft genutzte Möglichkeit für MQTT bilden die [[Sonoff]]-Geräte und weitere [[ESP8266]]-basierte Hardware, die unter vielen Handelsnamen erhältlich sind. Werden diese mit Tasmota ('''T'''heo '''A'''rends '''S'''onoff '''M'''QTT '''O'''ver '''T'''he '''A'''ir - einer offenen Firmware von [https://github.com/arendst arendst]) geflasht, so kommunizieren sie über MQTT. Um diese Geräte einzubinden, ist wie folgt vorzugehen. Zuerst ist ein Serverdienst (Broker) bereitzustellen, wie oben beschrieben.
 
Unter Sonoff sind einige Topics voreingestellt. arendst stellt insbesondere drei Topic-Präfixe bereit, die seiner Meinung jedes Topic einleiten sollen (in den Eingabemasken als "%prefix%" notiert). Das sind einmal Kommandos (abgekürzt als cmnd), die dazu dienen, Befehle auszuführen. Daten werden mit tele und stat übertragen. Ein Topic besteht dann zuerst aus diesem Präfix und danach dem eigentlichen Topic. Wer also beispielsweise einem Sonoff_Switch einen Befehl senden will, sollte als Topic cmnd/Sonoff_Switch wählen. Wenn der Switch ein- und ausgeschaltet werden kann, muss der Topic noch das Wort POWER enthalten (in MQTT werden viele Kennworte komplett groß geschrieben). Der Topic lautet damit vollständig "cmnd/Sonoff_Switch/POWER/set"
 
{{Randnotiz|RNTyp=g|RNText=Dabei ist darauf zu achten, dass für den Parameter ''topic = %topic% (sonoff)'' statt ''sonoff'' ein gerätespezifischer eigener Name eingetragen wird. Hierzu kann man z.B. auch die dynamisch aus der Chip-ID erzeugte Kennung ''DVES_%06X'' verwenden, indem man die unter ''client (DVES_8BABA9)'' zu findende Angabe kopiert. Die eigentliche Umbenennung zu einem "sprechenden Namen" kann dann innerhalb von FHEM - mittels ''rename'' oder ggf. mit einem ''alias'' - erfolgen.}}
 
Link zum Forum: {{Link2Forum|Topic=27532|LinkText=MQTT FHEM Einrichtung}} (hier als ''MQTT_DEVICE''!):
 
### FHEM Device mit MQTT verbinden ###
define Sonoff_Switch MQTT_DEVICE
attr Sonoff_Switch IODev myBroker
attr Sonoff_Switch devStateIcon ON:rc_GREEN:OFF OFF:rc_RED:ON
attr Sonoff_Switch icon hue_filled_br30
attr Sonoff_Switch publishSet ON OFF cmnd/TestSwitch/POWER
attr Sonoff_Switch room MQTT
attr Sonoff_Switch subscribeReading_Licht stat/Sonoff_Switch/POWER
attr Sonoff_Switch subscribeReading_Sensor tele/Sonoff_Switch/SENSOR
attr Sonoff_Switch subscribeReading_Status stat/Sonoff_Switch/STATUS
attr Sonoff_Switch webCmd ON:OFF
 
Der hier dargestellte Beispielcode realisiert die Kommunikation zwischen FHEM und dem sonoff Modul via MQTT Broker. Zu beachten ist hier, dass '''subscribeReading_Licht''' und '''subscribeReading_Status''' unterschiedliche Syntax des Topic Strings haben!
 
=== OpenMQTTGateway ===
Um verschiedene Systeme wie BLE usw. auf MQTT zu bringen bietet sich [https://github.com/1technophile/OpenMQTTGateway OpenMQTTGateway] an, z.B. wird für das Auslesen vieler BLE-Sensoren lediglich ein ESP32-Board ohne Zusatzhardware (ab ca. 5,- Euro in Fernost erhältlich) benötigt, auf das dann eine vorkompilierte Firmware geflasht wird (USB-seriell-Wandler erforderlich).
 
Nähere Details sind im Artikel [[OpenMQTTGateway]] zu finden.
 
== Sicherheit ==
Prinzipiell ist MQTT ebenso sicher wie eine Postkarte. Solange man es nicht extra absichert, kann jeder der, im eigenen LAN ist (und die Adresse vom Broker kennt) alle Topics mitlesen.
:<code>meinHaus/Flur/Haustuer:open / close</code>
bietet unter diesen Umständen reichlich Raum für Verbesserungen!
 
Abhilfe:
=== Username / Passwort ===
Zunächst kann man erst mal einen Username / Passwort vergeben, was alle IO-Device-Module unterstützen. Da ist zwar auch noch lange nicht sicher, aber zumindest steigert es den Aufwand schon mal. Jetzt muss man zumindest schon mal Pakete sniffen und verstehen, um unbefugt zu lesen oder gar zu publishen.
 
=== TLS ===
Um wirklich sicher zu werden, führt kein Weg an TLS vorbei.
 
Der MQTT-Client in [[#Tasmota|Tasmota]] (für ESP8266) kann mit TLS betrieben werden, vgl. [https://github.com/arendst/Tasmota/wiki/TLS Beschreibung im Tasmota-Wiki].
 
Leider kann z.B. ein Arduino das schlicht nicht mehr, da die einfacheren Modelle nicht über ausreichend Speicher und die Rechenleistung verfügen.
 
'''(Hier fehlt eine Anleitung für allowed usw.)'''
 
== Probleme ==
=== Anweisung und Ergebnis weichen voneinander ab ===
In der Regel melden MQTT-fähige Geräte entweder den Erhalt einer Nachricht zurück oder den Status nach Durchführung der in der ''payload'' enthaltenen Anweisung. Dabei findet aber in der Regel beim Empfänger eine Verarbeitung der Nachricht statt, ggf. wird diese auch weitergesendet und nochmals verarbeitet, bevor dann ggf. eine Rückmeldung des neuen Status an den MQTT-Server erfolgt. Handelt es sich um einfache on/off-Befehle, bleibt Anweisung und Ergebnis in der Regel identisch. Bei anderen, namentlich bei Dimmer-Werten, kann es zu Rundungsdifferenzen bei nummerischen Werten kommen. So kann z.B. ein Dimm-Wert von 70% gesetzt werden, zürückgemeldet wird dann aber 72% (oder 67%).
Dies ist technisch bedingt, vermeiden kann das jedoch in aller Regel nur der Autor der jeweiligen software/firmware auf dem "rechnenden" Gerät.
 
=== Unbeabsichtigte Schleifen ===
Durch Fehler in der topic-Struktur können unbeabsichtigte Schleifen entstehen, die FHEM komplett blockieren können. Es ist unbedingt darauf zu achten, dass die jeweiligen Sende- und Empfangs-topics andere sind!
 
== FAQ ==
=== Welche Infos sollten Anfragen im MQTT-Forum enthalten? ===
* Anfragen bitte nur zur aktuellsten FHEM-Version: Befehl <code>update</code> ergibt Ausgabe "nothing to do..."
* detaillierte Beschreibung des Problems
* Art der Einbindung
** eingesetzter MQTT-Server? (=> MQTT2_SERVER oder externer Serverdienst wie mosquitto?)
** Wenn externer Server: Interface-Modul: MQTT2_CLIENT oder 00_MQTT.pm?
** Wenn MQTT2_SERVER: ''list'' beifügen und klären, ob dieser von der jeweiligen Komponente aus im Netzwerk zu erreichen ist:
*** steht auf "global"?
*** ggf. passendes [[allowed]] definiert, falls weiter entferntes Netzwerk oder falls Zugangsbeschränkungen/Authentifizierungsverfahren eingestellt sind?
*** Modifikationen am ''autocreate''-Attribut?
** Bitte einen Hinweis, falls MQTT_GENERIC_BRIDGE definiert ist bzw. auch ein ''list'' von der MQTT_GENERIC_BRIDGE.
** TYPE des eigentlichen MQTT-Devices (MQTT2_DEVICE, MQTT_DEVICE, TASMOTA_DEVICE, ...)
* Informationen zur eigentlichen Komponente:
** Hersteller, ggf. aktuell verwendete firmware incl. Version (Beispiel: ein Shelly-Gerät mit originaler firmware verhält sich anders als dasselbe Gerät mit Tasmota-, ESPEasy oder ESPurna-firmware!).
** Infos zur MQTT-Konfiguration auf dem Gerät selbst
** Bei weniger gängigen Komponenten oder Diensten:
*** (sofern vorhanden): Link zu Projektseiten, MQTT-API-Seiten usw..
*** Mittschnitte des MQTT-Verkehrs (z.B. durch Einschalten der rawEvents an den MQTT2-Interface-Modulen, s.o.).
** Ein ''list'' des eigentlichen Devices - bei MQTT2_DEVICE gerne in Form einer RAW-Definition (''list -r <devicename>'').
* Bei MQTT2-Einbindung und aktiviertem ''autocreate'' an den Interface-Modulen den Status des ''autocreate''-'Devices:
list TYPE=autocreate
=== Älterer FAQ-Thread im Forum ===
Dieser ist {{Link2Forum|Topic=70119|LinkText=hier}} zu finden. Bitte beachten: es sind einige grundlegende Informationen und Links zu vielen Tools und Fundstellen enthalten, allerdings nur bis zum Stand des Jahres 2017. Die neue Modulgeneration MQTT2_.* wird dort nicht behandelt.


== Links ==
== Links ==
* [http://mqtt.org Offizielle Homepage von MQTT, englisch]
* [http://www.hivemq.com/blog/mqtt-essentials-part-1-introducing-mqtt Sehr gute Einführung, englisch, sind 5 lesenswerte Teile]
* [https://www.heise.de/developer/artikel/MQTT-Protokoll-fuer-das-Internet-der-Dinge-2168152.html Ein Exkurs von Heise mit Beispielen, deutsch, sehr lesenswert]
* [http://www.mqttfx.org/ MQTT FX - ein sehr praktisches Analysetool]
* {{Link2Forum|Topic=69230|LinkText=Diskussionsthread im Forum}}
* {{Link2Forum|Topic=92888|LinkText=Thread, zur Entstehungsgeschichte von MQTT2_CLIENT}}
* {{Link2Forum|Topic=92888|LinkText=Thread, zur Entstehungsgeschichte von MQTT2_CLIENT}}
* {{Link2Forum|Topic=93255|LinkText=Ankündigungsthread zur MQTT2-Erweiterung der MQTT_GENERIC_BRIDGE}}
* {{Link2Forum|Topic=93255|LinkText=Ankündigungsthread zur MQTT2-Erweiterung der MQTT_GENERIC_BRIDGE}}
* [[MQTT_Einf%C3%BChrung_Teil_2|Teil 2 der MQTT Einführung]]: Detailaspekte (vorrangig zur Modulfamilie MQTT/MQTT_DEVICE)
* [[MQTT Einführung Teil 3|Teil 3 der MQTT Einführung]]: Arduino-Client selbst programmieren


== Hinweise ==
== Hinweise ==
<references />
<references />


[[Kategorie:Glossary]]
[[Kategorie:HOWTOS]]
[[Kategorie:MQTT|Einführung]]
[[Kategorie:MQTT| ]]
[[Kategorie:MQTT| ]]

Aktuelle Version vom 20. Februar 2024, 15:40 Uhr

MQTT ist ein Protokoll ("Message Queue Telemetry Transport"), mit dem Daten und Befehle zwischen verschiedenen Geräten ausgetauscht werden. Die Kommunikation erfolgt dabei über einen zentralen MQTT-Server, in alter Nomenklatur auch Broker genannt.

MQTT wurde entwickelt, um möglichst effizient, sicher und mit wenig Datenlast zu kommunizieren. MQTT ist nachrichtenorientiert, daher muss ein Client nicht beständig beim Server anfragen, ob neue Daten vorliegen. Heute findet sich MQTT vor allem im Bereich des Internet of Things (IoT). MQTT kann leicht mit FHEM verbunden werden, ohne dass dabei größerer CPU- oder Datenverbrauch entsteht.

Schnellstart für Ungeduldige

define m2s MQTT2_SERVER 1883 global

Am MQTT-Endgerät den FHEM-Server angeben wie in der Dokumentation des Endgeräts angegeben, danach das Endgerät neu starten. Das Endgerät ist dann im Raum MQTT2_DEVICE zu finden.

Schau mal in attrTemplate des neu angelegten MQTT2_DEVICE, ob was passendes für Dich dabei ist.

Für die meisten ggf. hierzu auftretenden Fragen sollten Hinweise in den Praxisbeispielen zu den MQTT2-Modulen enthalten sein.

Eine sehr kurze Einführung in MQTT

Die folgende Einführung kann eine vollwertige Einleitung wie beispielsweise diese Wikieinträge nicht ersetzen.

Bei MQTT findet die nachrichtenbasierte Kommunikation zwischen einzelnen Teilnehmern[1] in der Regel nicht direkt statt. Stattdessen werden alle Nachrichten von einem Teilnehmer an einen Serverdienst, den MQTT-Server (früher Broker genannt) übergeben, der dann dafür sorgt, dass die Nachricht an alle (berechtigten) anderen Teilnehmer verteilt wird, die sich für derartige Nachrichten "interessieren". Wenn also ein Teilnehmer ohne Server-Funktion (Client) Daten von einem bestimmten anderen Teilnehmer (anderer Client) empfangen will, muss es vorher dem MQTT-Server (Broker) mitteilen, dass er die Nachrichten dieses anderen Teilnehmers abonniert (deshalb wird dieser Vorgang als subscribe bezeichnet). Im IoT ist besonders interessant, dass Sender und Empfänger von Nachrichten durch den MQTT-Server vollständig entkoppelt werden können - jemand, der Daten bereit stellt, muss sich also nicht darum kümmern, wer diese Daten empfängt[2].

Eine Nachricht besteht im Wesentlichen aus den folgenden Elementen:

  • ClientID - das ist die Kennung des Senders einer Nachricht[3]
  • Topic - das ist die Adresse, an die eine Nachricht gesendet wird, bzw. von wo sie abgeholt werden kann (so ähnlich wie ein Postfach in der realen Welt). Topics sind einfache Strings, die mit Schrägstrichen getrennt werden (keine Leerzeichen und nur sehr wenige Sonderzeichen erlaubt). Ein Topic könnte beispielhaft so lauten: zuHause/1OG/Kueche/Licht/state. Diese Topics beinhalten also eine Hierarchie der Objekte - hier im Beispiel sind sie zuerst danach sortiert, ob sie sich zu Haus befinden, dann wird nach Stockwerken sortiert und im ersten Stock schaut man auf die Küche sowie das dort vorhandene Licht.
  • Payload - das ist der Inhalt der Nachricht, oft handelt es sich um Befehle oder Daten, gelegentlich auch message genannt.
  • Quality of Service - soll geprüft werden, ob die Nachricht zugestellt wurde und wenn ja, mit welcher "Tiefe"?
  • Retained Message.

Details bitte in der oben genannten Einführung nachlesen.

Das Protokoll MQTT kommuniziert üblicherweise über Port 1883, es können aber unter derselben Netzwerkadresse an unterschiedlichen Ports auch mehrere Serverdienste bereitstehen.

Installation in FHEM

Um MQTT in FHEM zu nutzen, benötigt man (mindestens) einen MQTT-Server. Es gibt zwei Möglichkeiten: man kann FHEM-externe Server-Software (oder auch einen oder mehrere im Internet bereitstehende MQTT-Server) verwenden oder man kann die MQTT-Serverkomponente aktivieren, die mit MQTT2_SERVER in FHEM direkt bereitsteht. Hier werden kurz beide Installationswege erläutert, zwingend ist nur einer, da eben mindestens ein MQTT-Serverdienst aktiv sein muß.

Die nachfolgenden Schaubilder zeigen schematisch die in FHEM zur Verfügung stehenden Wege der Einbindung von Hard- und/oder Softwarekomponenten, die über das MQTT-Protokoll Daten austauschen.

Info blue.png
Neueinsteigern in das MQTT-Protokoll wird dringend empfohlen, MQTT2_SERVER, oder - sofern unbedingt ein externer Server zum Einsatz werden soll - MQTT2_CLIENT zu verwenden.



FHEM als MQTT-Server

Die mit dem Modul MQTT2_SERVER bereitstehende Serverkomponente kann z.B. wie folgt aktiviert werden:

defmod myBroker MQTT2_SERVER 1883 global

Dieses Gerät übernimmt dann die Kommunikation mit den externen Clients (und wird von diesen behandelt, wie jeder andere MQTT-Server auch[4]) und verteilt die eingehenden Nachrichten als IO-Device[5] für die Client-Module MQTT2_DEVICE[6] und MQTT_GENERIC_BRIDGE. Ein weiterer Vorteil dieser Lösung besteht darin, dass man ein MQTT2_SERVER-Device mit Hilfe von allowed absichern kann, was auch SSL-verschlüsselte Kommunikation ermöglicht. Hinweis: In diesem Fall muss User bzw. Passwort auch in den entsprechenden Geräten eingetragen werden.


Info blue.png
Wenn Sie beabsichtigen, diese Variante zu verwenden, sollten Sie als nächstes die Praxisbeispiele zu den MQTT2-Modulen lesen, und ggf. später wieder hierher zurückkehren. Dort findet sich auch ein Abschnitt zu dem auf den Grafiken zu den MQTT2-IO-Modulen enthaltenen bridgeRegexp-Attribut.


Info blue.png
Falls Sie neben Anweisungen aus FHEM selbst heraus andere Software nutzen wollen, um Befehle über den MQTT2_SERVER an die darüber eingebundenen Geräte zu senden, beachten Sie bitte auch den Abschnitt zum ignoreRegexp-Attribut bei MQTT2_CLIENT.


FHEM-externer Broker

Beispiel: mosquitto

Eine gern verwendete MQTT-Server-Software ist Mosquitto. Sie kann ohne weiteres auf dem Raspberry Pi, der bereits eine FHEM-Installation besitzt, installiert werden und wird keine größere CPU- oder Netzwerklast verursachen.

Im wesentlichen beschränkt sich die Installation eines MQTT Servers aber auf wenige Arbeitsschritte. Seit stretch ist Mosquitto bereits in der Distribution enthalten und kann - zusammen mit dem client Befehl mosquito_sub, der weiter unten benötigt wird, wie folgt installiert und getestet werden

  sudo apt-get install mosquitto mosquitto-clients
 
 # MQTT Server Test
 sudo systemctl status mosquitto 

 # Start / Stop des Servers
 sudo systemctl stop mosquitto 
 sudo systemctl start mosquitto

Danach ist der RPi mit shutdown restart neu zu starten.

IO-Module für externe MQTT-Server

Damit FHEM mit dem MQTT-Server kommuniziert, muss noch ein IO-Device angelegt werden. Dabei stehen zwei Varianten zur Wahl, das Modul MQTT oder seit Ende 2018 MQTT2_CLIENT.

Beide Module können auch dazu genutzt werden, um Daten zwischen zwei FHEM-Installationen auszutauschen, insbesondere kann auch 00_MQTT.pm als Client für einen MQTT2_SERVER eingesetzt werden, der auf der anderen Installation als MQTT-Serverdienst eingerichtet ist. Darüber hinaus bestehen eine Vielzahl von Kombinationsmöglichkeiten der diversen IO-Module, wenn die Installation auf mehrere Server verteilt ist. Auf einer FHEM-Installation wird jedoch in der Regel nur eines der IO-Module benötigt.

MQTT2_CLIENT

Ein MQTT2_CLIENT-IO-Device wird z.B. angelegt mit

define myBroker MQTT2_CLIENT 10.0.0.5:1883 ## bitte EIGENE IP-Adresse eintragen


Info blue.png
Wenn Sie beabsichtigen, MQTT2_CLIENT zu verwenden, sollten Sie zuerst die Praxisbeispiele zu den MQTT2-Modulen lesen, und dabei die Hinweise im Artikel MQTT2_CLIENT beachten.


Ein MQTT2_CLIENT-Device kann ebenfals mit Hilfe von allowed abgesichert werden, um z.B. SSL-verschlüsselte Kommunikation zu ermöglichem. Client-Module zu diesem IO-Typ sind wiederum MQTT2_DEVICE und MQTT_GENERIC_BRIDGE.

MQTT (Modul)

Vorab werden für diese Variante weitere Perl-Pakete benötigt:

 # Perl Version ausgeben
 perl -v
 # Perl MQTT Module nachinstallieren (läuft ein paar Minuten)
 sudo cpan install Net::MQTT::Constants

Dabei wird neben dem ausdrücklich aufgeführten Modul noch Module::Pluggable und Net::MQTT::Message (sowie ein weiteres, nicht für FHEM genutztes Paket) installiert.

Ein IO-Device des Typs MQTT wird z.B. angelegt mit

Info green.pngSofern der Broker mit FHEM über localhost kommuniziert, kann als IP 127.0.0.1 verwendet werden.
define myBroker MQTT 10.0.0.5:1883 ## bitte EIGENE IP-Adresse eintragen
Info green.pngAußerhalb der offiziellen Quellen sind auch einige ältere Varianten des Moduls MQTT_DEVICE verfügbar, die jeweils spezielle Anforderungen (z.B. für Zigbee2mqtt) separat abbilden. Diese werden hier nicht gesondert behandelt, da solche Sonderfälle heute generischer und einfacher durch den Einsatz von MQTT2_DEVICE abzubilden sind.

Client-Device-Module zum Modul MQTT sind MQTT_DEVICE, MQTT_BRIDGE (veraltet!) und MQTT_GENERIC_BRIDGE. Da MQTT_DEVICE payload im JSON-Format (im Unterschied zu MQTT2_DEVICE) nicht selbst verarbeiten kann wird hier zusätzlich das Modul expandJSON benötigt, um den JSON String auszuwerten.

Auswahl

Als Einsteiger sollte man MQTT2_CLIENT als Interface-Modul wählen. Dies hat folgende Vorteile:

  • MQTT2_CLIENT kann verschlüsselte Verbindungen aufbauen.
  • Es sind keine externen Perl-Module erforderlich.
  • Als Client-Modul steht u.a. MQTT2_DEVICE zur Verfügung, das - im Vergleich zu MQTT_DEVICE direktere Möglichkeiten der Behandlung von heutzutage häufig verbreiteten JSON-Payloads bietet.

Performancefragen...

...oder was sollte man unter Performance-Gesichtspunkten als Lösung wählen, wenn man in die MQTT-Welt einsteigt[7]? Grundsätzlich sollte man davon ausgehen, dass innerhalb von FHEM die Verarbeitung derselben Daten näherungsweise denselben Aufwand bedeuten, unabhängig davon, welche der Implementierungen (MQTT2_CLIENT, MQTT oder MQTT2_SERVER) man konkret wählt. Ein externer Broker hat daher vor allem dann Vorteile, wenn die MQTT Daten überwiegend für was anderes (nicht FHEM) verwendet werden, oder MQTT zweckentfremdet wird (wie z.Bsp. für Musikübertragung). Nutzt man das MQTT-Protokoll dagegen vorwiegend innerhalb von FHEM, ist eher der Einsatz von MQTT2_SERVER in Betracht zu ziehen. Dieser soll Anfängern die Anbindung von MQTT Geräten in FHEM einfacher machen. Wer später merkt, dass er doch einen externen Broker benötigt, kann dann immer noch auf MQTT2_CLIENT in Verbindung mit einem anderen Broker wechseln. Dagegen ist der Weg von MQTT_DEVICE zu MQTT2_DEVICE mit erheblich mehr Aufwand verbunden.

Kommunikation zu sonstigen FHEM-Geräten über MQTT

Möchte man Daten von einem Gerät (im FHEM-Sinn), das nicht vom Typ MQTT2_DEVICE oder MQTT_DEVICE (je nach IO-Modul) ist, per MQTT-Protokoll versenden (z.B. für eine andere Visualisierungslösung als FHEMWEB, oder als FHEM2FHEM-Ersatzlösung), oder diese sonstigen Geräte über MQTT-Anweisungen von außen steuern können, hat man mehrere Möglichkeiten:

MQTT_GENERIC_BRIDGE

Allgemeines

Das Modul MQTT_GENERIC_BRIDGE ermöglicht es, sein jeweiliges IO-Modul-Gerät zu nutzen, um diesen Kommunikationsweg für beliebig viele andere FHEM-Geräte bereitzustellen. Dabei erfolgt am MQTT_GENERIC_BRIDGE-Gerät selbst nur eine Basiskonfiguration, im Übrigen durch Attribute an dem jeweiligen Gerät selbst. So kann z.B. ein Aktor des Typs CUL_HM an- oder ausgeschaltet werden oder auch einfach nur seinen aktuellen Schaltzustand per MQTT-Protokoll publizieren.

Dieses Modul kann seit November 2018 mit allen drei IO-Modul-Varianten zusammen eingesetzt werden, also sowohl mit MQTT2_SERVER bzw. MQTT2_CLIENT oder MQTT (00_MQTT.pm). Seit Rev. 23514 (Jan. 2021) wird für MQTT_GENERIC_BRIDGE iVm. den MQTT2-IO-Modulen keine zusätzliche Software mehr benötigt.

MQTT_GENERIC_BRIDGE und autocreate bei MQTT2-IO-Modulen
Info green.pngAlternativ kann eine bridgeRegexp an einem beliebigen MQTT2_DEVICE existiert, die die betreffenden Nachrichten mit einer leeren CID zurückgibt.

Die technischen Hintergründe bzgl. autocreate sind diesem Thread zu entnehmen.

Beispiel für die Erstellung einer passenden bridgeRegexp:

Es existiert ein "Neben-FHEM" namens fhem2, das von einem "Haupt-FHEM" namens fhem aus Nachrichten empfangen soll, die dann an die an fhem2 angeschlossene Hardware weitergegeben werden. Die Nachrichten kommen über ein MQTT2_CLIENT-IO mit der CID fhem2 in fhem2 an. Das Haupt-FHEM sendet mit der $base fhem/. Dann wäre in fhem2 folgendes MQTT2_DEVICE anzulegen (der Name kann frei gewählt werden):

define M_G_B_bridgeRegex_device MQTT2_DEVICE fhem2
attr M_G_B_bridgeRegex_device bridgeRegexp [\b]fhem/.*:.* ""

Dabei sollte man jedoch beachten, dass eingehende MQTT-Nachrichten von den MQTT2-IO Modulen (MQTT2_SERVER oder MQTT2_CLIENT) nur dann an die MQTT_GENERIC_BRIDGE zur weiteren Auswertung übergeben werden, wenn

- zum einen kein passender readingList-Eintrag an irgendeinem MQTT2_DEVICE exisitert und die autocreate-Funktion des betreffenden IOs ausgeschaltet wird und bleibt, oder - die Priorität bei der Übergabe der Daten an die weiteren Module geändert wird. Hierfür stellen die Module MQTT2_SERVER oder MQTT2_CLIENT das Attribut clientOrder auf MQTT_GENERIC_BRIDGE MQTT2_DEVICE zu stellen:

attr <mqtt2_server> clientOrder MQTT_GENERIC_BRIDGE MQTT2_DEVICE

Die letztere Methode mit clientOrder wird zur Vermeidung von späteren Irritationen ausdrücklich empfohlen!

Anwendungsbeispiele

Anwendungsfälle und -beispiele für das Modul sind diesem Thread zu entnehmen.

MQTT_BRIDGE

Dieses früher in FHEM enthaltene Modul kann nur zusammen mit einem IO-Gerät des Typs MQTT verwendet werden. Dabei wird pro weiterzuleitendem anderen FHEM-Gerät eine eigene Instanz dieses Moduls verwendet. Auf den Einsatz dieser Option sollte in neuen Installationen zugunsten von MQTT_GENERIC_BRIDGE verzichtet werden!

Info blue.png
MQTT_BRIGE wird seit FHEM-Version 6.1 nicht mehr direkt als Modul mit installiert. Es ist bei Bedarf in contrib zu finden.


Per publish-Befehl am IO-Gerät

Alle drei IO-Module kennen direkte publish-Anweisungen, mit deren Hilfe beliebige payloads an beliebige topics gesendet werden können. Dies kann man z.B. in einem notify oder at nutzen, um einzelne Events zu publishen oder Werteanfragen abzusetzen.

Hier eine regelmäßige Werteabfrage auf einen ebus:

defmod get_ebus_updates at +*00:15:00 set ebusMQTT publish ebusd/430/Hc1HeatCurve/get;
set ebusMQTT publish ebusd/430/HwcTempDesired/get;
...


RAW-Events am IO-Gerät (MQTT2.*)

Bei beiden MQTT2-IO-Modulen (MQTT2_SERVER und MQTT2_CLIENT) kann per regulärem Ausdruck festgelegt werden, welche Nachrichten ein Event erzeugen sollen, auf das dann wieder z.B. mit einem notify reagiert werden kann, z.B. um beliebige Schaltaktionen auszulösen.


MQTT-Clients (Beispiele)

Arduino-library

Zur Kommunikation mit dem Broker von Seiten eines Arduinos mit selbst erstellten Sketches böte sich der PubSubClient an.

PC-Software

Um die Funktionalität des Brokers zu testen kann z.B. ein Analyse-Tool wie MQTT.fx verwendet werden, oder die im Paket mosquitto-clients enthaltenen Linux-Kommandozeilen-Programme mosquitto_sub und mosquitto_pub. Letzterer könnte z.E. auch aus beliebigen shell-scripten heraus aufgerufen werden. Als Perl-Bibliothek steht alternativ z.B. anyevent-mqtt-pub zur Verfügung.

Tasmota

Eine derzeit oft genutzte Möglichkeit für MQTT bilden die Sonoff-Geräte und weitere ESP8266-basierte Hardware, die unter vielen Handelsnamen erhältlich sind. Werden diese mit Tasmota (Theo Arends Sonoff MQTT Over The Air - einer offenen Firmware von arendst) geflasht, so kommunizieren sie über MQTT. Um diese Geräte einzubinden, ist wie folgt vorzugehen. Zuerst ist ein Serverdienst (Broker) bereitzustellen, wie oben beschrieben.

Unter Sonoff sind einige Topics voreingestellt. arendst stellt insbesondere drei Topic-Präfixe bereit, die seiner Meinung jedes Topic einleiten sollen (in den Eingabemasken als "%prefix%" notiert). Das sind einmal Kommandos (abgekürzt als cmnd), die dazu dienen, Befehle auszuführen. Daten werden mit tele und stat übertragen. Ein Topic besteht dann zuerst aus diesem Präfix und danach dem eigentlichen Topic. Wer also beispielsweise einem Sonoff_Switch einen Befehl senden will, sollte als Topic cmnd/Sonoff_Switch wählen. Wenn der Switch ein- und ausgeschaltet werden kann, muss der Topic noch das Wort POWER enthalten (in MQTT werden viele Kennworte komplett groß geschrieben). Der Topic lautet damit vollständig "cmnd/Sonoff_Switch/POWER/set"

Info green.pngDabei ist darauf zu achten, dass für den Parameter topic = %topic% (sonoff) statt sonoff ein gerätespezifischer eigener Name eingetragen wird. Hierzu kann man z.B. auch die dynamisch aus der Chip-ID erzeugte Kennung DVES_%06X verwenden, indem man die unter client (DVES_8BABA9) zu findende Angabe kopiert. Die eigentliche Umbenennung zu einem "sprechenden Namen" kann dann innerhalb von FHEM - mittels rename oder ggf. mit einem alias - erfolgen.


Link zum Forum: MQTT FHEM Einrichtung (hier als MQTT_DEVICE!):

### FHEM Device mit MQTT verbinden ###
define Sonoff_Switch MQTT_DEVICE
attr Sonoff_Switch IODev myBroker
attr Sonoff_Switch devStateIcon ON:rc_GREEN:OFF OFF:rc_RED:ON
attr Sonoff_Switch icon hue_filled_br30
attr Sonoff_Switch publishSet ON OFF cmnd/TestSwitch/POWER
attr Sonoff_Switch room MQTT
attr Sonoff_Switch subscribeReading_Licht stat/Sonoff_Switch/POWER
attr Sonoff_Switch subscribeReading_Sensor tele/Sonoff_Switch/SENSOR
attr Sonoff_Switch subscribeReading_Status stat/Sonoff_Switch/STATUS
attr Sonoff_Switch webCmd ON:OFF

Der hier dargestellte Beispielcode realisiert die Kommunikation zwischen FHEM und dem sonoff Modul via MQTT Broker. Zu beachten ist hier, dass subscribeReading_Licht und subscribeReading_Status unterschiedliche Syntax des Topic Strings haben!

OpenMQTTGateway

Um verschiedene Systeme wie BLE usw. auf MQTT zu bringen bietet sich OpenMQTTGateway an, z.B. wird für das Auslesen vieler BLE-Sensoren lediglich ein ESP32-Board ohne Zusatzhardware (ab ca. 5,- Euro in Fernost erhältlich) benötigt, auf das dann eine vorkompilierte Firmware geflasht wird (USB-seriell-Wandler erforderlich).

Nähere Details sind im Artikel OpenMQTTGateway zu finden.

Sicherheit

Prinzipiell ist MQTT ebenso sicher wie eine Postkarte. Solange man es nicht extra absichert, kann jeder der, im eigenen LAN ist (und die Adresse vom Broker kennt) alle Topics mitlesen.

meinHaus/Flur/Haustuer:open / close

bietet unter diesen Umständen reichlich Raum für Verbesserungen!

Abhilfe:

Username / Passwort

Zunächst kann man erst mal einen Username / Passwort vergeben, was alle IO-Device-Module unterstützen. Da ist zwar auch noch lange nicht sicher, aber zumindest steigert es den Aufwand schon mal. Jetzt muss man zumindest schon mal Pakete sniffen und verstehen, um unbefugt zu lesen oder gar zu publishen.

TLS

Um wirklich sicher zu werden, führt kein Weg an TLS vorbei.

Der MQTT-Client in Tasmota (für ESP8266) kann mit TLS betrieben werden, vgl. Beschreibung im Tasmota-Wiki.

Leider kann z.B. ein Arduino das schlicht nicht mehr, da die einfacheren Modelle nicht über ausreichend Speicher und die Rechenleistung verfügen.

(Hier fehlt eine Anleitung für allowed usw.)

Probleme

Anweisung und Ergebnis weichen voneinander ab

In der Regel melden MQTT-fähige Geräte entweder den Erhalt einer Nachricht zurück oder den Status nach Durchführung der in der payload enthaltenen Anweisung. Dabei findet aber in der Regel beim Empfänger eine Verarbeitung der Nachricht statt, ggf. wird diese auch weitergesendet und nochmals verarbeitet, bevor dann ggf. eine Rückmeldung des neuen Status an den MQTT-Server erfolgt. Handelt es sich um einfache on/off-Befehle, bleibt Anweisung und Ergebnis in der Regel identisch. Bei anderen, namentlich bei Dimmer-Werten, kann es zu Rundungsdifferenzen bei nummerischen Werten kommen. So kann z.B. ein Dimm-Wert von 70% gesetzt werden, zürückgemeldet wird dann aber 72% (oder 67%). Dies ist technisch bedingt, vermeiden kann das jedoch in aller Regel nur der Autor der jeweiligen software/firmware auf dem "rechnenden" Gerät.

Unbeabsichtigte Schleifen

Durch Fehler in der topic-Struktur können unbeabsichtigte Schleifen entstehen, die FHEM komplett blockieren können. Es ist unbedingt darauf zu achten, dass die jeweiligen Sende- und Empfangs-topics andere sind!

FAQ

Welche Infos sollten Anfragen im MQTT-Forum enthalten?

  • Anfragen bitte nur zur aktuellsten FHEM-Version: Befehl update ergibt Ausgabe "nothing to do..."
  • detaillierte Beschreibung des Problems
  • Art der Einbindung
    • eingesetzter MQTT-Server? (=> MQTT2_SERVER oder externer Serverdienst wie mosquitto?)
    • Wenn externer Server: Interface-Modul: MQTT2_CLIENT oder 00_MQTT.pm?
    • Wenn MQTT2_SERVER: list beifügen und klären, ob dieser von der jeweiligen Komponente aus im Netzwerk zu erreichen ist:
      • steht auf "global"?
      • ggf. passendes allowed definiert, falls weiter entferntes Netzwerk oder falls Zugangsbeschränkungen/Authentifizierungsverfahren eingestellt sind?
      • Modifikationen am autocreate-Attribut?
    • Bitte einen Hinweis, falls MQTT_GENERIC_BRIDGE definiert ist bzw. auch ein list von der MQTT_GENERIC_BRIDGE.
    • TYPE des eigentlichen MQTT-Devices (MQTT2_DEVICE, MQTT_DEVICE, TASMOTA_DEVICE, ...)
  • Informationen zur eigentlichen Komponente:
    • Hersteller, ggf. aktuell verwendete firmware incl. Version (Beispiel: ein Shelly-Gerät mit originaler firmware verhält sich anders als dasselbe Gerät mit Tasmota-, ESPEasy oder ESPurna-firmware!).
    • Infos zur MQTT-Konfiguration auf dem Gerät selbst
    • Bei weniger gängigen Komponenten oder Diensten:
      • (sofern vorhanden): Link zu Projektseiten, MQTT-API-Seiten usw..
      • Mittschnitte des MQTT-Verkehrs (z.B. durch Einschalten der rawEvents an den MQTT2-Interface-Modulen, s.o.).
    • Ein list des eigentlichen Devices - bei MQTT2_DEVICE gerne in Form einer RAW-Definition (list -r <devicename>).
  • Bei MQTT2-Einbindung und aktiviertem autocreate an den Interface-Modulen den Status des autocreate-'Devices:
list TYPE=autocreate

Älterer FAQ-Thread im Forum

Dieser ist hier zu finden. Bitte beachten: es sind einige grundlegende Informationen und Links zu vielen Tools und Fundstellen enthalten, allerdings nur bis zum Stand des Jahres 2017. Die neue Modulgeneration MQTT2_.* wird dort nicht behandelt.

Links

Hinweise

  1. Teilnehmer in diesem Sinne kann ein Stück Hardware mit einer MQTT-fähigen firmware sein, ein auf einem Computer laufendes Script (einschließlich eines MQTT-Server-Dienstes wie mosquitto oder MQTT2_SERVER, kurz: alles mögliche sein. Dadurch kann auch ein einzelner Computer unter mehreren ClientID's am MQTT-Datenaustausch beteiligt sein.
  2. Aufgrund dieser Funktionsweise sollte allerdings darauf geachtet werden, die Möglichkeiten des jeweiligen Servers zur Sicherung der Daten gegen unberechtigten Zugriff zu nutzen, insbesondere wenn die Art der Daten oder die sich hierdurch ergebenden Möglichkeiten, z.B. Schaltvorgänge in der realen Welt auszulösen, dies notwendig macht!
  3. Diese kann sich bei der Weitergabe der Nachricht ändern: Zunächst sendet ein Client eine Nachricht unter seiner ClientID, der MQTT-Server wird diese dann in der Regel durch seine Kennung ersetzten, wenn er die Nachricht an einen Abonnenten - der auch ein weiterer MQTT-Server sein kann - weitergibt.
  4. Bitte beachten Sie, dass (Stand: Janar 2021) MQTT2_SERVER nicht alle features des MQTT-Protokolls unterstützt.
  5. im Sinne des 2-stufigen Modulkonzepts
  6. Die Zahl 2 in den Modulnamen verweist nur darauf, dass es sich um eine neuere Modulfamilie handelt; die Kommunikation mit den externen Komponenten unterscheidet sich nicht zu den älteren Modulen, die vor dem Jahr 2018 genutzt werden konnten.
  7. vgl. hierzu diesen Beitrag von Rudolf König