MQTT2_CLIENT => MQTT2_BRIDGE => MQTT2_DEVICE (Verständnisfrage)

Begonnen von JudgeDredd, 16 Februar 2022, 14:49:59

Vorheriges Thema - Nächstes Thema

JudgeDredd

Hi Beta-User,
Zitat von: Beta-User am 16 Februar 2022, 19:05:42Falls du bereit bist, den Hauptteil der Arbeit für alle zu machen, liefere ich dir die Bausteine, mit denen du das zusammenpuzzeln kannst...?
Also gerne bin ich bereit im Rahmen meiner Möglichkeiten mitzuwirken. Auf keinen Fall möchte ich, das Andere für meine Sonderlocken die Arbeit machen.

Ich habe Dein Templatevorschlag mal ausprobiert.
3 kleine Syntaxfehler habe ich korrigiert.

Hochkomma hinter Readingsname bei AttrVal '
par:DEV_TPC;base topic to be used for devicetopic attribute;{ my $is = AttrVal('DEVICE','devicetopic',undef); return $is if $is; AttrVal('DEVICE','readingList','') =~ m,(?:[^:]*:)?(shellies.*/[^/]*)/online, ? $1 : undef }

Hochkomma beim default AttrVal-Wert '
Abschließende Klammen }
par:DEVNAME;Shelly1 name in the topic;{ par:DEV_TPC;Shelly name in the topic;{ AttrVal('DEVICE','devicetopic',undef) =~ m,shellies.*/(shelly[^/]+)?, ? $1 : AttrVal('DEVICE','readingList','') =~ m,shellies/([^/]+)/online, ? $1 : undef } }


Nach der Korrektur habe ich dann:
# shelly1 using original firmware.
name:shelly1_customTopic
filter:TYPE=MQTT2_DEVICE
desc:Base template for a lot of first generation shelly devices
par:DEV_TPC;base topic to be used for devicetopic attribute;{ my $is = AttrVal('DEVICE','devicetopic',undef); return $is if $is; AttrVal('DEVICE','readingList','') =~ m,(?:[^:]*:)?(shellies.*/[^/]*)/online, ? $1 : undef }
par:DEVNAME;Shelly1 name in the topic;{ par:DEV_TPC;Shelly name in the topic;{ AttrVal('DEVICE','devicetopic',undef) =~ m,shellies.*/(shelly[^/]+)?, ? $1 : AttrVal('DEVICE','readingList','') =~ m,shellies/([^/]+)/online, ? $1 : undef } }
par:CALLSPEECHRECOGN;Set this to 0 to not set any speech recogn. related attributes;{ 1 }
order:A_10
attr DEVICE devicetopic DEV_TPC
attr DEVICE setList\
  off:noArg $\DEVICETOPIC/relay/0/command off\
  on:noArg $\DEVICETOPIC/relay/0/command on\
  x_update:noArg $\DEVICETOPIC/command update_fw\
  x_mqttcom $\DEVICETOPIC/command $EVTPART1
attr DEVICE readingList \
  $\DEVICETOPIC/relay/0:.* state\
  $\DEVICETOPIC/relay/0:.* relay0\
  $\DEVICETOPIC/input/0:.* input0\
  $\DEVICETOPIC/online:.* online\
  $\DEVICETOPIC/announce:.* { json2nameValue($EVENT) }\
  shellies/announce:.* { $EVENT =~ m,..id...DEVNAME...mac.*, ? json2nameValue($EVENT) : return }
attr DEVICE devStateIcon {my $onl = ReadingsVal($name,"online","false") eq "false" ? "rot" : ReadingsVal($name,"new_fw","false") eq "true" ? "gelb" : "gruen"; my $light = ReadingsVal($name,"state","off"); my $show = '<a href="';$show .= $onl eq "gelb" ? "/fhem?cmd.dummy=set $name x_update&XHR=1\">" : "http://".ReadingsVal($name,"ip","none").' "target="_blank">'; $show .= FW_makeImage("10px-kreis-".$onl)."</a>"; "<div> $show <a href=\"/fhem?cmd.dummy=set $name toggle&XHR=1\">".FW_makeImage($light)."</a></div>" }
deletereading -q DEVICE (?!associatedWith|IODev).*
set DEVICE x_mqttcom announce
attr DEVICE model shelly1
setreading DEVICE attrTemplateVersion 20220216
option:{ CALLSPEECHRECOGN }
set DEVICE attrTemplate speechcontrol_type_switch


Wenn ich das Template anwende, bekomme ich aber noch immer den Fehler:
for param DEVNAME: Can't locate object method "in" via package "the" (perhaps you forgot to load "the"?)
Hier komme ich aber gerade nicht weiter.
Sieht jemand den Fehler ?

Gruß,
JudgeDredd
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

Die hier sieht komisch aus:
par:DEVNAME;Shelly1 name in the topic;{ par:DEV_TPC;Shelly name in the topic;{ AttrVal('DEVICE','devicetopic',undef) =~ m,shellies.*/(shelly[^/]+)?, ? $1 : AttrVal('DEVICE','readingList','') =~ m,shellies/([^/]+)/online, ? $1 : undef } }
Vermutlich sollte es so gehen:
par:DEVNAME;Shelly1 name in the topic;{ AttrVal('DEVICE','devicetopic',undef) =~ m,shellies.*/(shelly[^/]+)?, ? $1 : AttrVal('DEVICE','readingList','') =~ m,shellies/([^/]+)/online, ? $1 : undef }
(War wohl etwas müde gestern)
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

eisman

Zitat von: Beta-User am 16 Februar 2022, 19:56:50
...das ist aber doch ein Ersatzweg für die Verwendung von MQTT_GENERIC_BRIDGE und hat mit dem (im Threadtitel nur unzureichend widergegebenen) eigentlichen Anliegen des TE doch wenig zu tun, oder...?

S
ist bei mir ohne MQTT_GENERIC_BRIDGE....

ja, hast recht, MQTT2_CLIENT => MQTT2_BRIDGE => MQTT2_DEVICE (Verständnisfrage) past nicht da zu....

danke für die INFO
1x FHEM Debian, Homematic,ZigBee,FS20 / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian, Homematic,ZigBee         / 1X Raspberry, ConBee / 5x ESP
1x FHEM Debian,MQTT                               / 1X Raspberry, i2c,onewire,gpio
1x auf Windows 2012 Hyper-V-S

Beta-User

Zitat von: eisman am 17 Februar 2022, 15:10:36
ist bei mir ohne MQTT_GENERIC_BRIDGE....
Das habe ich gesehen, und auch, dass deine Lösung einen kleinen "Pferdefuß" hat: gibt es keine Aktualisierungen bei anderen Devices, wird trotzdem von allen der jeweils letzte Wert versendet, gibt es keine Aktualisierung des "trigger-Readings", wird gar nichts mehr gepublisht...

Ist zwar OT, aber hier mal ein Beispiel für ein Device, das zum einen Informationen via MQTT (generisch) erhält, die Daten dann aber zum Teil direkt (bei triggerndem Empfang) über MQTT_GENERIC_BRIDGE weitersendet unter anderem Namen bzw. anderer Struktur (an einen anderen Server); verantwortlich dafür ist das Attribut "mqttGB1Publish":
define Raumfuehler_Wohnzimmer MQTT2_DEVICE A4C138CC86D1
attr Raumfuehler_Wohnzimmer alias Raumfühler
attr Raumfuehler_Wohnzimmer event-min-interval 300
attr Raumfuehler_Wohnzimmer event-on-change-reading batteryPercent,temperature:0.2,humidity:0.2,rssi:5,distance:5
attr Raumfuehler_Wohnzimmer genericDeviceType thermometer
attr Raumfuehler_Wohnzimmer group Heizung
attr Raumfuehler_Wohnzimmer icon temperature_humidity
attr Raumfuehler_Wohnzimmer jsonMap batt:batteryPercent tempc:temperature tempf:0 hum:humidity servicedatauuid:0 servicedata:0
attr Raumfuehler_Wohnzimmer model OpenMQTTGateway_BT_temp_hum_sensor
attr Raumfuehler_Wohnzimmer mqttGB1Publish temperature|humidity:topic={"$base/$device/$name"}
attr Raumfuehler_Wohnzimmer readingList home/O[^/]*M[^/]*G[^/]*/BTtoMQTT/A4C138CC86D1:.* { json2nameValue($EVENT,'',$JSONMAP) }
attr Raumfuehler_Wohnzimmer readingsWatcher 4000,0.000,temperature,humidity
attr Raumfuehler_Wohnzimmer rhasspyName raumfühler
attr Raumfuehler_Wohnzimmer room Wohnzimmer
attr Raumfuehler_Wohnzimmer stateFormat T: temperature°C, H: humidity%rH

Mit sowas kann man
- Displays füttern;
- externe Visualisierungen anbinden (HomeAssistant, z.B.);
- ein zentrales oder entferntes FHEM mit Infos versorgen (auch mit einer gewissen Toleranz gegen Verbindungsabbrüche, als Alternative z.B. zu FHEM2FHEM);
- ...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

JudgeDredd

ok, ich habe die geänderte Zeile par:DEVNAME... übernommen.
Allerdings hat nun der Devicename im Topic gefehlt.
Das habe ich im Template nochmal angepasst.
name:shelly1_customTopic
filter:TYPE=MQTT2_DEVICE
desc:Base template for a lot of first generation shelly devices
par:DEV_TPC;base topic to be used for devicetopic attribute;{ my $is = AttrVal('DEVICE','devicetopic',undef); return $is if $is; AttrVal('DEVICE','readingList','') =~ m,(?:[^:]*:)?(shellies.*/[^/]*)/online, ? $1 : undef }
par:DEVNAME;Shelly1 name in the topic;{ AttrVal('DEVICE','devicetopic',undef) =~ m,shellies.*/(shelly[^/]+)?, ? $1 : AttrVal('DEVICE','readingList','') =~ m,shellies/([^/]+)/online, ? $1 : undef }
par:CALLSPEECHRECOGN;Set this to 0 to not set any speech recogn. related attributes;{ 1 }
order:A_10
attr DEVICE devicetopic DEV_TPC
attr DEVICE setList\
  off:noArg $\DEVICETOPIC/DEVNAME/relay/0/command off\
  on:noArg $\DEVICETOPIC/DEVNAME/relay/0/command on\
  x_update:noArg $\DEVICETOPIC/DEVNAME/command update_fw\
  x_mqttcom $\DEVICETOPIC/DEVNAME/command $EVTPART1
attr DEVICE readingList \
  $\DEVICETOPIC/DEVNAME/relay/0:.* state\
  $\DEVICETOPIC/DEVNAME/relay/0:.* relay0\
  $\DEVICETOPIC/DEVNAME/input/0:.* input0\
  $\DEVICETOPIC/DEVNAME/online:.* online\
  $\DEVICETOPIC/DEVNAME/announce:.* { json2nameValue($EVENT) }\
  shellies/announce:.* { $EVENT =~ m,..id...DEVNAME...mac.*, ? json2nameValue($EVENT) : return }
attr DEVICE devStateIcon {my $onl = ReadingsVal($name,"online","false") eq "false" ? "rot" : ReadingsVal($name,"new_fw","false") eq "true" ? "gelb" : "gruen"; my $light = ReadingsVal($name,"state","off"); my $show = '<a href="';$show .=
deletereading -q DEVICE (?!associatedWith|IODev).*
set DEVICE x_mqttcom announce
attr DEVICE model shelly1
setreading DEVICE attrTemplateVersion 20220216
option:{ CALLSPEECHRECOGN }
set DEVICE attrTemplate speechcontrol_type_switch

Die Neuanlage funktioniert nun und der Shelly kann auch geschaltet werden.

Soweit sogut ... Jetzt kommt aber wieder mein Verständninsproblem.

Der Ablauf:

  • Ich lege ein Device MQTT2_CLIENT an.
    subscriptions shellies/licht/+/#
    autocreate simple/complex
  • Nach ein paar Sekunden wird genau ein MQTT2_DEVICE angelegt.
    Name: mqttIO_Licht
    Im Attribut readingsList stehen nun sämtliche Shellies die das Topic matchen
  • Setzte ich das Attribut
    devicetopic shellies/licht/1g
  • wende ich das Template an
    Shelly1 name in the topic:  shelly1-ABCDEF123456
  • Nun kann ich den Shelly schalten.

Aber was nun ?
Das automatisch erzeugte Device
- heißt weiterhin mqttIO_Licht
- in readingsList stehen weiterhin alle gematchten Shellies drin.
- ein weiteres Dervice wird nicht automatisch erzeugt.

Ist das alles so korrekt wiedergegeben, oder sollte an irgendeiner Stelle etwas anderes passieren ?

Gruß,
JudgeDredd
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

#20
Vielleicht nochmal ein bißchen Theorie:

- Ein MQTT2-IO gibt die Daten mit einer "CID" (ClientID) via "Dispatch" an das Modul MQTT2_DEVICE weiter. Das muss dann entscheiden, ob es
-- "jemanden kennt", der mit den Daten was anfangen kann. Das ist zu bejahen, wenn es (mindestens) eine MQTT2_DEVICE-Instanz gibt, deren readingList einen passenden Eintrag hat;
-- "autocreate" anwerfen soll (ein flag, wird am IO gesetzt), wenn das nicht der Fall ist;
-- wenn "autocreate" stattfinden soll: Welches Device bekommt die Daten? Das wird anhand der CID entschieden.

Daraus folgt:
- MQTT2_SERVER kennt den Sender und kann anhand von dessen ClientID die Daten passend verteilen;
- MQTT2_CLIENT kennt den Sender nicht (das liefert z.B. Mosquitto gar nicht mit) und versieht daher alle Pakete mit seiner eigenen CID => alles landet in ein und demselben Device...

Daraus folgt weiter:
- wenn du ein neues Device machst, nimmst du eine Kopie von deinem "Sammeldevice", machst alle Infos raus bis auf das, was attrTemplate braucht, entfernst insbesondere auch die CID aus der DEF und legst damit den "kleinen Klon" an => attrTemplate anwenden, alles ist gut...

ODER:
- du baust eine passende bridgeRegexp ;) . Das ermittelt "Pseudo-CID's", die dann im weiteren autocreate-Prozess verwendet werden.
Es gibt dafür ein Muster, das einen "normalen Shelly" direkt "vereinzeln" würde, zu finden im attrTemplate "MQTT2_CLIENT_general_bridge".
Da machst du einfach eine weitere Zeile rein, die deinen Fall umfasst. Mit den Infos aus der par:-Ermittlung zu DEVNAME sollte das hinzubekommen sein :P .
(Im Prinzip kannst du das frei gestalten, ich würde aber empfehlen, das so zu machen, dass die "Pseudo-CID" genau dem entspricht, was MQTT2_SERVER "sehen" würde, und das ist (hier und nur) das, was als DEVNAME ermittelt wird).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

JudgeDredd

Zitat von: Beta-User am 17 Februar 2022, 15:58:35
ODER:
- du baust eine passende bridgeRegexp ;) . Das ermittelt "Pseudo-CID's", die dann im weiteren autocreate-Prozess verwendet werden.
Die bridgeRegexp als "Vereinzelner" Funktioniert. bei meinem Beispiel.
(shellies/licht/1g/shelly1-ABCDEF123456)

Problematisch wird es nur mit dynamischen Topics alles in einem Regex abzubilden.
z.B. (shellies/sensor/eg/temperatur/shelly1-ABCDEF123456)

Da muss ich mir erst nochmal Gedanken zu machen.
Danke mal bis hierhin für ein wenig Aufklärungsunterricht ;)

Gruß,
JudgeDredd
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

 :)

Ist schon klar, dass es reichlich schwierig ist, das alles "auf einmal" zu überblicken, was es alles gibt und für was jeweils welches Attribut usw. gedacht ist und wie was ineinandergreift. Die meisten kennen auch nur das Ergebnis und haben wenig Ahnung davon, wie was zusammenhängt, von daher bin ich eigentlich ganz froh, wenn hin und wieder mal jemand "vorbeikommt", der etwas speziellere Anforderungen realisieren will (daher auch der OT-Exkurs zu MQTT_GENERIC_BRIDGE).

Kleines Helferlein noch:
https://regex101.com/r/LKnABh/1
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files