[geklärt] MQTT_GENERIC_BRIDGE per subscription nutzen, um slave-Geräte...

Begonnen von Beta-User, 05 Januar 2019, 11:45:04

Vorheriges Thema - Nächstes Thema

Beta-User

Zitat von: hexenmeister am 07 Januar 2019, 21:55:52
Machbar ist das natürlich trotzdem, wenn Du das machen willst, kann ich dich (in Rahmen meiner Fähigkeiten) unterstützen.
Zitat von: hexenmeister am 07 Januar 2019, 21:52:22
Angesichts der Tatsache, dass es (ganz gut) funktioniert, war mir der Aufwand, dies im MQTT zu ändern, zu hoch. :o
Wenn nicht mittelfristig irgendwelche Probleme zu erwarten sind (außer dem Umstand, dass Rudi der Code offensichtlich nicht behagt), sehe ich im Moment auch keine Veranlassung, da (ggf. abgesehen vom im anderen Thread angerissenen setExtensions-Thema) nachzubessern; Danke trotzdem für das Angebot!
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

hexenmeister

setExtensions haben mit dem dispatch-Mechanismus nichts zu tun. Die bekommen wir ggf. unabhängig von der Umstellung hin.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Beta-User

Thx.
Im Moment sind es bei MySensors zwei Baustellen:
a) zum einen funktioniert die "Rückwärtssuche für das Chanenl76-IO" in MYSENSORS (noch) nicht.
b) das mit setExtensions.

Da Rudi die Art und Weise in GPUtils für die Client-Suche nicht zu gefallen scheint, würde mich zum Punkt a) interessieren, wie das am "FHEM-konformsten" zu lösen wäre? Vermutung: Besser devspec2Array nutzen statt den GPUtils-Code verändert in MYSENSORS einzubauen?

Zu b) (und ggf., sofern erforderlich auch zu a)) würde ich vorschlagen, das nicht hier weiter zu diskutieren, sondern in (je) einem eigenen Thread im MySensors-Bereich?
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

rudolfkoenig

Zitata) zum einen funktioniert die "Rückwärtssuche für das Chanenl76-IO" in MYSENSORS (noch) nicht.
Ich weiss nicht genau, was du meinst, ich Rate :)
Wenn ein Modul ein device-id nach Geraet-Mapping haben will, dann kann er das mit
$modules{<MyModeleName>}{defptr}{device-id} = $defs{deviceName}
machen, da dieser defptr auch bei rereadcfg gerettet wird.

Zitatb) das mit setExtensions.
Wenn das Modul in SetFn feststellt, dass es mit dem Befehl nichts anfangen kann, dann wird nicht das Usage zurueckgeliefert (Unknown argument XX, choose one of $list")  sondern SetExtensions($hash, $list, @a), wobei $hash das "eigene" $defs-Eintrag ist (erstes Parameter zu SetFn), $list die Leerzeichen separierte Liste der moeglichen Befehle, und @a Parameter 2...X zu SetFn.

Beta-User

Sorry Leute,

für sowas (und zwar je einzeln) benötige ich leider immer eine gefühlte Ewigkeit, um es zu verstehen.
zu a) weiß ich noch nicht so recht, ob man sowas braucht wie von Rudi vorgeschlagen. Der Ablauf, um den es konkret geht, ist der:

Normalerweise kommen MySensors-Nachrichten _von_ einer Node immer über dasselbe GW rein, über das auch später wieder gesendet werden soll. Dabei ist in einer Message immer eine ID enthalten (0-255), die entweder eindeutig ist (0-254) oder eine Anfrage zur Vergabe einer Nummer (255). Der vorhandene Code für das IO (00_MYSENSORS.pm) sucht jetzt also das (10_MYSENSORS_DEVICE-) Client-Device, dessen Konfigurationsdaten _den eigenen Namen als IO_ und die ID enthält und reicht die Message dann an das betreffende Client-Device weiter, das dann selber entscheidet, was damit passieren soll (bzw. erstellt bei aktivem autocreate ein neues, wenn noch nicht vorhanden).

Klappt super, nur eben dann nicht, wenn man eigentlich einen anderen Kanal nutzt, jetzt aber der Bootloader (der auf OTA-Daten wartet) den Kanal verstellt - dann kommen die Messages _über ein anderes IO_ rein und dieses Matching klappt nicht, da ja der Name des IO's nicht paßt. Im Ergebnis wird die message dann verworfen (statt über das "spezielle" IO eine Antwort zu senden).

Es muß also (im speziellen Fall bestimmter Nachrichtentypen) ein elsif-Zweig her, der prüft, ob es "zufällig" ein Device gibt, das (per Attribut) als "OTA_Chan76_IODev" den aktuellen IO-Namen festgelegt hat und dann die Nachricht an dieses weitergibt (das Client-Device sollte dann die Antwort auch bereits über das richtige IO auf Kanal 76 antworten). Da das ein absoluter Spezialfall ist, ist vermutlich eine Abfrage mit devspec2Array die simpelste Lösung.

zu b) So wie ich das verstehe, ist der setExtensions-Aufruf immer der letzte in so einer Kette.
Das "Problem" ist, dass man das an den genannten Stellen irgendwie harmonisieren muß mit einem GPUtils-Aufruf, der sich ebenfalls für den letzten in der Kette hält und mit "return ..." beginnt, was dann wohl nicht so bleiben kann.
Vermutlich müßte ich den dortigen Rückgabewert in eine Variable ("my $GPUtilsReturnvalue = ") packen und dann mal sehen, ob ich das anschließend zuletzt in den setExtensions Aufruf irgendwie reinwurstle?
(Teste ich demnächst mal :) , aber erst kommt a)).
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

hexenmeister

Zu a)
Du kannst hier (vermuttlich) den 'normalen' Dispatch-Mechanismus gar nicht normal verwende, aber das Modul tut das eh nicht. Du kannst aber auch nicht dafür die GP_ForallClients nehmen, da diese IODev-Name prüft. Du ´brauchst eine ähnliche eigene Methode, die über alle bekannten Module(Instanzen) durchgeht, den Typ des Moduls und ein bestimmtes spezielles IODev-Attribut vergleicht. Dann eine speziel dafür zu erstellende Methode im Client aurufen. Irgendwie so.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Zu b)
Auf den ersten Blick sieht es richtig aus. Der Aufrug GP_Catch sollte gar nicht aufgerufen werden, wenn 'on-for-timer' gerufen wird, das dies nicht in 'sets' enthalten ist (sein darf). Man muss Debug-Ausgaben einbauen und testen, was da wirklich passiert.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

LudgerR

Habe ich das richtig verstanden?

Wenn man innerhalb von Fhem, d.h. via MQTT mittels publish und subscribe  zwischen verschiedenen devices (innerhalb von Fhem) Bedingungen prüfen und Aktionen triggern will kann man dies (zur Zeit ?) nicht   mit MTTQ2 Server realisieren und muss auf einen externen Broker (z.B. mosquitto ) ausweichen?
Ich bin auf diesen Thread gestoßen, weil ich das Verhalten der MQTT2 Bridge im Zusammenspiel mit MQTT2 Server trotz Einschaltung aller Debug Optionen nicht erklären konnte.
In meinen konkreten Fall steuere ich meine Sony TV (modul BRAVIA) und den SonosPlayer im Wohnzimmer mittels einer MQTT dashboard App.  Das Publishing des ,,on" states vom (Sony) BRAVIA device ans MQTT Frontend wollte ich dazu nutzen um im SonosPlayer device  per set-topic den Player auf ,,Pause" zu setzen.
Um nicht ein zusätzliches notify  zu bemühen und um die Logik am device selbst zu binden habe ich für mich  als ,,dirty workaround" folgende Lösung gefunden:


define Sony BRAVIA 192.168.69.209 10
      :
  :
attr Sony mqttDefaults base={"SH/EG/E3/MEDIA/$device/$reading"} pub:qos=0 sub:qos=2 retain=1
attr Sony mqttPublish *:topic={"$base"}\
       state:topic={"$base"} state:expression={fhem("set Sonos_Wohnzimmer pause") if $value eq on";;$value=$value}
attr Sony mqttSubscribe channel:set-topic={"SH/EG/E3/MEDIA/Sony/channel/cmd"}\
                          volume:set-topic={"SH/EG/E3/MEDIA/Sony/volume/cmd"}\
                          mute:set-topic={"SH/EG/E3/MEDIA/Sony/mute/cmd"}\
                          state:set-topic={"SH/EG/E3/MEDIA/Sony/state/cmd"}


Ich mißbrauche die expression im mqttPublish um ein fhem set on den SONOSPLAYER abzusetzen.

Auf die Dauer betrachte ich diese fehlende Funktionalität von MQTT2 Bridge im Zusammenspiel mit MQTT2 Server jedoch als ein Manko.

Fhem/mosquitto/zigbee2mqtt  on PI 3+ , 2xCUNO, 13xFHT, EM1000 WZ/GZ, FS20,AMAD,SONOS, MQTT (Sonoff/Shelly),Buderus GB-112,CanOverEthernet(UVR67/CIM)

Beta-User

M.E. sind da ein paar Unsauberkeiten drin:
"Eigentlich" ist es nur so, dass man nicht gleichzeitig mit einem MQTT2-Interface aus demselben topic ein MQTT2_DEVICE und ein MQTT_GENERIC_BRIDGE beliefern kann.

Ob das bei dir der Fall ist? (Gibt es ein (per autocreate erstelltes) MQTT2_DEVICE, in dem die für den SonosPlayer gedachten Befehle gelandet sind?)

Daneben: MQTT_GENERIC_BRIDGE gibt es nur in der "V1+", das ist aber (bei ausgeschaltetem autocreate!) kompatibel mit allen verfügbaren MQTT-IO-Modulen, aber eben nur für unterschiedliche subscriptions.

Ob der MQTT2_SERVER überhaupt "interne" Messages so verteilt, kann ich nicht sagen, das ergab sich aus meinen Tests nicht eindeutig; aber eventuell ist es auch bei mosquitto so, dass ein Client, der was reinsendet dasselbe nicht gleichzeitig als subscription wieder bekommt (sowas ist m.E. sehr gefährlich: man baut damit schnell mal eine unbeabsichtigte Schleife).

Weiter könnte es sein, dass die ursprüngliche Konfiguration nicht ging, weil in der GenericBridge auch eine Funktion drin ist, um solche Schleifen zu vermeiden (da gab es neulich einen Beitrag im GenericBridge-Thread, bei dem es um sowas ähnliches ging, wenn ich das richtig interpretiert habe); also selbst wenn der jeweilige Broker das mitmacht.

An sich ist der Fall bei dir auch anders: Es geht nicht eigentlich um die "doppelte" subscription unter dasselbe topic, sondern eine logische Reaktion, oder? Sowas ist eigentlich wirklich klassisches Event-Handling, da finde ich es ok, wenn es nicht funktioniert (mittelfristig sollte es da ggf. sowas wie do's and don'ts rund um MQTT+FHEM geben).

Viele Fragen, aber ob man deswegen schon die Flinte ins Korn werfen darf?

(Der Ansatz, die Reaktion in die expression zu schreiben ist aber interessant, behalte ich im Hinterkopf ;) ).
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

LudgerR

Zitat
Ob das bei dir der Fall ist? (Gibt es ein (per autocreate erstelltes) MQTT2_DEVICE, in dem die für den SonosPlayer gedachten Befehle gelandet sind?)

Nein,  außerdem wenn ich mit (mosquitto_sub)  das topic von extern publishe wird am SonosPlayer der set-topc Befehl wie erwartet erkannt und ausgeführt.

Zitat
Ob der MQTT2_SERVER überhaupt "interne" Messages so verteilt, kann ich nicht sagen, das ergab sich aus meinen Tests nicht eindeutig; aber eventuell ist es auch bei mosquitto so, dass ein Client, der was reinsendet dasselbe nicht gleichzeitig als subscription wieder bekommt (sowas ist m.E. sehr gefährlich: man baut damit schnell mal eine unbeabsichtigte Schleife).

Das mit der "infinite loop" ist mir schon bewußt.  Dennoch würde mich interessieren ob bei mosquitto eine deratige Restriktion ebenfalls vorhanden ist. Da ich dabei bin als Frontend  dasboards auf MQTT Basis  einzusetzten und die interne Kommunikation in erster Linie über MQTT erfolgt, präferiere ich Lösungen/ Steuerungen auf MQTT Basis.

Selbstverständlich kann man mit notify und DOIF sehr gute / komplexe Ereignissteuerung machen. Für die einfachen Dinge bevorzuge ich jedoch Lösungen, die man in der Device Konfiguration direkt ablesen kann. (Siehe mein Beispiel Sony-TV und SonosPlayer).

Zitat
(Der Ansatz, die Reaktion in die expression zu schreiben ist aber interessant, behalte ich im Hinterkopf ;) ).

Genau deshalb habe ich dies public gemacht.

Wegen meiner Ausrichtung auf MQTT Frontends, wird die Mehrzahl meiner Devices eh von der MQTT2 GenericBridge überwacht.
Damit könnte ich mit dem expression Konstrukt jegliches "Reading-Event" des Devices in solch einer  expression behandeln und auf ein separates notify bzw. DOIF in vielen Fällen verzichten.
Da ich durch ein Finales setzen auf undef letzendlich eine Publikation verhindern kann,steht dem "Mißbrauch" nichts mehr im Wege.

Das gleiche gilt in ähnlicher Form auch für mqttSubscribe.
Fhem/mosquitto/zigbee2mqtt  on PI 3+ , 2xCUNO, 13xFHT, EM1000 WZ/GZ, FS20,AMAD,SONOS, MQTT (Sonoff/Shelly),Buderus GB-112,CanOverEthernet(UVR67/CIM)

Beta-User

Hm,

also irgendwie stehe ich entweder immer noch auf dem Schlauch oder die Lösung hat doch einen Haken (was ich glaube, siehe nachfolgendes).

Was die Bridge macht (btw: was soll nochmal eine MQTT2 Bridge sein?), ist bei stopics _das Zielgerät_ zu schalten, also das, bei dem das Attribut auch steht. Gedacht ist das mit den stopics m.E. nie für ein ganz anderes Zielgerät. Wenn man das will, müßte man nach meinem Verständnis dort (!) eine eigene set-subscription haben und dieselbe Info dort dann ggf. gesondert auswerten.

Hier hast/hättest du das weitere Problem, dass es dann einen Unterschied macht, wenn du das von der MQTT-Seite über die App schaltest oder innerhalb FHEM (Erwartung: dieselbe Reaktion; Ergebnis: abweichend, da nicht über MQTT ausgelöst).

Und ob es übersichtlicher ist, das in ein eigenes 3. Device (notify etc) zu schreiben, oder direkt innerhalb des Zieldevice (Sonos_Wohnzimmer)abzubilden sei dahingestellt, aber diese Lösung, Teile der dieses Device betreffenden Logik innerhalb eines ganz anderen Devices (Sony) abzubilden, ist m.E. nicht wirklich dauerhaft transparent. In einem notify sieht man wenigstens noch die beteiligten Devices vice versa...

Just my2ct.
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

LudgerR


Zitat
Was die Bridge macht (btw: was soll nochmal eine MQTT2 Bridge sein?), ist bei stopics _das Zielgerät_ zu schalten, also das, bei dem das Attribut auch steht. Gedacht ist das mit den stopics m.E. nie für ein ganz anderes Zielgerät. Wenn man das will, müßte man nach meinem Verständnis dort (!) eine eigene set-subscription haben und dieselbe Info dort dann ggf. gesondert auswerten.

Bei der MQTT Bridge meine ich natürlich "MQTT_GENERIC_BRIDGE". 

Selbstverständlich habe ich das set-topic  am Zielgerät dem SONOSPLAYER device definiert. (Die Definition hätte ich möglicher  mitliefern müssen).
Nur weil es am Destination-Device per mqttSubscribe widererwarten nicht funktioniert, habe ich dies am Quell-Device mit fhem("set ......") im expression erfolgreich eingebaut.

Inzwischen hatte ich  set-topic auf topic geändert, um das unterschiedliche Verhalten beim in- und externen publishing zu dokumentieren.


defmod Sonos_Wohnzimmer SONOSPLAYER RINCON_949F3E1410FC01400_MR
        :
attr Sonos_Wohnzimmer mqttSubscribe Sony:topic={"SH/EG/E3/MEDIA/Sony/state"}
        :


Das Reading "Sony" im device Sonos_Wohnzimmer wird beim publishing durch mqttPublish in Sony  nicht upgedated.

Nutze ich jedoch mosquitto_pub   und schneide mittels mosquitto_sub mit, so erhalte ich in beiden Fällen das identische Protokoll.  Der wesentliche Unterschied ist jedoch, dass diesmal das Reading "Sony" im device Sonos_Wohnzimmer (SONOSPLAYER)  upgedated wird. 

Es ist somit das Zusammenspiel von "MQTT2_Server" mit "MQTT_GENERIC_BRIDGE", das dieses inkonsistente Verhalten an den Tag legt.

Für mich stellt sich die Frage ob in der Kombination

        MQTT_GENERIC_BRIDGE <---> MQTT2_Client <---> Externer Broker

dieses inkonsistente Verhalten verschwindet.
 


Fhem/mosquitto/zigbee2mqtt  on PI 3+ , 2xCUNO, 13xFHT, EM1000 WZ/GZ, FS20,AMAD,SONOS, MQTT (Sonoff/Shelly),Buderus GB-112,CanOverEthernet(UVR67/CIM)

Beta-User

Vorab mal Danke für die Erläuterungen, wie das ursprünglich war, dann sind wir uns scheinbar einig, wie das - von der Empfangsseite her gedacht - "sauber" aussehen sollte...
Zitat von: LudgerR am 18 Januar 2019, 16:31:13
Für mich stellt sich die Frage ob in der Kombination

        MQTT_GENERIC_BRIDGE <---> MQTT2_Client <---> Externer Broker

dieses inkonsistente Verhalten verschwindet.
Ich weiß nicht, ob die Bezeichnung "inkonsitstent" paßt: Nach dem Verständnis, das ich bis dato entwickelt habe, hat eben jedes in MQTT teilnehmende "Gerät" eine Kennung, die eindeutig sein sollte (CID). Aus Sicht des MQTT-Verkehrs sind alle FHEM-internen Devices, (also alles, was "eigentlich" nicht nativ MQTT spricht und von außen kommt) vermutlich "ein" Gerät in diesem Sinne, weil sie alle die CID des MQTT2-Servers haben. Für interne Zwecke auf einem (also innerhalb eines) Device ist das ganze Protokoll eigentlich nicht gemacht, es ging bei der Entwicklung ja gerade drum, leichtgewichtig zu sein... Dass die Nachrichten daher nicht auf diesem Weg FHEM-MQTT2-intern weiter verteilt werden, leuchtet mir ein, und zu mosquitto hatte ich das hier schon ausgeführt:
Zitat von: Beta-User am 18 Januar 2019, 12:21:18[...] aber eventuell ist es auch bei mosquitto so, dass ein Client, der was reinsendet dasselbe nicht gleichzeitig als subscription wieder bekommt (sowas ist m.E. sehr gefährlich: man baut damit schnell mal eine unbeabsichtigte Schleife).
Käme also auf einen Test an, ob mosquitto das anders macht undzurückdispatcht... Wenn ja, wäre das ggf. wirklich ein Argument für mosquitto (wenn man unbedingt auf Event-Handler verzichten will, was ich - trotz meiner Tendenz, möglichst Geräte einzusparen - immer noch für in diesem Fall angemessener halte).

Aber mal schauen, was ggf. deine Tests bringen und die wirklichen Experten dazu meinen...
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

LudgerR

Moin,

In der Kombination

     MQTT_GENERIC_BRIDGE <---> MQTT2_CLIENT <---> Externer Broker

funktioniert das Publish and Subscribing genau so, wie ich MQTT verstanden habe.

Die augenblicklichen Stand der Implementierung mittels
 
   MQTT_GENERIC_BRIDGE <---> MQTT2_SERVER

ist wegen dem fehlenden dispatch der outbound message auch in inbound Richtung (bei enstsprechender Subskription) jedoch noch inkonsistent.


Zu deinem Hinweis
   
Zitat
Ob der MQTT2_SERVER überhaupt "interne" Messages so verteilt, kann ich nicht sagen, das ergab sich aus meinen Tests nicht eindeutig; aber eventuell ist es auch bei mosquitto so, dass ein Client, der was reinsendet dasselbe nicht gleichzeitig als subscription wieder bekommt (sowas ist m.E. sehr gefährlich: man baut damit schnell mal eine unbeabsichtigte Schleife).

möchte ich nur anmerken, dass das Empfangen eines Topics und anschließendem Dispatchen des Topics an den selben Client nichts Ungewöhnliches ist.  Sowohl  MQTT2_SERVER als auch mosquitto unterstützt meinen Tests nach diese Funktionalität. 

Nur halt in der Kombination

  MQTT_GENERIC_BRIDGE <---> MQTT2_SERVER

fehlt (noch ?) diese Funktionalität.

Fhem/mosquitto/zigbee2mqtt  on PI 3+ , 2xCUNO, 13xFHT, EM1000 WZ/GZ, FS20,AMAD,SONOS, MQTT (Sonoff/Shelly),Buderus GB-112,CanOverEthernet(UVR67/CIM)

rudolfkoenig

Ich habe das rePublish Attribute in MQTT2_SERVER implementiert:
ZitatrePublish
  if a topic is published from a source inside of FHEM (e.g. MQTT2_DEVICE), it
  is only sent to real MQTT clients, and it will not internally republished. By
  setting this attribute the topic will also be dispatched to the FHEM internal
  clients.