Bei MQTT2_CLIENT auf Subscriptions reagieren

Begonnen von kampi, 29 August 2020, 14:48:41

Vorheriges Thema - Nächstes Thema

kampi

Hallo zusammen,

ich habe mittlerweile erfolgreich mein FHEM über MQTT mit ThingsBoard verbunden und bekomme nun schon ein paar Werte übertragen, die ich mir dann anzeigen lassen kann. Jetzt möchte ich noch auf Bedienelemente im Board reagieren können und dafür muss ich mich auf ein bestimmtes MQTT-Topic subscriben. Gemäß der Doku für einen MQTT2_CLIENT habe ich dies über das "subscriptions"-Attribut gemacht:


defmod ThingsBoard MQTT2_CLIENT 192.168.178.52:1883
attr ThingsBoard subscriptions v1/devices/me/rpc/request/+


Wie kann ich nun auf eine eingehende Nachricht in diesem Topic reagieren? Kann ich das über ein "notify" machen oder wie funktioniert das? In der Dokumentation und im Wiki habe ich leider nichts passendes gefunden.

Danke und Gruß


amenomade

Ja, Events im Eventmonitor beobachten, und dort das passende notify erstellen lassen.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

Beta-User

Oder autocreate auf simple stellen und mit MQTT2_DEVICE  als Zwischenschicht arbeiten.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kampi

Zitat von: amenomade am 29 August 2020, 14:51:34
Ja, Events im Eventmonitor beobachten, und dort das passende notify erstellen lassen.

Das habe ich gerade gemacht, aber anscheinend wird kein Event ausgelöst, wenn ich eine entsprechende Nachricht sende.

Beta-User

Um das im Event-Monitor zu sehen, muß bei dem MQTT2-IO's auch rawEvent entsprechend gesetzt werden. Falls das Teil im JSON-Format sendet, würde ich in jedem Fall MQTT2_DEVICE verwenden.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kampi

Zitat von: Beta-User am 29 August 2020, 15:43:24
Um das im Event-Monitor zu sehen, muß bei dem MQTT2-IO's auch rawEvent entsprechend gesetzt werden. Falls das Teil im JSON-Format sendet, würde ich in jedem Fall MQTT2_DEVICE verwenden.

Okay ich habe mir nun ein MQTT2_DEVICE angelegt:

defmod ThingsBoard_RPC MQTT2_DEVICE
attr ThingsBoard_RPC room ThingsBoard
attr ThingsBoard_RPC readingList v1/devices/me/rpc/request/+:.* { ThingsBoard_Utils_Receiver($NAME) }


Die Funktion ThingsBoard_Utils_Receiver ist ebenfalls definiert und schreibt vorerst nur was ins Log. Aber anscheinend scheint da nochwas falsch zu sein, weil wenn ich eine JSON-Nachricht mit dem Topic "v1/devices/me/rpc/request/+" sende passiert weiterhin nichts.

Beta-User

Lass besser mqtt2-autocreate machen, das geht idR. schneller. RL ist Perl/regex => .* statt +
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kampi


Beta-User

+ ist eine MQTT-Wildcard, readingList folgt aber Perl- bzw. allg. regex-Regeln (das subscriptions-Attribut am CLIENT folgt dagegen MQTT-Regeln, wenn ich die Commandref richtig lese).

Nochmal: Du tust dich leichter, wenn du das händisch erstellte Device löschst und einfach autocreate am CLIENT auf "simple" stellst (und dann dafür sorgst, dass auch Nachrichten kommen).

Das gibt dann zwar immer noch keine optimalen Ergebnisse bzw. Nacharbeitsbedarf, aber es ist einfacher, das dann hinterher zu (er-)klären.

rawEvents (aus dem Event-Monitor, kannst du beim CLIENT erst mal auf ".*" stellen) würde ich trotzdem gerne mal sehen (alternativ: den relevanten MQTT-Verkehr z.B. mit mosquitto_sub mitschneiden), die Doku ist nicht sonderlich aufschlußreich.
Entsprechendes gilt für das per autocreate dann erstellte Device; davon bitte ein RAW-list.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kampi

So ich habe die entsprechenden Attribute aktiviert


attr ThingsBoard autocreate 1
attr ThingsBoard subscriptions v1/devices/me/rpc/request/+


Nachdem ich einen Slider in meinem Dashboard bewegt habe, wurde ein entsprechendes Device angelegt und für jede Aktion kommt nun ein Eintrag in das Attribut "readingList".



2020-08-30 00:31:46 Global global UNDEFINED MQTT2_ThingsBoard MQTT2_DEVICE ThingsBoard ThingsBoard
2020-08-30 00:31:46 Global global DEFINED MQTT2_ThingsBoard
2020-08-30 00:31:46 Global global DEFINED FileLog_MQTT2_ThingsBoard
2020-08-30 00:31:46 MQTT2_CLIENT ThingsBoard v1/devices/me/rpc/request/48:{"method":"setValue","params":true}
2020-08-30 00:31:46 Global global ATTR MQTT2_ThingsBoard readingList ThingsBoard:v1/devices/me/rpc/request/48:.* { json2nameValue($EVENT) }
2020-08-30 00:31:46 MQTT2_DEVICE MQTT2_ThingsBoard method: setValue
2020-08-30 00:31:46 MQTT2_DEVICE MQTT2_ThingsBoard params: true


Im Event-Log erhalte ich die folgende Ausgabe (das Element ist nur ein Slider mit On und Off):


2020-08-30 00:29:38 MQTT2_CLIENT ThingsBoard v1/devices/me/rpc/request/47:{"method":"setValue","params":false}
2020-08-30 00:29:38 Global global ATTR MQTT2_ThingsBoard readingList ThingsBoard:v1/devices/me/rpc/request/39:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/40:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/41:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/42:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/43:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/44:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/45:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/46:.* { json2nameValue($EVENT) } ThingsBoard:v1/devices/me/rpc/request/47:.* { json2nameValue($EVENT) }
2020-08-30 00:29:38 MQTT2_DEVICE MQTT2_ThingsBoard method: setValue
2020-08-30 00:29:38 MQTT2_DEVICE MQTT2_ThingsBoard params: false



Beta-User

Oha, das scheint eine neue Variante zu sein, wie man Infos via MQTT+JSON verpacken kann...

Interpretiere ich das richtig: Das Bedienen desselben Elements auf dem Gerät/der Hardware (oder was immer das ist) generiert eine fortlaufende Nummer, unter der dann JSON-verpackt gesendet wird, was passiert ist, ohne dass allerdings eine echte Rückverfolgbarkeit gegeben ist, die z.B. darauf schließen läßt, welcher slider (es kann mehrere geben, oder?) betätigt wurde?

Wenn das so ist, ist das insgesamt wenig hilfreich und kaum als input-Methode geeignet (ich würde das als Bug ansehen), nur, wenn es eine Beziehung gibt zwischen der Zahl und dem Slider, sieht es anders aus. Dann können wir mit etwas regex+Perl in readingList durchaus was nettes daraus basteln; (auch als eigener Merker:) spezielle Berücksichtigung von topic-Elementen bei der Reading-Benennung macht z.B. OpenMQTTGateway_BT_scanner, regex zur Auswertung der Payload tasmota_rf u.a..
Aber erst würde ich mal Info benötigen, wie das dann aussieht, wenn andere Bedienelemente ins Spiel kommen. Hast du da irgendwelche Infos? (Ich habe gesehen, dass es da irgendwelche Videos usw. gibt, will mir aber nach Möglichkeit nicht alles selbst zusammensuchen bzw. zusammenreimen. Gibt es irgendwo eine knappe Info, um was es da eigentlich geht?)
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kampi

#11
Zitat von: Beta-User am 30 August 2020, 07:02:09
Oha, das scheint eine neue Variante zu sein, wie man Infos via MQTT+JSON verpacken kann...

Interpretiere ich das richtig: Das Bedienen desselben Elements auf dem Gerät/der Hardware (oder was immer das ist) generiert eine fortlaufende Nummer, unter der dann JSON-verpackt gesendet wird, was passiert ist, ohne dass allerdings eine echte Rückverfolgbarkeit gegeben ist, die z.B. darauf schließen läßt, welcher slider (es kann mehrere geben, oder?) betätigt wurde?

Wenn das so ist, ist das insgesamt wenig hilfreich und kaum als input-Methode geeignet (ich würde das als Bug ansehen), nur, wenn es eine Beziehung gibt zwischen der Zahl und dem Slider, sieht es anders aus. Dann können wir mit etwas regex+Perl in readingList durchaus was nettes daraus basteln; (auch als eigener Merker:) spezielle Berücksichtigung von topic-Elementen bei der Reading-Benennung macht z.B. OpenMQTTGateway_BT_scanner, regex zur Auswertung der Payload tasmota_rf u.a..
Aber erst würde ich mal Info benötigen, wie das dann aussieht, wenn andere Bedienelemente ins Spiel kommen. Hast du da irgendwelche Infos? (Ich habe gesehen, dass es da irgendwelche Videos usw. gibt, will mir aber nach Möglichkeit nicht alles selbst zusammensuchen bzw. zusammenreimen. Gibt es irgendwo eine knappe Info, um was es da eigentlich geht?)

Guter Punkt. Daran habe ich bisher noch nicht gedacht, bzw. noch nicht überlegt. Ich werde das morgen mal den Support fragen, weil irgendwie muss man die Elemente doch voneinander unterscheiden können.
Testweise habe ich mir mal einen Drehschalter und einen On/Off-Schalter rein gezogen und die Nachrichten geloggt:


{"method":"setValue","params":true} <- Wird bei Betätigung des Schalters gesendet
{"method":"getValue"} <- Wird permanent vom Drehschalter gesendet
{"method":"setValue","params":33.33} <- Wird bei Veränderung am Drehschalter gesendet


Alle Nachrichten wurden mit einer anderen Request-ID gesendet.

Ich schreibe morgen früh mal direkt ein entsprechendes Ticket bei Git, weil ich brauche da auch schon eine gute Lösung für, da die Kommunikationsrichtung zwischen FHEM und ThingsBoard schon gerne bidirektional halten möchte. Die Antwort werde ich dann hier posten.

Kleines Edit und bissl Offtopic für die Zwischenzeit (vielleicht hast du da ja eine Anlaufstelle für):
Ich würde gerne im zweiten Schritt (wenn alles läuft) ein eigenes Modul für ein Gerät schreiben um die ganze MQTT-Kommunikation darüber abzuwickeln anstatt ein MQTT2_CLIENT, ein MQTT2_DEVICE und die Events händisch anzulegen, sodass man nur noch die Adresse von der ThingsBoard-Instanz und den API-Key eingeben muss. Gibt es irgendwelche weiterführende Dokumentation, wie ich den MQTT2-Code in meinem eigenen Modul nutzen kann?

rudolfkoenig

ZitatJetzt möchte ich noch auf Bedienelemente im Board reagieren können und dafür muss ich mich auf ein bestimmtes MQTT-Topic subscriben. Gemäß der Doku für einen MQTT2_CLIENT habe ich dies über das "subscriptions"-Attribut gemacht:
MQTT2_CLIENT bestellt per Voreinstellung alle Topics (subscripotions=#). subscriptions setzt man nur dann, wenn man nicht alle Topics bekommen soll.


ZitatGibt es irgendwelche weiterführende Dokumentation, wie ich den MQTT2-Code in meinem eigenen Modul nutzen kann?
Mir nicht bekannt, und der Code in den erwaehnten Modulen ist auch nicht mit dem Gedanken gebaut, als Bibliothek verwendet zu werden. Meiner Ansicht nach laesst sich das Problem mit setzen der richtigen Attribute per attrTemplate fuer den Benutzer bequem loesen.

Beta-User

Zitat von: rudolfkoenig am 30 August 2020, 11:30:44
Meiner Ansicht nach laesst sich das Problem mit setzen der richtigen Attribute per attrTemplate fuer den Benutzer bequem loesen.
Sehe ich ähnlich, wobei mir die MQTT-Kommunikation von diesem Ding noch ziemlich "unausgegoren" vorkommt und ich auch bei der Diskussion in diesem Thread noch nicht erkennen konnte, wo denn der Mehrwert eines eigenen Moduls liegen soll. Mir kam es eher so vor, als wären dir (kampi) Grundlagen der Kommunikation via MQTT und die Funktionsweise der vorhandenen Module noch nicht vertraut und würde daher auch eher empfehlen, erst mal da anzusetzen.
Das Framework, das Rudi da bereitgestellt hat, ist so flexibel, dass wir es eigentlich bisher immer geschafft haben, Lösungen zu basteln, die die betreffenden User (mind.) gut fanden (genauer gesagt: ich kann mich bisher nur an eine Ausnahme erinnern (das BT-Thermostat-Ding), aber da wollte der TE - warum auch immer - nicht weitermachen).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

kampi

Zitat von: Beta-User am 30 August 2020, 14:00:42
Sehe ich ähnlich, wobei mir die MQTT-Kommunikation von diesem Ding noch ziemlich "unausgegoren" vorkommt und ich auch bei der Diskussion in diesem Thread noch nicht erkennen konnte, wo denn der Mehrwert eines eigenen Moduls liegen soll. Mir kam es eher so vor, als wären dir (kampi) Grundlagen der Kommunikation via MQTT und die Funktionsweise der vorhandenen Module noch nicht vertraut und würde daher auch eher empfehlen, erst mal da anzusetzen.
Das Framework, das Rudi da bereitgestellt hat, ist so flexibel, dass wir es eigentlich bisher immer geschafft haben, Lösungen zu basteln, die die betreffenden User (mind.) gut fanden (genauer gesagt: ich kann mich bisher nur an eine Ausnahme erinnern (das BT-Thermostat-Ding), aber da wollte der TE - warum auch immer - nicht weitermachen).

Gut dann schiebe ich die Idee erst einmal beiseite. Die Grundidee war eigentlich auch nur das ganze sauber zu unterteilen, aber wenn es nicht notwendig ist, bzw. am Ende mehr Arbeit macht als eine ordentliche Parametrierung durch die Attribute vorzunehmen kann ich auch drauf verzichten. Es war (wenn überhaupt) eh eine Idee für später :)

Anyway ich habe mal ein Ticket bei Git erstellt (keine Lust gehabt zu warten und vielleicht schauen die zuständigen Leute ja heute noch rein...) und mal gefragt ob es eine Möglichkeit gibt die Dinger über MQTT zu identifizieren. Leider scheint auch die HTTP-Implementierung keine vernünftige Identifizierung mitzubringen (bzw. es ist nichts dokumentiert).