(FHEM) 00 MQTT.pm

Aus TippvomTibb
Zur Navigation springen Zur Suche springen

00_MQTT.pm

Zurueck Uebersicht

Ein einzelnes MQTT-Gerät kann mehrere MQTT_DEVICE, MQTT_GENERIC_BRIDGE Clients und (veraltete) MQTT_BRIDGE Clients bedienen.  Jedes MQTT_DEVICE fungiert als Brücke zwischen einem Fhem-Gerät und mqtt. 
Hinweis: Dieses Modul basiert auf Net::MQTT, das zuerst von CPAN installiert werden muss.
Das Modul MQTT fungiert als Verbindung zwischen FHEM und einem MQTT Broker (Server) und repräsentiert ein MQTT Gateway. Die durch die Module MQTT_DEVICE oder (veraltet!) MQTT_BRIDGE (In neuen Installationen soll das Modul MQTT_GENERIC_BRIDGE bevorzugt werden.) repräsentierten Client-Geräte sind gesondert anzulegen. 

Nebenbemerkung: Genau wie in der Netzwerktechnik gehen scheinbar hier die Begriffe Gateway und Bridge munter durcheinander. Ein Gateway liegt im ISO/OSI und im TCP/IP auf verschiedenen Schichten! Weiterhin scheint es mit diesem Modul Probleme zu geben wenn der Broker nicht auf dem gleichen Server liegt, also die ip nicht localhost oder 127.0.0.1 ist. Aber selbst da gibt es Probleme. Solange ich keine triftigen Grund kenne werde ich auf den Einsatz dieses Moduls verzichten.

Es muss für jedes MQTT-Gateway ein Server (Broker) eingerichtet und erreichbar sein. 

Wenn also von einem MQTT-Gateway die Rede ist, ist damit ein FHEM-Device vom Typ MQTT (Modul 00_MQTT.pm)gemeint.

Define

define <name> MQTT <ip:port> [<username>] [<password>]

Set

set <name> connect
set <name> disconnect
set <name> publish [qos:?] [retain:?] <topic> <message>

Get

version (steht nur im Programmcode, tauscht sonst nirgends auf)

Readings

  

Attributes

keep-alive
attr <name> last-will [qos:?] [retain:?] <topic> <message>
attr <name> client-id client id
on-connect
on-disconnect
on-timeout
privacy 0|1

Erlaeuterungen

Hindernisse/Hinweise=

#1

Clients: MQTT_DEVICE und MQTT_BRIDGE

Abhaengigkeiten: DevIo.pm

Wenn eine 'Cannot load module MQTT' erscheint fhelt wohl das 'Net::MQTT'

cpan install Net::MQTT 

FHEM#>restart

Fehlermeldung:

2022.08.07 20:02:53.913 1: reload: Error:Modul 00_MQTT deactivated:
 Can't locate Net/MQTT/Constants.pm in @INC (you may need to install the Net::MQTT::Constants module) (@INC contains: ./lib ./FHEM . /usr/lib/perl5/site_perl/5.26.1/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.26.1 /usr/lib/perl5/vendor_perl/5.26.1/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.26.1 /usr/lib/perl5/5.26.1/x86_64-linux-thread-multi /usr/lib/perl5/5.26.1 /usr/lib/perl5/site_perl ./FHEM/lib) at ./FHEM/00_MQTT.pm line 42.
BEGIN failed--compilation aborted at ./FHEM/00_MQTT.pm line 42.

2022.08.07 20:02:53.913 0: Can't locate Net/MQTT/Constants.pm in @INC (you may need to install the Net::MQTT::Constants module) (@INC contains: ./lib ./FHEM . /usr/lib/perl5/site_perl/5.26.1/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.26.1 /usr/lib/perl5/vendor_perl/5.26.1/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.26.1 /usr/lib/perl5/5.26.1/x86_64-linux-thread-multi /usr/lib/perl5/5.26.1 /usr/lib/perl5/site_perl ./FHEM/lib) at ./FHEM/00_MQTT.pm line 42.
BEGIN failed--compilation aborted at ./FHEM/00_MQTT.pm line 42.

Loesung: Leider habe ich noch keinen Hinweis dazu erhalten welche der 3 Net::MQTT Libraries die richtige ist.

cpan[5]> i /Net-MQTT/
Distribution    BEANZ/Net-MQTT-1.163170.tar.gz
Distribution    JUERD/Net-MQTT-Simple-1.26.tar.gz
Distribution    KRENZKE/Net-MQTT-Simple-Auth-0.002.tar.gz
3 items found
cpan[6]> install BEANZ/Net-MQTT-1.163170.tar.gz

Nach dem Installieren war die Definition des Beispiels (s. u.) erfolgreich.

Das MQTT-modul macht nach einem Reconnect einen Retransmit aller noch nicht bestätigten (acknowledged bzw. completet) Messages.

Beispiele

Define MQTT.png
Define MQTT Attribute.png


define 00_MQTT_Test MQTT

Erstmal kam eine Fehlermeldung. Loesung siehe oben.

Beim zweiten Anlauf war die Definition erfolgreich, obwohl hier der notwendige Parameter der IP des MQTT-Server (Broker) weggelassen wurde.


Die 'Raw definition' sieht so aus:

defmod 00_MQTT_Test MQTT
setstate 00_MQTT_Test disconnected
setstate 00_MQTT_Test 2022-08-07 21:08:16 state disconnected


Etwas deutlicher im FHEM-Wiki:

define meinMQTTGW MQTT <Broker-IP>[:<Broker-Port>]

Allerdings fehlt hier der Hinweis auf die optionalen Parameter <username> und <password>.

Warum man bei der Broker-IP 127.0.0.1 den Vorzug vor localhost geben soll, wenn der MQTT-Server auf dem gleichen Rechner laeuft, erschlieszt sich mir nicht.

define 00_MQTT_test MQTT 127.0.0.1
2022.08.07 22:54:15.008 3: Opening 00_MQTT_Test device 127.0.0.1
2022.08.07 22:54:15.008 1: 00_MQTT_Test: Can't open 127.0.0.1: No such file or directory
defmod 00_MQTT_Test MQTT localhost:1883
2022.08.07 23:02:18.153 3: Opening 00_MQTT_Test device localhost:1883
2022.08.07 23:02:18.157 3: 00_MQTT_Test device opened
2022.08.07 23:03:18.633 3: Opening 00_MQTT_Test device 127.0.0.1:1883
2022.08.07 23:03:18.637 3: 00_MQTT_Test device opened

Die Warnung von oben hat sich bestaetigt. Wenn man in DEF zwischen localhost und 127.0.0.1 wechselt und mit 'set disconnect' und 'set connect' den STATE beobachtet, ergibt sich folgende Meldung:

2022.08.07 23:05:42.513 1: 127.0.0.1:1883 disconnected, waiting to reappear (00_MQTT_Test)
2022.08.07 23:05:45.503 1: 127.0.0.1:1883 reappeared (00_MQTT_Test)
2022.08.07 23:05:45.516 1: 127.0.0.1:1883 disconnected, waiting to reappear (00_MQTT_Test)
2022.08.07 23:05:46.003 1: localhost:1883 reappeared (00_MQTT_Test)

Mit 'set <name> publish [qos:?] [retain:?] <topic> <message>' kann man Messages absetzen. qos meint Quality of Service und retain meint das die Nachricht aufbewahrt werden soll. qos kann die Werte [0,1,2] annehmen. QOS ist im Publish Fixed Header in 2 Bit codiert. Eine vierte Stufe (3) ist denkbar aber im MQTT-Standard nicht implementiert. Das Retain ist ein 1-Bit Flag im Header. Um eine Nachricht die mit retain:1 verschickt wurde wieder zu loeschen ist eine Nachricht wieder mit retain:1, dem gleiche Topic und dem NULL_String zu senden.

set <MQTT> publish retain:1 <topic> <"" oder >


Attribute

Die Attribute kann man in 3 Gruppen teilen.

Gruppe 1: MQTT spezifisch

keep-alive siehe meine Erlaeuterung dazu
attr <name> last-will [qos:?] [retain:?] <topic> <message> siehe meine Erlaeuterung dazu

Ich habe grosze Zweifel, dass hier die beiden Attribute richtig implementiert sind. Stellt man zum Beispiel keep-alive auf 1 (Sekunde) dann wird der Client auf dem Server nicht nach 1 Sekunde disconnectet, sondern der das connection-reading laeuft im Sekundentakt. ???

Gruppe 2: Verhalten des FHEM-DEVICES

attr <name> client-id client id

Mit diesem Attribut kan die Client ID mit der sich das FHEM-DEVICE am MQTT-Server anmeldet geaendert werden. Wenn das Attribut nicht gesetzt ist wird die FUUID als Client ID genommen.

1659906662: New connection from 127.0.0.1:39670 on port 1883.
1659906662: New client connected from 127.0.0.1:39670 as 62f02811-f33f-7372-6a3f-c658ba3431097541 (p1, c1, k60).
1659906854: Client 62f02811-f33f-7372-6a3f-c658ba3431097541 disconnected.
1659906854: New connection from 127.0.0.1:39722 on port 1883.
1659906854: New client connected from 127.0.0.1:39722 as clientid (p1, c1, k60).
attr <name> on-connect {Perl-expression} <topic> <message>
attr <name> on-disconnect {Perl-expression} <topic> <message>
attr <name> on-timeout {Perl-expression} 

Im Prinzip sind alle drei Attribute gleich. Bei 'on-connect' und 'on-disconnect' wird eine Nachricht (<message>) an den angegebenen Topic gesendet. Die Perl-expression darf hier weggelassen werden. Bei diesen beiden Attributen ist dieser Publish sozusagen das "Gegenteil" des Last Will Wird die Perl-expression uebergeben wird diese nach einem connect oder disconnect zuerst ausgewertet und die Nachricht erst im Falle eines (Rueckgabe-)wertes von true, 1 oder undef, gesendet. Die folgenden Variablen werden bei der Auswertung an den Ausdruck übergeben: $hash, $name, $qos, $retain, $topic, $message.

Bei 'on-timeout' die Perl-expression wegzulassen ist dagegen sinnlos. Welcher timeout hier gemeint sein koennte muss ich noch herausfinden.

Beispiele: attr mqtt on-connect /topic/status connected attr mqtt on-connect {Log3("abc",1,"on-connect")} /fhem/status connected

Ein sinnvoller Einsatz der Perl-Expression ist mir noch nicht eingefallen.

Gruppe 3: Bedeutung TODO

privacy 0|1

Anwendungen

Eine sinnvolle Anwendung habe ich noch keine. Nach dem Anlegen des Devices kann man Nachrichten mit set verschicken. Ich habe bisher diesen Devicetyp nur zum Testen benutzt.