Ich bin vor geraumer Zeit von der ursprünglichen auf die MQTT2 Lösung migriert. Seit dem habe ich das Problem daß das Versenden von Daten (MQTT Publishing) funktioniert, nicht aber deren Empfang (MQTT Subskription). Ich nutze einen externen MQTT Broker der aus dem Subnet meiner FHEM-Instanzen erreichbar ist.
#
# MQTT Devices
define emqttd MQTT2_CLIENT 192.168.###.###:1883
setuuid emqttd 5f815e86-f33f-cc95-f674-1293c51f2e8d8768
attr emqttd clientId FHEM-DG_MQTT
attr emqttd icon mqtt
attr emqttd room MQTT
Ich habe eine Reihe von zum Beispiel Schaltdevices mit einer eigenen Software die den jeweiligen Topic actor/indoor/dg/GERAETEID
subscriben und dort den Schaltbefehl erwarten. Darüberhinaus publishen sie auf ihrem jeweiligen Topic actor/indoor/dg/GERAETEID/status
eben diesen in Form einer einfachen JSON-Struktur
{
"Timestamp" : "2021-04-22 08:15:50",
"State" : "OFF"
}
Entsprechend habe ich ein MQTT2_DEVICE angelegt:
define deckenventilator_Eszecke MQTT2_DEVICE
setuuid deckenventilator_Eszecke 5f815e86-f33f-cc95-fdd2-e938ce4b22ac6cd0
attr deckenventilator_Eszecke IODev emqttd
attr deckenventilator_Eszecke devStateIcon off:Ventilator_fett on:Ventilator_wind
attr deckenventilator_Eszecke icon Ventilator_fett
attr deckenventilator_Eszecke readingList actor/indoor/dg/deckenluefter/status:.* { json2nameValue($EVENT) }
attr deckenventilator_Eszecke room Eszecke,MQTT
attr deckenventilator_Eszecke setList on actor/indoor/dg/deckenluefter on\
off actor/indoor/dg/deckenluefter off
Über FHEM kann ich entsprechend Ein- und Ausschalten, das Auslesen des Status erfolgt hingegen nicht. Irgendwie scheint der Subscribe und die die Notification nicht zu funktionieren, entsprechend werden auch Statusänderungen die durch andere Quellen als FHEM ausgelöst werden nicht korrekt dargestellt.
Wie läßt sich nachvollziehen warum der Topic nicht subscribed und verarbeitet wird?
Vorab mal: Willkommen im Forum!
"Eigentlich" müsste das klappen. Leider kann man an direkten fhem.cfg-Auszügen nichts über den aktuellen Zustand der Geräte (v.a. des MQTT2_CLIENT) erfahren. Bitte stelle daher mal ein "list" von dem emqttd ein.
Falls FHEM nicht aktuell ist, bitte vorab ein update machen oder wenigstens den output von "version MQTT2_.*" posten.
MQTT2_CLIENT sendet folgende Subscription an dem Server:
- #, oder
- das subscriptions Attribut, falls gesetzt, oder
- falls das subscriptions Attribut setByTheProgram ist, den Inhalt des .subscriptions Internals. Das sieht man mit "list mqtt2_client", wenn man "attr global showInternalValues 1" gesetzt hat.
Vielen Dank für die rasche Antwort. Hier die ergänzenden Informationen:
version MQTT2_.*
00_MQTT2_CLIENT.pm 22830 2020-09-23 14:35:44Z rudolfkoenig
10_MQTT2_DEVICE.pm 22458 2020-07-24 07:42:21Z rudolfkoenig
doif.js 15546 2017-12-03 09:57:42Z Ellert
fhemweb.js 22618 2020-08-17 16:21:28Z rudolfkoenig
list emqttd
Internals:
BUF
DEF 192.168.###.###:1883
DeviceName 192.168.###.###:1883
FD 4
FUUID 5f815e86-f33f-cc95-f674-1293c51f2e8d8768
NAME emqttd
NR 222
PARTIAL
STATE opened
TYPE MQTT2_CLIENT
WBCallback
clientId FHEM-DG_MQTT
lastMsgTime 1619084214.36824
nextOpenDelay 5
READINGS:
2020-10-03 17:14:48 lastPublish actor/indoor/dg/deckenluefter:on
2021-04-22 10:14:52 state opened
Attributes:
clientId FHEM-DG_MQTT
icon mqtt
room MQTT
Mit
Zitatlist mqtt2_client
ist doch mein definiertes MQTT2_CLIENT Device
emqttd gemeint?
Zitat von: FHEMbaer am 22 April 2021, 11:45:43
Mit ist doch mein definiertes MQTT2_CLIENT Device emqttd gemeint?
Ja, das paßt so. Damit ist der aktuelle Zustand im laufenden System gemeint, siehe "help list".
NAn. solltest du als erstes ein update machen, die MQTT2-Module sind "reichlich veraltet".
Update ist durch:
00_MQTT2_CLIENT.pm 23899 2021-03-06 13:08:15Z rudolfkoenig
10_MQTT2_DEVICE.pm 23843 2021-02-27 19:42:42Z rudolfkoenig
doif.js 15546 2017-12-03 09:57:42Z Ellert
fhemweb.js 23979 2021-03-15 14:00:33Z rudolfkoenig
und es gibt mehr Internats zu sehen
Internals:
BUF
Clients :MQTT2_DEVICE:MQTT_GENERIC_BRIDGE:
ClientsKeepOrder 1
DEF 192.168.###.###:1883
DeviceName 192.168.###.###:1883
FD 4
FUUID 5f815e86-f33f-cc95-f674-1293c51f2e8d8768
NAME emqttd
NR 222
PARTIAL
STATE opened
TYPE MQTT2_CLIENT
WBCallback
clientId FHEM-DG_MQTT
lastMsgTime 1619088940.64553
nextOpenDelay 5
MatchList:
1:MQTT2_DEVICE ^.
2:MQTT_GENERIC_BRIDGE ^.
READINGS:
2020-10-03 17:14:48 lastPublish actor/indoor/dg/deckenluefter:on
2021-04-22 12:35:40 state opened
Attributes:
clientId FHEM-DG_MQTT
icon mqtt
room MQTT
Aber an dem prinzipiellen Problem ändert es aber leider nichts :'( Merkwürdig finde ich auch die erste Zeile in READINGS, der TimeStamp ändert sich nicht selbst wenn ich aktiv via FHEM einen Wechsel vornehme...
Ich bin ziemlich ratlos...
Das ist in der Tat seltsam, lastPublish sollte aktualisiert werden.
Der Server ist nicht zufällig Passwortgeschützt?
Ggf. wäre es für Rudi noch hilfreich zu wissen, was das genau für ein MQTT-Server ist (auch die Version und ggf. Einstellungen zum MQTT-Protokoll).
Nein, der Server ist im Moment offen, also keine User/Password und auch kein TLS. Ich verwende EMQ X in der Version 4.2 https://docs.emqx.io/en/broker/v4.2/ (https://docs.emqx.io/en/broker/v4.2/). Deployed ist er als Docker Image in der Version 4.2.4 auf einem Odroid. Ich habe sicherheitshalber nur einen Knoten laufen und habe alle Cluster Features abgeschaltet. Ich hatte bisher mit keinem Client und keiner Client-Bibliothek für MQTT bisher ein Problem, daher ist meine Verwunderung das es nicht funktioniert sehr groß...
Ich kann erkennen das mein MQTT2_CLIENT emqttd mit meiner definierten clientId im MQTT Broker als aktiver Client (CONNECTED) aufgeführt ist. In der Übersicht der aktiven Subscriptions hingegen erscheint er nicht.
Ich wuerde mit "attr emqttd verbose 5" eine Verbindung aufbauen, und im FHEM-Log schauen, was genau via subscriptions bestellt wird.
2021.04.22 17:31:54 5: HttpUtils url=http://192.168.###.###:1883/
2021.04.22 17:31:54 4: IP: 192.168.###.### -> 192.168.###.###
2021.04.22 17:31:54 5: emqttd: sending CONNECT (16)(26)(0)(6)MQIsdp(3)(2)(0)(30)(0)(12)FHEM-DG_MQTT
2021.04.22 17:31:54 5: SW: 101a00064d51497364700302001e000c4648454d2d44475f4d515454
2021.04.22 17:31:54 1: 192.168.###.###:1883 reappeared (emqttd)
2021.04.22 17:31:54 5: emqttd: received CONNACK (0)(0)
2021.04.22 17:31:54 5: emqttd: sending SUBSCRIBE (130)(6)(0)(4)(0)(1)#(0)
Wie sind denn die Klammerausdrücke zu verstehen? Verstehe ich das richtig: der MQTT2_CLIENT versucht den kompletten Topic-Baum zu subscriben? Das ist keine gute Idee: Subscription with a multi-level wildcard alone is an anti-pattern. Läßt sich dem MQTT2_CLIENT eine Liste von Topic definieren für die ein SUBSCRIBE durchgeführt werden soll? Ich würde die ACL meines Brokers nur ungerne ändern um '#' zuzulassen, zumal dann das arme FHEM mit einem sehr großen Topic-Baum mit viel Dynamik zum durchforsten bekommt...
Für das Eingrenzen der subscriptions gibt es extra ein Attribut. "Einfach" da die entsprechenden Topics eintragen.
Zum Glück hast du hier relativ stringent organisierte Topics, sonst kann das "abenteuerlich" werden...
ZitatWie sind denn die Klammerausdrücke zu verstehen?
In Klammer wird das angezeigt, was nicht druckbar ist, als Dezimalzahl.
ZitatVerstehe ich das richtig: der MQTT2_CLIENT versucht den kompletten Topic-Baum zu subscriben?
Ja, das habe ich versucht vorhin zu erklaeren.
ZitatDas ist keine gute Idee: Subscription with a multi-level wildcard alone is an anti-pattern.
Wo lernt man sowas?
Und vorallem: wenn man das doch macht, wieso akzeptiert der Server es, ohne Daten zu senden?
Nein der Server akzeptiert es nicht deswegen wird ja auch kein Acknowledge für die Subskription gesendet. Das in diesem Fall auch kein NACK gesendet wird liegt einfach daran das die Access Control List Mechanismus den Request bereits geblockt hat. Um FHEM mit ernsthaften MQTT Broker Konfigurationen betreiben zu können wäre es hilfreich eine Alternative zur Root-Wildcard-Subscription anzubieten, zum Beispiel in Form einer Liste von Subscriptions (inklusive Wildcards).
Für mich ist das Problem nicht gelöst auch wenn ich im Moment eine im Prinzip funktionierende Konfiguration habe. Meinen MQTT Cluster in einer solchen Konfiguration zu betreiben und dann auch noch die FHEM Instanzen mit Notification zu fluten kann ich mir nicht vorstellen...
Zitatwäre es hilfreich eine Alternative zur Root-Wildcard-Subscription anzubieten,
Verstehe ich nicht, insb. das mit "wäre".
Was ist so falsch an dem subscriptions Attribut?
Ah jetzt ja – es hat etwas gedauert bis der Groschen die lange Leitung erfolgreich passiert hat :-[
MQTT2_CLIENT aggregiert also nicht die die Tonics aus den MQTT2_DEVICEs sondern umgekehrt nur die Subscriptions aus dem Client können in den Devices genutzt werden. Und wenn ich im Client keine expliziten Subscriptions angebe dann versucht dieser eine Root-Wildcard-Subscription.
Nach dem es endlich Kling gemacht hat habe ich die Definitionen passend modifiziert:
#
# MQTT Devices
define emqttd MQTT2_CLIENT 192.168.###.###:1883
setuuid emqttd 5f815e86-f33f-cc95-f674-1293c51f2e8d8768
attr emqttd clientId FHEM-DG_MQTT
attr emqttd icon mqtt
attr emqttd room MQTT
attr emqttd subscriptions actor/#
attr emqttd verbose 5
define deckenventilator_Eszecke MQTT2_DEVICE
setuuid deckenventilator_Eszecke 5f815e86-f33f-cc95-fdd2-e938ce4b22ac6cd0
attr deckenventilator_Eszecke IODev emqttd
attr deckenventilator_Eszecke devStateIcon off:Ventilator_fett on:Ventilator_wind
attr deckenventilator_Eszecke icon Ventilator_fett
attr deckenventilator_Eszecke jsonMap State:state Timestamp:statusTime
attr deckenventilator_Eszecke readingList actor/indoor/dg/deckenluefter/status:.* { json2nameValue($EVENT,'',$JSONMAP) }
attr deckenventilator_Eszecke room Eszecke,MQTT
attr deckenventilator_Eszecke setList on actor/indoor/dg/deckenluefter on\
off actor/indoor/dg/deckenluefter off
attr deckenventilator_Eszecke userReadings state {if(ReadingsVal("deckenventilator_Eszecke","state","") eq "ON") {return "on"} else {return "off"}}
Damit klappt dann auch der Startup wie gewünscht:
2021.04.23 09:39:51 5: HttpUtils url=http://192.168.###.###:1883/
2021.04.23 09:39:51 4: IP: 192.168.###.### -> 192.168.###.###
2021.04.23 09:39:51 5: emqttd: sending CONNECT (16)(26)(0)(6)MQIsdp(3)(2)(0)(30)(0)(12)FHEM-DG_MQTT
2021.04.23 09:39:51 5: SW: 101a00064d51497364700302001e000c4648454d2d44475f4d515454
2021.04.23 09:39:51 1: 192.168.###.###:1883 reappeared (emqttd)
2021.04.23 09:39:51 5: emqttd: received CONNACK (0)(0)
2021.04.23 09:39:51 5: emqttd: sending SUBSCRIBE (130)(12)(0)(4)(0)(7)actor/#(0)
2021.04.23 09:39:51 5: emqttd: received SUBACK (0)(4)(0)
Vielen Dank für den Support!
Schön, dass das jetzt so klappt, wie du das haben willst.
Vielleicht noch ein Hinweis, da du mehrere FHEM-Instanzen zu haben scheinst:
ignoreRegexp wäre das Mittel der Wahl, um dann die Topics auszufiltern, über die Kommandos an die (Nicht-FHEM-) Clients geschickt werden. Sonst kann es sein, dass Anweisungen und erfolgreiche Umsetzung nicht unterschieden werden können.