MQTT GENERIC BRIDGE: Unterschied zwischen den Versionen

Aus FHEMWiki
(insbes. mqttAlias in Subscription korrigiert)
(Klarstellung bzgl. ClientID und mosquitto_pub)
 
(8 dazwischenliegende Versionen von 6 Benutzern werden nicht angezeigt)
Zeile 11: Zeile 11:
==Einführung==
==Einführung==


Das Modul ''MQTT_GENERIC_BRIDGE'' stellt eine zentrale Schnittstelle zum MQTT-Protokoll für beliebig viele andere FHEM-Geräte bereit. Es wird für eine FHEM-Installation jeweils nur ein erreichbarer MQTT-Server sowie eine Instanz der ''MQTT_GENERIC_BRIDGE'' benötigt.
Das Modul ''MQTT_GENERIC_BRIDGE'' stellt eine zentrale Schnittstelle zum MQTT-Protokoll für beliebig viele andere FHEM-Geräte bereit. Es wird für eine FHEM-Installation jeweils nur ein erreichbarer MQTT-Server sowie eine Instanz der ''MQTT_GENERIC_BRIDGE'' benötigt. Es ist aber auch möglich, mehrere Server parallel zu betreiben.


Dieses Modul kann seit November 2018 mit allen drei IO-Modul-Varianten zusammen eingesetzt werden, also sowohl mit {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}} bzw. [[MQTT2_CLIENT]] oder [[MQTT (Modul)|MQTT]](00_MQTT.pm), und seit Rev. 23514 (Jan. 2021) wird für ''MQTT_GENERIC_BRIDGE'' iVm. den MQTT2-IO-Modulen keine zusätzliche Software mehr benötigt.  
Dieses Modul kann seit November 2018 mit allen drei IO-Modul-Varianten zusammen eingesetzt werden, also sowohl mit {{Link2CmdRef|Anker=MQTT2_SERVER|Lang=en|Label=MQTT2_SERVER}} bzw. [[MQTT2_CLIENT]] oder [[MQTT (Modul)|MQTT]](00_MQTT.pm), und seit Rev. 23514 (Jan. 2021) wird für ''MQTT_GENERIC_BRIDGE'' iVm. den MQTT2-IO-Modulen keine zusätzliche Software mehr benötigt.  
Zeile 17: Zeile 17:
Dabei erfolgt an dem zentralen ''MQTT_GENERIC_BRIDGE''-Gerät selbst nur eine Basiskonfiguration, die Standardwerte für alle anzubindenden Geräte bereitstellt, alle übrigen Einstellungen erfolgen durch Attribute an dem jeweiligs anzubindenden Gerät selbst.  
Dabei erfolgt an dem zentralen ''MQTT_GENERIC_BRIDGE''-Gerät selbst nur eine Basiskonfiguration, die Standardwerte für alle anzubindenden Geräte bereitstellt, alle übrigen Einstellungen erfolgen durch Attribute an dem jeweiligs anzubindenden Gerät selbst.  


Beispiel: ein Aktor des Typs CUL_HM kann über MQTT-Kommandos an den für ihn passenden Topic an- oder ausgeschaltet werden oder auch einfach nur seinen aktuellen Schaltzustand per MQTT-Protokoll publizieren.
Beispiel: ein Aktor des Typs [[HomeMatic|CUL_HM]] kann über MQTT-Kommandos an den für ihn passenden Topic an- oder ausgeschaltet werden oder auch einfach nur seinen aktuellen Schaltzustand per MQTT-Protokoll publizieren.


==Installation==
==Installation==
Zeile 61: Zeile 61:


Damit sind die wesentlichen Vorarbeiten abgeschlossen, und die ''MQTT_GENERIC_BRIDGE'' kann bereits dafür genutzt werden, beliebige Reading- oder Attribut-Änderungen von FHEM-Devices über MQTT zu publishen oder entsprechende Anweisungen umzusetzen. Es wird jedoch empfohlen, zunächst noch einige grundlegende Einstellungen vorzunehmen. Hierfür - sowie dann auch für die Konfiguration der weiteren Devices, die an MQTT angebunden werden sollen, steht als Hilfsmittel [[attrTemplate]] zur Verfügung.
Damit sind die wesentlichen Vorarbeiten abgeschlossen, und die ''MQTT_GENERIC_BRIDGE'' kann bereits dafür genutzt werden, beliebige Reading- oder Attribut-Änderungen von FHEM-Devices über MQTT zu publishen oder entsprechende Anweisungen umzusetzen. Es wird jedoch empfohlen, zunächst noch einige grundlegende Einstellungen vorzunehmen. Hierfür - sowie dann auch für die Konfiguration der weiteren Devices, die an MQTT angebunden werden sollen, steht als Hilfsmittel [[attrTemplate]] zur Verfügung.
Hinweis: Eventuell muss erst noch (einmalig) der zugehörige attrTemplate-Satz gelesen werden. Dies erfolgt mittels
{AttrTemplate_Initialize()}


===Basisangaben in der MQTT_GENERIC_BRIDGE selbst===
===Basisangaben in der MQTT_GENERIC_BRIDGE selbst===
Zeile 85: Zeile 82:
===Readingwerte publishen===
===Readingwerte publishen===
====mqttPublish====
====mqttPublish====
{{Randnotiz|RNTyp=y|RNText=Der Name der Attribute kann anweichen, falls ein anderes ''MQTT-Präfix'' über das ''Define'' in der ''MQTT_GENERIC_BRIDGE'' gesetzt ist. Hier wird davon ausgegangen, dass dieses nicht geändert wurde.}}Um Reading-Werte von einem Gerät zu versenden, wird das Attribut ''mqttPublish'' verwendet. Im einfachsten Fall wird festgelegt, welche Readings versendet werden sollen, und unter welchem Topic. Für einen beliebigen Temperatursensor könnte dies z.B. so aussehen:
{{Randnotiz|RNTyp=y|RNText=Der Name der Attribute kann abweichen, falls ein anderes ''MQTT-Präfix'' über das ''Define'' in der ''MQTT_GENERIC_BRIDGE'' gesetzt ist. Hier wird davon ausgegangen, dass dieses nicht geändert wurde.}}
 
Um Reading-Werte von einem Gerät zu versenden, wird das Attribut ''mqttPublish'' verwendet. Im einfachsten Fall wird festgelegt, welche Readings versendet werden sollen, und unter welchem Topic. Für einen beliebigen Temperatursensor könnte dies z.B. so aussehen:
  attr mySensor mqttPublish temperature:topic={"$base/$device/$name"}
  attr mySensor mqttPublish temperature:topic={"$base/$device/$name"}
In der Linux.Konsole, in der ''mosquitto_sub'' läuft, sollte jetzt bei jeder Aktualisierung des Sensor-Werts anzeigen, dass eine entsprechende Message an den MQTT-Server gesendet wurde. Dies geschieht [[Event|Event-basiert]], so dass sich hier ggf. auch insbesondere Einstellungen im Attribut [[Event-on-change-reading|event-on-change-reading]] auf die Häufigkeit der Aktualisierung auswirken.
In der Linux.Konsole, in der ''mosquitto_sub'' läuft, sollte jetzt bei jeder Aktualisierung des Sensor-Werts anzeigen, dass eine entsprechende Message an den MQTT-Server gesendet wurde. Dies geschieht [[Event|Event-basiert]], so dass sich hier ggf. auch insbesondere Einstellungen im Attribut [[Event-on-change-reading|event-on-change-reading]] auf die Häufigkeit der Aktualisierung auswirken.
Zeile 105: Zeile 104:


====state====
====state====
Da das Reading ''state'' in FHEM in der Regel eine Art Haupzustand eines Geräts beschreibt, wird für die weiter unten dargestellten ''attrTemplate'' dieses Reading kein ''$name''-Anteil im Topic versendet. Ein einfaches "ein-aus"-Gerät kann man dieser Vorgabe folgend daher so konfigurieren:
Da das Reading ''state'' in FHEM in der Regel eine Art Hauptzustand eines Geräts beschreibt, wird für die weiter unten dargestellten ''attrTemplate'' dieses Reading kein ''$name''-Anteil im Topic versendet. Ein einfaches "ein-aus"-Gerät kann man dieser Vorgabe folgend daher so konfigurieren:
  attr myRelay mqttPublish state:topic={"$base/$device"}
  attr myRelay mqttPublish state:topic={"$base/$device"}


Zeile 114: Zeile 113:
  attr myRGBLight mqttPublish state:topic={"$base/$device"} pct|rgb:topic={"$base/$device/$name"}
  attr myRGBLight mqttPublish state:topic={"$base/$device"} pct|rgb:topic={"$base/$device/$name"}


 
===Geräte steuern===
===Geräte ein- und ausschalten===
{{Randnotiz|RNTyp=y|RNText=Kommt als MQTT-Server MQTT2_SERVER zum Einsatz, ist beim publishen via ''mosquitto_pub'' zwingend eine ''ClientID'' mit anzugeben, andernfalls werden die so generierten Messages eventuell nicht ausgewertet!}}Um Geräte über die MQTT-Schnittstelle bedienen zu können, wird zum einen eine Software benötigt, mit der man entsprechende publish-Anweisungen generieren kann. Dies kann z.B. das bereits genannte ''mosquitto_pub'' sein.
{{Randnotiz|RNTyp=y|RNText=Kommt als MQTT-Server MQTT2_SERVER zum Einsatz, ist zwingend eine ''ClientID'' mit anzugeben, andernfalls werden die so generierten Messages eventuell nicht ausgewertet!}}Um Geräte über die MQTT-Schnittstelle bedienen zu können, wird zum einen eine Software benötigt, mit der man entsprechende publish-Anweisungen generieren kann. Dies kann z.B. das bereits genannte ''mosquitto_pub'' sein.
====mqttSubscribe====
====mqttSubscribe====
Spiegelbildlich zum o.g. ''mqttPublish''-Attribut wird über das jeweilige ''mqttSubscribe''-Attribut festgelegt, welche Topics für das FHEM-Gerät ausgewertet werden sollen und welchen Readings diese zugeordnet sind.  
Spiegelbildlich zum o.g. ''mqttPublish''-Attribut wird über das jeweilige ''mqttSubscribe''-Attribut festgelegt, welche Topics für das FHEM-Gerät ausgewertet werden sollen und welchen Readings diese zugeordnet sind.  
Für ein einfaches "ein-aus"-Gerät verwendet man daher denselben Attributwert wie für das ''mqttPublish'':
Für ein einfaches "ein-aus"-Gerät verwendet man daher denselben Attributwert wie für das ''mqttPublish'':
  attr myRelay mqttSubscribe state:topic={"$base/$device"}
  attr myRelay mqttSubscribe state:stopic={"$base/$device"}


Da wir oben in ''globalDefaults'' für ''sub:$base=mqttGenericBridge/set'' festgelegt haben, muss die Schaltanweisung allerdings an einen anderen Topic erfolgen als die Statusmeldung, die wir wegen des ''mqttPublish''-Attributs erhalten - auf diese Weise können unbeabsichtigte Schleifen unterbunden werden.   
Da wir oben in ''globalDefaults'' für ''sub:$base=mqttGenericBridge/set'' festgelegt haben, muss die Schaltanweisung allerdings an einen anderen Topic erfolgen als die Statusmeldung, die wir wegen des ''mqttPublish''-Attributs erhalten - auf diese Weise können unbeabsichtigte Schleifen unterbunden werden.   
Zeile 127: Zeile 125:
  mosquitto_pub -h 127.0.0.1 -i fhem-test -t mqttGenericBridge/set/myRelay -m on
  mosquitto_pub -h 127.0.0.1 -i fhem-test -t mqttGenericBridge/set/myRelay -m on


Bei ''mosquitto_sub'' auf der Linux-Konsole sollte jetzt zunächst die Schaltanweisung (Topic mit ''set'-Element) wie auch die Readingänderung am Device vermeldet werden.
Bei ''mosquitto_sub'' auf der Linux-Konsole sollte jetzt zunächst die Schaltanweisung (Topic mit ''set-Element'') wie auch die Readingänderung am Device vermeldet werden.


====Geräte mit mehreren Settern====
====Geräte mit mehreren Settern====
Das Prinzip dürfte jetzt klarer sein, also versuchen wir es direkt mit unserer farbigen Leuchte:
Das Prinzip dürfte jetzt klarer sein, also versuchen wir es direkt mit unserer farbigen Leuchte:
  attr myRGBLight mqttSubscribe state:topic={"$base/$device"} pct|rgb:topic={"$base/$device/$name"}
  attr myRGBLight mqttSubscribe state:stopic={"$base/$device"} pct|rgb:stopic={"$base/$device/$name"}
Und schon sollte diese über ''msoquitto_pub'' bzw. MQTT schalt- und dimmbar sein und Farbänderungen entegennehmen - und natürlich den zugehörigen Status zurückmelden.
Und schon sollte diese über ''msoquitto_pub'' bzw. MQTT schalt- und dimmbar sein und Farbänderungen entgegennehmen - und natürlich den zugehörigen Status zurückmelden.


====mqttAlias====
====mqttAlias====
Bei den Supscriptions besteht derzeit nicht die Möglichkeit, ''mqttAlias'' zu verwenden und die Namen über diesen Weg zu verändern.
Auch bei den Supscriptions besteht die Möglichkeit, ''mqttAlias'' zu verwenden und die Namen über diesen Weg zu verändern. Dies kann insbesondere sinnvoll sein, um in externen Anwendungen dann (dort) dieselben Vorlagen nutzen zu können.
 
====topic, stopic und atopic====
In obigem Beispiel haben wir in ''mqttSubscribe'' das Schlüsselwort ''stopic'' (die Kurzform von ''set-topic'') verwendet. Dieses bewirkt bei einer entsprechenden MQTT-Nachricht dasselbe wie der FHEM-Befehl <code>set <device> <reading> <value></code>, also <code>set myRGBLight pct 70</code>. Daneben gibt es die weiteren Schlüsselwörter ''topic'' und ''atopic''.
* ''topic'' (Langform: readings-topic) entspicht einer ''setreading''-Anweisung. Dabei wird dann lediglich der Readingwert aktualisiert, allerdings (falls Hardware gesteuert werden könnte) aber kein Schaltbefehl an die Hardware gesendet. In Installationen ohne MQTT2-Interface kann dies dazu genutzt werden, [[Dummy|dummy]]-Geräte ähnlich flexibel zu verwenden wie [[MQTT2_DEVICE]].
* ''atopic'' (Langform: attr-topic) schließlich dient dazu, Attributwerte zu ändern. ''atopic'' kann auch in ''mqttPublish'' eingesetzt werden, um Änderungen der Attribut-Werte an den MQTT-Server zu übermitteln.


===Weitere Optionen===
===Weitere Optionen===
MQTT_GENERIC_BRIDGE bietet weitere Attribute, die im Zusammenspiel teils sehr umfassende weitere Möglichkeiten ergeben, Geräte an MQTT anzubinden. Einige der Möglichkeiten, insbesondere, über ''expression'' beliebigen Perl-Code zur Auswertung bzw. Strukturierung der Daten zu verwenden, sind in den Grundzügen weiter unten dargestellt.  
''MQTT_GENERIC_BRIDGE'' bietet weitere Attribute, die im Zusammenspiel teils sehr umfassende weitere Möglichkeiten ergeben, Geräte an MQTT anzubinden. Einige der Möglichkeiten, insbesondere, über ''expression'' beliebigen Perl-Code zur Auswertung bzw. Strukturierung der Daten zu verwenden, sind in den Grundzügen weiter unten dargestellt.  


==Standardisierung via attrTemplate==
==Standardisierung via attrTemplate==
Insbesondere zur Anbindung externer Lösungen ist es jedoch häufig ausreichend, die Geräte-Daten in einer etwas strukturierten Weise aufzubereiten. Dies ist das Ziel der für MQTT_GENERIC_BRIDGE entwickelten ''attrTemplate''.
Insbesondere zur Anbindung externer Lösungen ist es jedoch häufig ausreichend, die Geräte-Daten in einer etwas strukturierten Weise aufzubereiten. Dies ist das Ziel der für ''MQTT_GENERIC_BRIDGE'' entwickelten ''attrTemplate''.


(tbc)
(tbc)
Zeile 149: Zeile 152:
===expression===
===expression===


attr ZWave_THERMOSTAT_20 mqttGB1Alias reportedState=actuator
attr ZWave_THERMOSTAT_20 mqttGB1Alias reportedState=actuator
attr ZWave_THERMOSTAT_20 mqttGB1Publish desired-temp|temperature|reportedState:topic={"$base/$device/$name"} temperature:expression={$value=~m,(-?\d+(\.\d+)?),?::round($1,1):undef} reportedState:expression={$value=~m,dim.(\d+),?$1:undef}
attr ZWave_THERMOSTAT_20 mqttGB1Publish desired-temp|temperature|reportedState:topic={"$base/$device/$name"} temperature:expression={$value=~m,(-?\d+(\.\d+)?),?::round($1,1):undef} reportedState:expression={$value=~m,dim.(\d+),?$1:undef}
attr ZWave_THERMOSTAT_20 mqttGB1Subscribe desired-temp:stopic={"$base/$device/$name"}
attr ZWave_THERMOSTAT_20 mqttGB1Subscribe desired-temp:stopic={"$base/$device/$name"}


===JSON===
===JSON===
Zeile 308: Zeile 311:
attr <actor-device-name> mqttPublish pct:topic=haus/wohnzimmer/rollo/all/position state:topic=haus/wohnzimmer/rollo/all/state
attr <actor-device-name> mqttPublish pct:topic=haus/wohnzimmer/rollo/all/position state:topic=haus/wohnzimmer/rollo/all/state
attr <actor-device-name> mqttSubscribe pct:stopic=haus/wohnzimmer/rollo/all/set
attr <actor-device-name> mqttSubscribe pct:stopic=haus/wohnzimmer/rollo/all/set





Aktuelle Version vom 30. November 2022, 17:54 Uhr

MQTT_GENERIC_BRIDGE
Zweck / Funktion
Stellt für beliebige Geräte eine Schnittstellt zum MQTT-Protokoll zur Verfügung
Allgemein
Typ Gerätemodul
Details
Dokumentation EN / DE
Support (Forum) MQTT
Modulname 10_MQTT_GENERIC_BRIDGE.pm
Ersteller hexenmeister (Forum )
Wichtig: sofern vorhanden, gilt im Zweifel immer die (englische) Beschreibung in der commandref!



Clock - Under Construction.svg An dieser Seite wird momentan noch gearbeitet.


Einführung

Das Modul MQTT_GENERIC_BRIDGE stellt eine zentrale Schnittstelle zum MQTT-Protokoll für beliebig viele andere FHEM-Geräte bereit. Es wird für eine FHEM-Installation jeweils nur ein erreichbarer MQTT-Server sowie eine Instanz der MQTT_GENERIC_BRIDGE benötigt. Es ist aber auch möglich, mehrere Server parallel zu betreiben.

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), und seit Rev. 23514 (Jan. 2021) wird für MQTT_GENERIC_BRIDGE iVm. den MQTT2-IO-Modulen keine zusätzliche Software mehr benötigt.

Dabei erfolgt an dem zentralen MQTT_GENERIC_BRIDGE-Gerät selbst nur eine Basiskonfiguration, die Standardwerte für alle anzubindenden Geräte bereitstellt, alle übrigen Einstellungen erfolgen durch Attribute an dem jeweiligs anzubindenden Gerät selbst.

Beispiel: ein Aktor des Typs CUL_HM kann über MQTT-Kommandos an den für ihn passenden Topic an- oder ausgeschaltet werden oder auch einfach nur seinen aktuellen Schaltzustand per MQTT-Protokoll publizieren.

Installation

Vorbereitung

Im folgenden wird als MQTT-Server mosquitto verwendet, der in aktuellen Linux-Distributionen über die Paketverwaltung angeboten wird. Hier die Installation für Raspberry Pi OS:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install mosquitto

Es kann aber auch ein bereits vorhandener MQTT2_SERVER verwendet werden.

Grundsätzliche Konfiguration

Definition der Schnittstelle zum MQTT-Server (hier: auf demselben Raspberry):

defmod mqtt_io MQTT2_CLIENT 127.0.0.1:1883
attr mqtt_io alias MQTT Broker
attr mqtt_io devStateIcon .*active:none:disconnect .*disconnected:none:connect
attr mqtt_io group MQTT
attr mqtt_io icon mqtt
attr mqtt_io room IO_Devices

Wer möchte, kann den Status des FHEM-Servers per MQTT LWT mitteilen:

Für MQTT2_CLIENT:

attr mqtt_io lwt system/<fhem-name>/connection/status connection lost
attr mqtt_io lwtRetain 1
attr mqtt_io msgAfterConnect -r system/<fhem-name>/connection/status connected
attr mqtt_io msgBeforeDisconnect -r system/<fhem-name>/connection/status disconnected

Alternativ: für MQTT

attr mqtt last-will retain:1 system/<fhem-name>/connection/status connection lost
attr mqtt on-connect retain:1 {Log3("mqtt",3,"connected to MQTT server");;1} system/<fhem-name>/connection/status connected
attr mqtt on-disconnect retain:1 {Log3("mqtt",3,"disconnected from MQTT server");;1} system/<fhem-name>/connection/status disconnected

Definition der Generic Bridge

Der Name mqttGenericBridge kann dabei frei gewählt werden:

defmod mqttGenericBridge MQTT_GENERIC_BRIDGE
attr mqttGenericBridge IODev mqtt_io
attr mqttGenericBridge alias MQTT generic bridge
attr mqttGenericBridge group MQTT
attr mqttGenericBridge room IO_Devices
attr mqttGenericBridge stateFormat dev: device-count in: incoming-count out: outgoing-count

Damit sind die wesentlichen Vorarbeiten abgeschlossen, und die MQTT_GENERIC_BRIDGE kann bereits dafür genutzt werden, beliebige Reading- oder Attribut-Änderungen von FHEM-Devices über MQTT zu publishen oder entsprechende Anweisungen umzusetzen. Es wird jedoch empfohlen, zunächst noch einige grundlegende Einstellungen vorzunehmen. Hierfür - sowie dann auch für die Konfiguration der weiteren Devices, die an MQTT angebunden werden sollen, steht als Hilfsmittel attrTemplate zur Verfügung.

Basisangaben in der MQTT_GENERIC_BRIDGE selbst

attrTemplate base_settings_to_MQTT_GENERIC_BRIDGE

Zunächst werden die Basisangaben zur Struktur der zu verwendenden MQTT-Topics sowie - bei Verwendung eines MQTT2-Interface-Moduls - die clientOrder konfiguriert:

set mqttGenericBridge attrTemplate base_settings_to_MQTT_GENERIC_BRIDGE

Dies kann direkt über die Detailansicht des Geräts mqttGenericBridge erfolgen, siehe der nebenstehende screenshot, aus dem auch zu entnehmen ist, was das attrTemplate an Änderungen der Konfiguration vornehmen wird. Dies sind zwei Aspekte: Zum einen wird eine Variable namens $base in Sende- und in Empfangsrichtung festgelegt. In Senderichtung (pub:) besteht diese nur aus dem Namen der MQTT_GENERIC_BRIDGE, in Empfangsrichtung (sub:) aus dem Namen sowie dem Topic-Anteil set. Diese Angaben können im Prinzip beliebig geändert werden, es muss lediglich darauf geachtet werden, dass die Angaben unterschiedlich sind, sonst kann es zu unbeabsichtigten Schleifen kommen!

attrTemplate Anfrage der gewünschten Konfigurationsoption

Zum anderen wird - sofern ein MQTT2_CLIENT und MQTT2_SERVER als Interface verwendet wird - je nach Wahl des Nutzers in dem dann erscheinenden Dialogfeld - die clientOrder festgelegt. Wer hier unschlüssig ist, sollte die empfohlene Variante wählen, um Probleme im Zusammenspiel mit der autocreate-Funktion dieser Interface-Typen möglichst zu vermeiden.


Info blue.png
In vielen im Internet zu findenden Anleitungen wird pauschal das Attribut globalPublish gesetzt. Dieses führt allerdings dazu, dass zum einen sehr viele unwichtige Daten (oder eben ggf. auch unbeabsichtigt: eigentlich besser geheim zu haltende Daten?) an den MQTT-Server übermittelt werden, und zum anderen eine aufwändige Nachbearbeitung auf der Gegenseite erforderlich werden kann. Daher wird hiervon ausdrücklich abgeraten! Stattdessen kann man relativ einfach über den attrTemplate-Mechanismus (nur) die Informationen über MQTT verfügbar machen, die in der Regel für externe Anwendungen auch benötigt werden.


Basics zur Konfiguration der anzubindenden Geräte

Info green.pngAuch wer plant, später die Kommandos mit einer ganz anderen Software zu versenden, sollte zunächst den Weg über die Linux-Konsole und die Tools mosquitto_sub und mosquitto_pub gehen. So läßt sich die Funktionalität von FHEM und der MQTT_GENERIC_BRIDGE zunächst ohne weitere Störeinflüsse prüfen und andere User können leichter helfen, falls Probleme auftreten sollten.

Um gezielt einzelne Werte zu senden und auch nur gewünschte Anweisungen zu erhalten, ist stattdessen eine auf das jeweilige Gerät angepasste Konfiguration der Schnittstelle zu empfehlen. Um die hier dargestellten Schritte und deren Wirksamkeit zu prüfen, sollte der Verkehr von und zum MQTT-Server beobachtet werden. Im Folgenden werden hierfür die Programme mosquitto_sub und mosquitto_pub aus dem Paket mosquitto-clients verwendet. Auf einem Raspberry Pi OS können diese mit sudo apt-get install mosquitto-clients installiert werden. Beide Programme funktionieren auch mit einem MQTT2_SERVER.

Den Verkehr auf der Linux-Konsole kann man mit

mosquitto_sub -h 127.0.0.1 -i fhem-test -v -t mqttGenericBridge/# -t system/# 

verfolgen, gegebenenfalls sind Username und Passwort zu ergänzen, falls die Einstellungen am Server dies erfordern (siehe manpage zu mosquitto_sub).


Readingwerte publishen

mqttPublish

Emblem-question-yellow.svgDer Name der Attribute kann abweichen, falls ein anderes MQTT-Präfix über das Define in der MQTT_GENERIC_BRIDGE gesetzt ist. Hier wird davon ausgegangen, dass dieses nicht geändert wurde.


Um Reading-Werte von einem Gerät zu versenden, wird das Attribut mqttPublish verwendet. Im einfachsten Fall wird festgelegt, welche Readings versendet werden sollen, und unter welchem Topic. Für einen beliebigen Temperatursensor könnte dies z.B. so aussehen:

attr mySensor mqttPublish temperature:topic={"$base/$device/$name"}

In der Linux.Konsole, in der mosquitto_sub läuft, sollte jetzt bei jeder Aktualisierung des Sensor-Werts anzeigen, dass eine entsprechende Message an den MQTT-Server gesendet wurde. Dies geschieht Event-basiert, so dass sich hier ggf. auch insbesondere Einstellungen im Attribut event-on-change-reading auf die Häufigkeit der Aktualisierung auswirken.

Es können auch mehrere Readings erfasst werden, für einen typischen kombinierten Temperatur- und Luftfeuchtigkeitssensor könnte dies z.B. so aussehen:

attr mySensor mqttPublish temperature|humidity:topic={"$base/$device/$name"}

oder auch so:

attr mySensor mqttPublish temperature|humidity|battery:topic={"$base/$device/$name"}

Falls (!) erforderlich oder gewünscht, kann auch ein * als wildcard verwendet werden. Dann werden alle Readings gepublisht:

attr mySensor mqttPublish *:topic={"$base/$device/$name"}

mqttAlias

Verfolgt man den Verkehr eine Zeitlang, wird die Bedeutung der Variablen klarer: $base entspricht der Angabe aus den globalDefaults an der MQTT_GENERIC_BRIDGE, $device wird durch den Namen des Geräts in FHEM erstetzt, und $name entspricht (noch) dem Namen des Readings. Bis hierhin könnte man also auch statt einer MQTTT_GENERIC_BRIDGE problemlos ein notify verwenden, um die Events für direkte publish-Anweisungen am jeweiligen Interface-Modul (z.B. MQTT2_CLIENT) auszuwerten.

Eine MQTT_GENERIC_BRIDGE bietet jedoch auch für das Publishen erweiterte Funktionalitäten an. Die erste: Z.B. kann der Parameter $name - etwa zur Standardisierung der Namensstruktur der Readings - mit Hilfe des Attributs mqttAlias verändert werden. Durch die folgende Einstellung würde z.B. ein battery-Wert unter dem Topic-Teil batteryPercent versendet und das Reading measured-temp unter temperature:

attr mySensor mqttAlias battery=batteryPercent measured-temp=temperature

state

Da das Reading state in FHEM in der Regel eine Art Hauptzustand eines Geräts beschreibt, wird für die weiter unten dargestellten attrTemplate dieses Reading kein $name-Anteil im Topic versendet. Ein einfaches "ein-aus"-Gerät kann man dieser Vorgabe folgend daher so konfigurieren:

attr myRelay mqttPublish state:topic={"$base/$device"}

Für ein dimmbares Licht (das als Reading pct kennt) kombiniert man beides:

attr myDimmer mqttPublish state:topic={"$base/$device"} pct:topic={"$base/$device/$name"}

Und zu guter letzt noch als farbiges (mit Reading rgb) und dimmbares Licht:

attr myRGBLight mqttPublish state:topic={"$base/$device"} pct|rgb:topic={"$base/$device/$name"}

Geräte steuern

Emblem-question-yellow.svgKommt als MQTT-Server MQTT2_SERVER zum Einsatz, ist beim publishen via mosquitto_pub zwingend eine ClientID mit anzugeben, andernfalls werden die so generierten Messages eventuell nicht ausgewertet!

Um Geräte über die MQTT-Schnittstelle bedienen zu können, wird zum einen eine Software benötigt, mit der man entsprechende publish-Anweisungen generieren kann. Dies kann z.B. das bereits genannte mosquitto_pub sein.

mqttSubscribe

Spiegelbildlich zum o.g. mqttPublish-Attribut wird über das jeweilige mqttSubscribe-Attribut festgelegt, welche Topics für das FHEM-Gerät ausgewertet werden sollen und welchen Readings diese zugeordnet sind. Für ein einfaches "ein-aus"-Gerät verwendet man daher denselben Attributwert wie für das mqttPublish:

attr myRelay mqttSubscribe state:stopic={"$base/$device"}

Da wir oben in globalDefaults für sub:$base=mqttGenericBridge/set festgelegt haben, muss die Schaltanweisung allerdings an einen anderen Topic erfolgen als die Statusmeldung, die wir wegen des mqttPublish-Attributs erhalten - auf diese Weise können unbeabsichtigte Schleifen unterbunden werden.

Um jetzt mit mosquitto_pub eine passende Anweisung zu erzeugen, benötigen wir eine weitere (ssh-Linux-) Konsole, über die wir dann auf dem MQTT-Weg schalten können - vorausgesetzt, das Gerät myRelay kann den Befehl set myRelay on (bzw. off) verarbeiten. Auch hier wären ggf. die Zugangsdaten entsprechend der manpage zu ergänzen:

mosquitto_pub -h 127.0.0.1 -i fhem-test -t mqttGenericBridge/set/myRelay -m on

Bei mosquitto_sub auf der Linux-Konsole sollte jetzt zunächst die Schaltanweisung (Topic mit set-Element) wie auch die Readingänderung am Device vermeldet werden.

Geräte mit mehreren Settern

Das Prinzip dürfte jetzt klarer sein, also versuchen wir es direkt mit unserer farbigen Leuchte:

attr myRGBLight mqttSubscribe state:stopic={"$base/$device"} pct|rgb:stopic={"$base/$device/$name"}

Und schon sollte diese über msoquitto_pub bzw. MQTT schalt- und dimmbar sein und Farbänderungen entgegennehmen - und natürlich den zugehörigen Status zurückmelden.

mqttAlias

Auch bei den Supscriptions besteht die Möglichkeit, mqttAlias zu verwenden und die Namen über diesen Weg zu verändern. Dies kann insbesondere sinnvoll sein, um in externen Anwendungen dann (dort) dieselben Vorlagen nutzen zu können.

topic, stopic und atopic

In obigem Beispiel haben wir in mqttSubscribe das Schlüsselwort stopic (die Kurzform von set-topic) verwendet. Dieses bewirkt bei einer entsprechenden MQTT-Nachricht dasselbe wie der FHEM-Befehl set <device> <reading> <value>, also set myRGBLight pct 70. Daneben gibt es die weiteren Schlüsselwörter topic und atopic.

  • topic (Langform: readings-topic) entspicht einer setreading-Anweisung. Dabei wird dann lediglich der Readingwert aktualisiert, allerdings (falls Hardware gesteuert werden könnte) aber kein Schaltbefehl an die Hardware gesendet. In Installationen ohne MQTT2-Interface kann dies dazu genutzt werden, dummy-Geräte ähnlich flexibel zu verwenden wie MQTT2_DEVICE.
  • atopic (Langform: attr-topic) schließlich dient dazu, Attributwerte zu ändern. atopic kann auch in mqttPublish eingesetzt werden, um Änderungen der Attribut-Werte an den MQTT-Server zu übermitteln.

Weitere Optionen

MQTT_GENERIC_BRIDGE bietet weitere Attribute, die im Zusammenspiel teils sehr umfassende weitere Möglichkeiten ergeben, Geräte an MQTT anzubinden. Einige der Möglichkeiten, insbesondere, über expression beliebigen Perl-Code zur Auswertung bzw. Strukturierung der Daten zu verwenden, sind in den Grundzügen weiter unten dargestellt.

Standardisierung via attrTemplate

Insbesondere zur Anbindung externer Lösungen ist es jedoch häufig ausreichend, die Geräte-Daten in einer etwas strukturierten Weise aufzubereiten. Dies ist das Ziel der für MQTT_GENERIC_BRIDGE entwickelten attrTemplate.

(tbc)

Konfigurationsmöglichkeiten für Fortgeschrittene

expression

attr ZWave_THERMOSTAT_20 mqttGB1Alias reportedState=actuator
attr ZWave_THERMOSTAT_20 mqttGB1Publish desired-temp|temperature|reportedState:topic={"$base/$device/$name"} temperature:expression={$value=~m,(-?\d+(\.\d+)?),?::round($1,1):undef} reportedState:expression={$value=~m,dim.(\d+),?$1:undef}
attr ZWave_THERMOSTAT_20 mqttGB1Subscribe desired-temp:stopic={"$base/$device/$name"}

JSON

json2nameValue() und toJSON() via expression

publishes an mehrere Topics

"das Ausrufezeichen"


(Noch nachzubearbeiten, aus dem Thread Anwendungsfälle und Beispiele für MQTT_GENERIC_BRIDGE - https://forum.fhem.de/index.php/topic,91642.msg841367.html#msg841367)


eine Reading an einem beliebigen Device per MQTT setzen (für State-Reading soll state verwendet werden) Code: [Auswählen]

attr <device-name> mqttSubscribe <reading-name>:topic=<topic>

(anstatt 'topic' kann für eine bessere Lesbarkeit 'readings-topic' verwendet werden)

ein Set-Befehl an einem beliebigen Device mit dem per MQTT gesendeten Wert ausführen (für set ohne namen (set on, set off) soll state verwendet werden) Code: [Auswählen]

attr <device-name> mqttSubscribe <set-befehl>:stopic=<topic>

(anstatt 'stopic' kann für eine bessere Lesbarkeit 'set-topic' verwendet werden)

ein Attribut an einem beliebigen Device per MQTT setzen Code: [Auswählen]

attr <device-name> mqttSubscribe <attribut-name>:atopic=<topic>

(anstatt 'atopic' kann für eine bessere Lesbarkeit 'attr-topic' verwendet werden)

eine Änderung eines Readings per MQTT senen Code: [Auswählen]

attr <device-name> mqttPublish <readings-name>:topic=<topic>


eine Änderung eines Attributes per MQTT senen

attr <device-name> mqttPublish <attribut-name>:atopic=<topic>


Verwendung von Variablen Es können mit dem Attribute mqttDefaults Variablen definiert werden, die in mqttPublish und mqttSubscribe verwendet werden können: Code: [Auswählen]

attr <device-name> mqttDefaults base={"allgemeinerPfad/"} ... attr <device-name> mqttPublish <reading-name>:topic={"$base/irgendEinName"}

Weiterhin können in Topics folgende vordefinierte Variablen verwendet werden: $reading - aktuell zu verarbeitende Reading $device - aktulles Gerät $name - Die Variable $name wird im Unterschied zu $reading ggf. ueber die in 'mqttAlias' definierten Aliases beeinflusst. (s. Commandref für mqttAlias) Code: [Auswählen]

attr <device-name> mqttPublish <reading-name>:topic={"$base/$device/$name"}


Mehrere Readings auf einmal Es können für einen Topic (sinnigerweise mit Variablen) auch mehrere Readings gleichzeitig angegeben werden. Diese müssen in diesem Fall durch ein | getrennt werden: Code: [Auswählen]

attr <device-name> mqttPublish <reading-name1>|<reading-name2>:topic={"$base/$device/$name"}


Wildcards mit einem * kann ein Topic für alle Readings zusammen definiert werden: Code: [Auswählen]

attr <device-name> mqttPublish *:topic={"$base/$device/$name"}


Beim Subscribe können in der Topic-Definition auch MQTT-Wildcards (+ und #) verwendet werden. Falls der Reading-Name mit einem '*'-Zeichen am Anfang definiert wird, gilt dieser als 'Platzhalter'. Der tatsaechliche Name der Reading (und ggf. des Geraetes) wird dabei durch Variablen aus dem Topic definiert ($reading, $name). Im Topic wirken diese Variablen als Wildcards, macht natuerlich nur Sinn, wenn Reading-Name auch nicht fest definiert ist (also faengt mit '*' an).


Sensoren-Werte von einer FHEM-Instanz in eine andere übertragen

Definition für ein HomeMatic-Device (Dirk's-Sensor + Verwendung von DevPoint-Modul): (es werden gezielt bestimmte Werte übertragen) Code: [Auswählen]

defmod <sensor-device-name> CUL_HM xxxxxx attr <sensor-device-name> model HB-UW-Sen-THPL-I ... attr <sensor-device-name> mqttDefaults base=haus/wohnzimmer attr <sensor-device-name> mqttPublish humidity|luminosity|dewpoint|absoluteHumidity:topic={"$base/klima/$name"}


Definition eines Empfänger-Dummy: (es werden alle Werte bei passenden Topics empfangen) Code: [Auswählen]

defmod <dummy-device-name> dummy attr <dummy-device-name> readingList absoluteHumidity dewpoint humidity luminosity temperature vapourPressure attr <dummy-device-name> mqttDefaults base=haus/wohnzimmer attr <dummy-device-name> mqttSubscribe *:topic={"$base/klima/$reading"}

« Letzte Änderung: 11 Januar 2019, 21:31:38 von hexenmeister »


Aktoren, die in einer FHEM-Instanz definiert sind, aus einer anderen schalten Switch

Definition eines Schalters (EnOcean FSR14) Code: [Auswählen]

defmod <actor-device-name> EnOcean 0000000B attr <actor-device-name> IODev FGW14 attr <actor-device-name> alias Licht attr <actor-device-name> devStateIcon off:light_light_dim_00@gray on:light_light_dim_100@yellow .*:hourglass attr <actor-device-name> eep A5-38-08 attr <actor-device-name> group Beleuchtung attr <actor-device-name> gwCmd switching attr <actor-device-name> icon light_downlight attr <actor-device-name> manufID 00D attr <actor-device-name> mqttPublish state:topic=haus/wohnzimmer/licht/top/state attr <actor-device-name> mqttSubscribe state:stopic=haus/wohnzimmer/licht/top/set attr <actor-device-name> room Wohnzimmer attr <actor-device-name> subDef 0010000B attr <actor-device-name> subType gateway attr <actor-device-name> webCmd on:off



Aktoren, die in einer FHEM-Instanz definiert sind, aus einer anderen schalten Dimmer

Aktor-Definition: Code: [Auswählen]

defmod <actor-device-name> CUL_HM xxxxxx attr <actor-device-name> model HM-LC-Dim1TPBU-FM ... attr <actor-device-name> mqttPublish pct:topic=haus/wohnzimmer/licht/level state:topic=haus/wohnzimmer/licht/state attr <actor-device-name> mqttSubscribe pct:stopic=haus/wohnzimmer/licht/set


Aktoren, die in einer FHEM-Instanz definiert sind, aus einer anderen schalten Shutters / Blinds

Aktor-Definition: Code: [Auswählen]

defmod <actor-device-name> CUL_HM xxxxxx attr <actor-device-name> model HM-LC-Bl1PBU-FM ... attr <actor-device-name> mqttPublish pct:topic=haus/wohnzimmer/rollo/all/position state:topic=haus/wohnzimmer/rollo/all/state attr <actor-device-name> mqttSubscribe pct:stopic=haus/wohnzimmer/rollo/all/set


FAQ

Das ist so nicht vorgesehen, ein reading = ein Topic.


a) beim device-count werden nur Geräte gezählt, die mit eigenen mqtt*-Attributen versehen sind. Bei einer globalen Definition 'globalPublish' kann die Bridge nicht (ohne weiteres) wissen, welche Geräte angesprochen werden sollen. Daher wird auch nichts gezählt.

b) mqttSubscribe ist gedacht für diejenigen Geräte, die per MQTT 'versorgt' werden sollen. Die Bridge selbst gehört nicht dazu. Aus technischen Gründen kann es sein, dass diese Attribute trotzdem vom FHEM angeboten werden, gesetzt werden können sie jedoch nicht, die Bridge 'währt' sich dagegen. Ein 'globalSubscribe' gibt es nicht. Ich habe mich entschieden, diese Festure nicht anzubieten. Bei unbedachten Verwendung könnte ein großes Sicherheitsrisiko entstehen. Einfach diese Attribute an den gewünschgten Devices erstellen.

Die Definition lautet 'fhem room=MQTT_BRIDGE_DEVICES'. Der erste Parameter (wie im Commandref steht) ist der Prefix für die Optionsattribute. Ist für Sonderfälle gedacht, wenn mehr als eine Bridge im System vorhanen ist. Deine Parameter heißen also 'fhemSubscribe' etc.

Bin nun draufgekommen das dieses fehlerhafte Verhalten (Bridge geht nicht nach restart so lange bis man im User Interface DEF und "modify" geklickt hat) nur dann auftritt wenn device-count = 0 ist. Nun hab ich ein Device mit einem "fhemSubscribe" Attribut ausgestattet ... und nun lebt die Bridge auch nach einem Restart.


Du kannst aber mit * alle Readings greifen und dann mit Perlmitteln in der expression filtern.

irgendwie so (ungetestet): Code: [Auswählen]

desired-temp!info:expression={if($reading=~/SMAEM12345678.*/){$value}else{undef})}

Hinweise