Doppeltes Event auf state bei MQTT2_DEVICE (set ignorieren?)

Begonnen von der-pw, 24 November 2018, 10:12:20

Vorheriges Thema - Nächstes Thema

der-pw

Hallo,

vorab, ich bin mir bewusst, dass das dieses "Problem" in der aktuellen Konfiguration völlig normal ist.
Ich weiß allerdings nicht, wie ich es lösen kann. Der Thread hat mir auch nicht weitergeholfen und etwas anderes habe ich nicht gefunden, zu dem Thema.

Ich abonniere bei einem TasmotaDevice (hier am Beispiel eines Sonoff DUAL) den Topic "stat/sonoff_wz_dual/POWER1" auf das Reading "POWER1"
Mit "stateFormat POWER1" gebe ich den aktuellen Zustand an "state" weiter. Schließlich möchte ich den wirkichen state, der ja auch mal extern ausgelöst werden kann (Knopfdruck etc.)

Wenn ich nun mit "set mqtt_sw_wz_holzlampe on" anschalten möchte, habe ich zwei Mal das Event auf state
2018-11-24 09:59:22 MQTT2_DEVICE mqtt_sw_wz_holzlampe on
2018-11-24 09:59:22 MQTT2_DEVICE mqtt_sw_wz_holzlampe on

... was ja auch völlig normal ist.
Wie kann ich aber nun das "set" ignorieren, sodass nur ein Event erzeugt wird, wenn der Rückgabewert aus "POWER1" erzeugt wird?

Falls die Frage aufkommt, warum ich überhaupt den Schritt über "stateFormat POWER1" gehe? Ich möchte später, den Onlinestatus des TasmotaDevice (LWT) abonieren und den möglichen Offlinezustand auch an "state" übergeben.

Internals:
   DEVICETOPIC mqtt_sw_wz_holzlampe
   IODev      mqtt2_server
   LASTInputDev mqtt2_server
   MSGCNT     88
   NAME       mqtt_sw_wz_holzlampe
   NR         260
   STATE      off
   TYPE       MQTT2_DEVICE
   mqtt2_server_MSGCNT 88
   mqtt2_server_TIME 2018-11-24 09:44:06
   OLDREADINGS:
   READINGS:
     2018-11-24 09:44:06   POWER1          OFF
     2018-11-24 09:44:06   state           off
Attributes:
   DbLogExclude .*
   IODev      mqtt2_server
   alexaName  Holzlampe
   alexaRoom  Wohnzimmer
   eventMap   { dev=>{ON=>'on',OFF=>'off'} }
   genericDeviceType light
   readingList DVES_9D7CEE:stat/sonoff_wz_dual/POWER1:.* POWER1
   room       01_Wohnzimmer,Homekit,MQTT2_DEVICE,alexa
   setList    off:noArg    cmnd/sonoff_wz_dual/POWER1 0
on:noArg     cmnd/sonoff_wz_dual/POWER1 1
   siriName   Holzlampe
   stateFormat POWER1
   webCmd     on:off:toggle


Schöne Grüße,
Patrick

dev0

ZitatWie kann ich aber nun das "set" ignorieren, sodass nur ein Event erzeugt wird
Ob es spezielle Mechanismen in den MQTT* Modulen gibt weiß ich nicht, aber allgemein gesehen würden die globalen Attribute event-on-change-reading und event-on-update-reading doch greifen, oder?

der-pw

Zitat... doch greifen, oder?
Kurz und knapp, ja! Manchmal sieht man den Wald vor lauter Bäumen nicht.

Danke fürs "wachrütteln".  ;)

der-pw

#3
Zu früh gefreut.
Mit attr <dev> event-on-change-reading state wird state nicht mehr geloggt, wenn ich z.b. über die Tasmota-Weboberfläche schalte, obwohl der state eindeutig wechselt.


Edit:
attr <dev> event-on-change-reading POWER1.*
damit läuft es

Beta-User

Bin nicht sicher, aber mir kommt es so vor, als wäre es in dem Fall evtl. besser, ein event-min-interval zu definieren (kann eine kurze Spanne von z.B. nur 2 Sec. sein), und das auf alle Readings anzuwenden.

An sich müßte das Problem aber eigentlich bei allen bisherigen MQTT-Modulen bestehen, da viele Implementierungen auf der Client-Seite so gestrickt sind, dass sie eine Rückmeldung erzeugen, wenn der Befehl umgesetzt wurde. Von daher wäre zu überlegen, ob man nicht eine (deaktivierbare) set_xx-Logik einbauen könnte, so wie das z.B. bei CUL_HM der Fall ist? Ist aber vermutlich nicht ganz easy...
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

#5
Zitat von: Beta-User am 24 November 2018, 13:27:13
An sich müßte das Problem aber eigentlich bei allen bisherigen MQTT-Modulen bestehen, da viele Implementierungen auf der Client-Seite so gestrickt sind, dass sie eine Rückmeldung erzeugen, wenn der Befehl umgesetzt wurde.
Die Lösung heißt - getrennte Topics für das Befehl und die Rückmeldung. Dann ändert sich der Zustand dann (und nur dann), wenn es wirklich geschaltet wurde. Unabhängig davon, woher das Schaltbefehl kam.

Beispiel für UI einer per Mqtt schaltbaren Lampe mit getrennten Topics:
defmod DG_WZ_Licht_Top dummy
attr DG_WZ_Licht_Top devStateIcon off:light_light_dim_00@gray on:light_light_dim_100@#FF5722 .*:hourglass
attr DG_WZ_Licht_Top eventMap {usr=>{'an'=>'on','aus'=>'off'},fw=>{'an'=>'an:noArg','aus'=>'aus:noArg'}}
attr DG_WZ_Licht_Top icon light_ceiling
attr DG_WZ_Licht_Top mqttForward none
attr DG_WZ_Licht_Top mqttPublish state|select:topic=/ha/dg/wz/licht/top/set
attr DG_WZ_Licht_Top mqttSubscribe state|select:topic=/ha/dg/wz/licht/top/state
attr DG_WZ_Licht_Top readingList select
attr DG_WZ_Licht_Top setList on:noArg off:noArg select:iconRadio,use4icon@000000,off,circle_percent_v1_off@808080,on,circle_percent_v1_on@808080
attr DG_WZ_Licht_Top webCmd select
attr DG_WZ_Licht_Top widgetOverride setList:textField-long


EDIT: Das Beispiel setzt Nutzung von MQTT_GENERIC_BRIDGE voraus.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

Beta-User

...an sich einleuchtend...
Paßt auch auf meine Beobachtungen zum Verhalten z.B. der Zigbee-Leuchten.
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

Ich meine das Problem ist leicht anders gelagert.
Tasmota meldet das Schalten ueber zwei getrennte Topics:
Zitatstat/sonoff/POWER1:OFF
stat/sonoff/RESULT:{"POWER1":"OFF"}

Das bisherige autocreate hat das mitXX:stat/sonoff/RESULT:.* { json2nameValue($EVENT) }
XX:stat/sonoff/POWER1:.* POWER1
zu zweimal "POWER1:off" konvertiert, was wegen stateFormat zu zweimal "off" gefuehrt hat.

Ich habe autocreate jetzt erweitert, damit RESULT als
XX:stat/sonoff/RESULT:.* { json2nameValue($EVENT, 'RESULT_') }angelegt wird, d.h. Readings aus RESULT tragen den zusaetzlichen Praefix RESULT_. Damit steigt zwar die Zahl der Readings weiter (POWER1 und RESULT_POWER1), aber wenigstens gibt es keine doppelten Events.Wuerde mich freuen, wenn jemand das noch verifiziert.

Achtung: die Aenderung betrifft nur neu erweiterte ReadingList, die alten muss man manuell korrigieren.

der-pw

Danke für das Feedback bisher.

Rudolf, ich habe mein Device schon "ausgemistet" und abonniere ja nur noch den Topic "readingList DVES_9D7CEE:stat/sonoff_wz_dual/POWER1:.* POWER1" daher schließe ich das Doppelte Event darüber mal aus.

Wenn der neue Status über MQTT reinkommt, sprich ich den Sonoff in der Tasmotaoberfläche schalte, oder den cmnd-Topic direkt anspreche, dann habe ich nur ein Event auf "state".
Daher gehe ich fest davon aus, dass wenn ich in FHEM direkt schalte, das zusätzliche "state" über "set mqtt_sw_wz_holzlampe on/off" kommt. Kann das so sein?

Ich teste deinen Vorschlag nachher aber gern, wenn ich wieder zu Hause bin.

ZitatAn sich müßte das Problem aber eigentlich bei allen bisherigen MQTT-Modulen bestehen, da viele Implementierungen auf der Client-Seite so gestrickt sind, dass sie eine Rückmeldung erzeugen, wenn der Befehl umgesetzt wurde. Von daher wäre zu überlegen, ob man nicht eine (deaktivierbare) set_xx-Logik einbauen könnte, so wie das z.B. bei CUL_HM der Fall ist? Ist aber vermutlich nicht ganz easy...
So ein bißchen ist das auch mein Mantra. "Bei CUL_HM funktioniert das ja" :-)

ZitatDie Lösung heißt - getrennte Topics für das Befehl und die Rückmeldung. Dann ändert sich der Zustand dann (und nur dann), wenn es wirklich geschaltet wurde. Unabhängig davon, woher das Schaltbefehl kam.
Prinzipiell eine gute Lösung. Wenn ich logisch verstanden habe.
Aber du gehst den Weg über Dummy und ein weiteres Modul. Das wollte ich mir vorerst sparen.

Bzw. der Umstieg auf MQTT2 war auch zurück zu "weniger ist mehr" ;-)

hexenmeister

ZitatPrinzipiell eine gute Lösung. Wenn ich logisch verstanden habe.
Aber du gehst den Weg über Dummy und ein weiteres Modul. Das wollte ich mir vorerst sparen.
Dieses weitere Modul ist nur einmal vorhanden und erlaubt dafür sämtliche mqtt_devices einzusparen. Weniger ist mehr  ;)
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

rudolfkoenig

ZitatDie Lösung heißt - getrennte Topics für das Befehl und die Rückmeldung.
Ich fuerchte wir (mich inklusive) mischen hier unterschiedliche Sachen:
- ein "set XX on" erzeugt ein Event "XX on".
- die Rueckmeldung vom Geraet erzeugt "XX POWER1 on". Mit dem neuen Syntax eins weniger, aber kein "XX on"
- stateFormat setzt nur den Internal STATE, wg der Anzeige. Hat nichts mit Events zu tun.
- mit MQTT2_CLIENT+mosquitto+Tasmota kriegt man immer noch 2x POWER1: einmal aus dem gesendeten cmnds/sonoff/POWER1 (was mosquitto zurueckschickt), und einmal aus stat/sonoff/POWER1. Weiss noch nicht, wie ich das vermeiden soll
- mit MQTT2_SERVER gibts dieses Problem nicht.

=> Damit ist fuer mich das doppelte "XX on" aus dem ersten Beitrag noch nicht erklaert.

der-pw

#11
Danke für die Infos, da nehme ich auf jeden Fall wieder was mit.
Dass stateFormat nur den Internal STATE setzt und kein Event auslöst wusste ich nicht.

Also ich setze MQTT2_SERVER ein.

ZitatDamit ist fuer mich das doppelte "XX on" aus dem ersten Beitrag noch nicht erklaert.
Vermutlich kann ich es jetzt erklären.
das attr <dev> eventMap { dev=>{ON=>'on',OFF=>'off'} } schlägt da gnadenlos, auf alles was ON/OFF ist, zu.

Das erste "XX on" ist mein "set XX on" aus der Weboberfläche das zweite "XX on" ist eigentlich "POWER1 ON" was ja von eventMap gändert wurde.

Ich musste mein Sonoff DUAL als Testgerät aufgeben und habe einen Sonoff Zwischenstecker per autocreate angelegt.
Da fiel es mir dann auch auf.

Beim Schalten aus der Weboberfläche heraus.
- ohne eventMap:
2018-11-24 23:15:52 MQTT2_DEVICE MQTT2_DVES_3E0F61 on
2018-11-24 23:15:52 MQTT2_DEVICE MQTT2_DVES_3E0F61 RESULT_POWER: ON
2018-11-24 23:15:52 MQTT2_DEVICE MQTT2_DVES_3E0F61 POWER: ON


- mit eventMap:
2018-11-24 23:16:19 MQTT2_DEVICE MQTT2_DVES_3E0F61 on
2018-11-24 23:16:19 MQTT2_DEVICE MQTT2_DVES_3E0F61 on
2018-11-24 23:16:19 MQTT2_DEVICE MQTT2_DVES_3E0F61 on


Irgendwie bin ich nun unsicherer als zuvor.
Auf state schalte ich das Device, aber auf state möchte ich auch das Feedback sehen. Das muss ja unweigerlich zwei Events erzeugen. Muss ich mich damit anfreunden, dass ich ein anderes reading (gleich POWER) als Feedback hernehme um z.B. den Zustand in Alexa oder Homekit zu sehen? Aber auf der anderen Seite muss state ja auch den aktuellen Zustand vom Device bekommen, da es sonst im WebIF nicht den genauen Status anzeigt. Ich dreh mich irgendwie im Kreis.

Kurzer Geistesblitz vor um Mitternacht:
Vielleicht kann man ja RESULT_POWER hernehmen um mit eventMap den state zu setzen, und auf POWER triggert man einfach weiterführende Aktionen und hat eben keine Doppelaktionen mehr.

rudolfkoenig

Danke fuer die Recherche.

So muesste man eventMap anpassen, damit das passiert, was ich eigentlich wollte:
attr DEVICE eventMap { dev=>{'^(.*)POWER(.): OFF$'=>'$1POWER$2: off', '^(.*)POWER(.): ON$'=>'$1POWER$2: on'} }
Allerdings ist STATE dank stateFormat immer noch ON/OFF, da stateFormat auf das Reading zugreift, und eventMap die Events aendert, nicht die Readings selbst. Und ON/OFF erzeugt beim draufklicken kein toggle, dazu braucht man on/off.

Also muss stateFormat angepasst werden:attr DEVICE stateFormat {lc ReadingsVal("$name","POWER1",0)}
Aber dann ist eventMap ueberfluessig.

=> ich habe in attrTemplate das umgebauten stateFormat eingebaut und eventMap entfernt. Schalten erzeugt Folgendes:fhem> set MQTT2_mc off
2018-11-25 09:31:28 MQTT2_DEVICE MQTT2_mc off
2018-11-25 09:31:28 MQTT2_DEVICE MQTT2_mc RESULT_POWER1: OFF
2018-11-25 09:31:28 MQTT2_DEVICE MQTT2_mc POWER1: OFF



Wg. dem Geistesblitz: Beide Events kommen vom Geraet, ich verstehe noch nicht, warum RESULT_POWER1 besser sein soll als POWER1.

der-pw

ZitatSo muesste man eventMap anpassen, ...
[...]
Also muss stateFormat angepasst werden:
Hätte ich so nie hinbekommen, dankeschön!

ZitatSchalten erzeugt Folgendes:
Ja, bestätige ich! ;-)

Also heißt es zusammenfassend für mich.
Auf "state" schalte ich intern, wenn bspw. mittels notify, die Steckdose durch ein Event ausgelöst werden soll.
<dev>:event { fhem "set Steckdose on/off" }

Auf POWER oder RESULT_POWER (man kann den Topic ja auch entfernen und spart sich wieder ein Reading) reagiere ich, wenn in Abhängigkeit dessen Status weiteres passieren soll, oder ich den aktuellen Schaltzustand sowohl in Homekit oder Alexa darstellen möchte.

Vielen Dank für den Austausch, hat mich definitiv weitergebracht.
Ich hoffe mit meiner dummen Fragerei, konnte ich auch ein wenig für Inspiration sorgen.
Mir gefällt das mit den z.B. mit den Präfixen in den Readings richtig gut.

ZitatWg. dem Geistesblitz: Beide Events kommen vom Geraet, ich verstehe noch nicht, warum RESULT_POWER1 besser sein soll als POWER1.
Es war spät und wir hatten gestern Kindergeburtstag. ;-)

der-pw

Die Kapitulation vor meiner eigenen Unfähigkeit, hat mir nochmal einen anderen Weg aufgezeigt.
Warum das ganze? Weil ich es einfach nicht hinbekommen habe, Alexa zu zeigen welchen Zustand das Device gerade hat, in Homekit lief es perfekt.

Ich manipuliere jetzt state über userReadings state:RESULT_POWER.* {lc ReadingsVal("$name","RESULT_POWER",0)}
und entprelle das ganze in event-on-change-reading .* auf.

Wenn ich nun über WebIF schalte:
2018-11-25 17:04:36 MQTT2_DEVICE MQTT2_DVES_3E0F61 on
2018-11-25 17:04:36 MQTT2_DEVICE MQTT2_DVES_3E0F61 RESULT_POWER: ON
2018-11-25 17:04:36 MQTT2_DEVICE MQTT2_DVES_3E0F61 POWER: ON


und über extern:
2018-11-25 17:05:09 MQTT2_DEVICE MQTT2_DVES_3E0F61 RESULT_POWER: OFF
2018-11-25 17:05:09 MQTT2_DEVICE MQTT2_DVES_3E0F61 off
2018-11-25 17:05:09 MQTT2_DEVICE MQTT2_DVES_3E0F61 POWER: OFF


Damit kann ich leben, Siri war eh schon glücklich, und der digitale Sprachassisten eine großen Onlineversenders, dess Name bei uns nicht genannt werden darf, ist es nun auch.


Internals:
   CID        DVES_3E0F61
   DEF        DVES_3E0F61
   DEVICETOPIC MQTT2_DVES_3E0F61
   IODev      mqtt2_server
   LASTInputDev mqtt2_server
   MSGCNT     175
   NAME       MQTT2_DVES_3E0F61
   NR         261
   STATE      off
   TYPE       MQTT2_DEVICE
   mqtt2_server_MSGCNT 175
   mqtt2_server_TIME 2018-11-25 16:58:45
   OLDREADINGS:
   READINGS:
     2018-11-25 11:46:23   INFO1_FallbackTopic DVES_3E0F61
     2018-11-25 11:46:23   INFO1_GroupTopic sonoffs
     2018-11-25 11:46:23   INFO1_Module    Sonoff S2X
     2018-11-25 11:46:23   INFO1_Version   6.3.0
     2018-11-25 11:46:23   INFO2_Hostname  teststecki-3937
     2018-11-25 11:46:23   INFO2_IPAddress 192.168.178.75
     2018-11-25 11:46:23   INFO2_WebServerMode Admin
     2018-11-25 11:46:23   INFO3_RestartReason Power on
     2018-11-25 14:20:41   LWT             online
     2018-11-25 16:57:49   POWER           OFF
     2018-11-25 16:57:49   RESULT_POWER    OFF
     2018-11-25 16:58:45   STATE_POWER     OFF
     2018-11-25 16:58:45   STATE_Time      2018-11-25T16:58:34
     2018-11-25 16:58:45   STATE_Uptime    0T05:12:19
     2018-11-25 16:58:45   STATE_Vcc       3.170
     2018-11-25 16:58:45   STATE_Wifi_AP   1
     2018-11-25 16:58:45   STATE_Wifi_BSSId E0:28:6D:D2:72:AF
     2018-11-25 16:58:45   STATE_Wifi_Channel 1
     2018-11-25 16:58:45   STATE_Wifi_RSSI 98
     2018-11-25 16:58:45   STATE_Wifi_SSId FRITZ!Box 7490
     2018-11-25 16:02:03   UPTIME_Time     2018-11-25T16:02:00
     2018-11-25 16:02:03   UPTIME_Uptime   0T04:15:45
     2018-11-25 16:23:38   alexa_state     off
     2018-11-25 16:57:49   state           off
Attributes:
   DbLogExclude .*
   IODev      mqtt2_server
   alexaName  Teststecki
   event-on-change-reading .*
   genericDeviceType switch
   readingList DVES_3E0F61:stat/teststecki/POWER:.* POWER
DVES_3E0F61:tele/teststecki/LWT:.* LWT
DVES_3E0F61:tele/teststecki/INFO1:.* { json2nameValue($EVENT, 'INFO1_') }
DVES_3E0F61:tele/teststecki/INFO2:.* { json2nameValue($EVENT, 'INFO2_') }
DVES_3E0F61:tele/teststecki/INFO3:.* { json2nameValue($EVENT, 'INFO3_') }
DVES_3E0F61:tele/teststecki/STATE:.* { json2nameValue($EVENT, 'STATE_') }
DVES_3E0F61:tele/teststecki/UPTIME:.* { json2nameValue($EVENT, 'UPTIME_') }
DVES_3E0F61:stat/teststecki/RESULT:.* { json2nameValue($EVENT, 'RESULT_') }
   room       Homekit,MQTT2_DEVICE,alexa
   setList    off:noArg    cmnd/teststecki/POWER 0
on:noArg     cmnd/teststecki/POWER 1
   siriName   Teststecki
   userReadings state:RESULT_POWER.* {lc ReadingsVal("$name","RESULT_POWER",0)}