Triggern auf jegliche Zustandsänderung

Begonnen von vbs, 26 Februar 2017, 13:51:43

Vorheriges Thema - Nächstes Thema

dieter56

Der Unterschied ist meines Wissens ist Folgender:

([myDevice]) trigger auf Veränderung aller Reading von myDevice. (Einschränkungen durch event-on-change-reading, ...)

([myDevice:reading]) triggert auf Veränderung des Readings reading von myDevice.

([myDevice:state]) triggert auf Veränderung des Readings state von myDevice. Da state ein Sonderfall ist, der so nicht in den Events vorkommt, muss  das Attribut addStateEvent gesetzt werden damit es funktioniert.

Damian

Zitat von: dieter56 am 27 Februar 2017, 13:19:28
Der Unterschied ist meines Wissens ist Folgender:

([myDevice]) trigger auf Veränderung aller Reading von myDevice. (Einschränkungen durch event-on-change-reading, ...)

([myDevice:reading]) triggert auf Veränderung des Readings reading von myDevice.

([myDevice:state]) triggert auf Veränderung des Readings state von myDevice. Da state ein Sonderfall ist, der so nicht in den Events vorkommt, muss  das Attribut addStateEvent gesetzt werden damit es funktioniert.

1) Es ist egal welche Angabe man macht, es wird getriggert, sobald myDevice im Eventmonitor erscheint.

2) Mit checkReadingEvent kann man es bei Readingangaben [myDevice:reading]  einschränken. Also auch bei ([myDevice:state]) aber nicht bei ([myDevice]), da es keine Readingangabe ist.

3) checkReadingEvent  funktioniert auch ohne Angabe von addStateEvent.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

vbs

Ok, danke erstmal. Ich muss gestehen, dass ich immer noch verwirrt bin. Gerade in Bezug darauf, wann welche Readings ausgewertet werden und wie es sich verhält, wenn man auch noch eventbasierte Bedingungen dazu mischt... naja, bin gerade auf anderen Baustellen unterwegs, aber so richtig verstehen tue ich es noch nicht. Mag aber auch an mir liegen, trotzdem danke!
Vielleicht melde ich mich nochmal zurück zu dem Thema...

Damian

Zitat von: vbs am 27 Februar 2017, 21:30:55
Ok, danke erstmal. Ich muss gestehen, dass ich immer noch verwirrt bin. Gerade in Bezug darauf, wann welche Readings ausgewertet werden und wie es sich verhält, wenn man auch noch eventbasierte Bedingungen dazu mischt... naja, bin gerade auf anderen Baustellen unterwegs, aber so richtig verstehen tue ich es noch nicht. Mag aber auch an mir liegen, trotzdem danke!
Vielleicht melde ich mich nochmal zurück zu dem Thema...

Events der Art [device:"regex"] sind nur zum Zeitpunkt des Triggers wahr und sonst nicht. Readingangaben der Art [device:reading] liefern einfach den Wert des Readings, deswegen fragt man sie normalerweise nach einem Inhalt ab mit einem Perloperator wie eq, ==, usw., eine Veränderung des Readings aber auch schon des dazugehörigen Devices führt ebenfalls zum Trigger des Moduls.

Beispiel:
Du möchtest etwas ausführen, wenn deine Lampe in der Zeit von 18:00 Uhr bis 19:00 Uhr eingeschaltet wird, aber nicht wenn die Lampe um 18:00 Uhr bereits an war, dann musst du definieren [lamp:"on"] and [18:00-19:00]
möchtest du zusätzlich, dass um 18:00 Uhr etwas ausgeführt wird, wenn deine Lampe auch schon vorher an war, dann würdest du definieren: [lamp] eq "on" and [18:00-19:00]
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

vbs

So, ich hab nochmal einiges rumgespielt um es besser zu verstehen und es ist wieder etwas besser geworden. Nochmal ein paar gezielte Fragen bitte:

Was genau wird bei dieser Bedingung geprüft:
([dum:read1])

Ich denke, die Bedingung wird nur unwahr, wenn:
- eine "0" drin steht oder
- leer ist
- oder das Reading "read1" nicht existiert

hattest du Damian glaub ich auch auf Seite 1 schonmal so beschrieben

Dann diese Bedingung:
([dum])

entspricht das
([dum:state])
und verhält sich dann wie im Beispiel davor aber eben mit Reading "state"?


Und dann bitte noch einem zu dem "virtuellen" DOELSE:
Bei dieser Definition wird ein DOELSE vom Modul eingefügt, also wird kein do_always gebraucht:
([dum:read1] eq "on")
Also wenn read1 ungleich "on" ist, dann steht das Modul in "cmd_2". Beim nächsten "on" geht das Modul wieder in "cmd_1" und führt das Kommando aus.

Bei dieser Definition wird aber KEIN DOELSE vom Modul eingefügt, do_always wird also benötigt:
([dum:read1] eq "on") ()
DOELSEIF
([dum:read2] eq "on") ()

Auch wenn beide Bedingungen unwahr sind, steht das Modul im letzten Zustand (cmd_1 oder cmd_2). Es geht jedoch nicht in ein "cmd_3".
Richtig soweit? Fand ich erstmal überraschend, dass in dem einen Fall ein DOELSE eingefügt wird, in dem anderen jedoch nicht. In welchen Fällen genau wird das "virtuelle" DOELSE hinzugefügt?

Danke für die Antworten! :) Wenn ich zu dolle nerve, dann einfach nicht mehr antworten. Ich hab sonst den Hang nachzufragen bis auch der letzte Sonderfall in meinem Kopf geklärt ist :P Nicht böse gemeint...

Damian

Zitat von: vbs am 28 Februar 2017, 17:06:59
So, ich hab nochmal einiges rumgespielt um es besser zu verstehen und es ist wieder etwas besser geworden. Nochmal ein paar gezielte Fragen bitte:

Was genau wird bei dieser Bedingung geprüft:
([dum:read1])

Ich denke, die Bedingung wird nur unwahr, wenn:
- eine "0" drin steht oder
- leer ist
- oder das Reading "read1" nicht existiert
richtig.
Zitat
Dann diese Bedingung:
([dum])

entspricht das
([dum:state])
und verhält sich dann wie im Beispiel davor aber eben mit Reading "state"?

falsch, es wird das Internal state abgefragt und nicht das Reading state, das ist aber normalerweise bei den sauber programmierten Modulen das Gleiche.

Zitat
Und dann bitte noch einem zu dem "virtuellen" DOELSE:
Bei dieser Definition wird ein DOELSE vom Modul eingefügt, also wird kein do_always gebraucht:
([dum:read1] eq "on")
Also wenn read1 ungleich "on" ist, dann steht das Modul in "cmd_2". Beim nächsten "on" geht das Modul wieder in "cmd_1" und führt das Kommando aus.


richtig, allerdings ob ein do always gebraucht wird oder nicht hängt doch eher davon ab, ob der Befehl jedes mal ausgeführt werden soll oder nur nach Zustandswechsel.

Zitat
Bei dieser Definition wird aber KEIN DOELSE vom Modul eingefügt, do_always wird also benötigt:
([dum:read1] eq "on") ()
DOELSEIF
([dum:read2] eq "on") ()

Auch wenn beide Bedingungen unwahr sind, steht das Modul im letzten Zustand (cmd_1 oder cmd_2). Es geht jedoch nicht in ein "cmd_3".
Richtig soweit? Fand ich erstmal überraschend, dass in dem einen Fall ein DOELSE eingefügt wird, in dem anderen jedoch nicht. In welchen Fällen genau wird das "virtuelle" DOELSE hinzugefügt?
Es kommt darauf an, was du möchtest. Hier wird kein virtuelles DOELSE eingefügt, das es ja schon zwei Fälle gibt, die sich abwechseln können.
Du kannst natürlich immer ein DOELSE hinten dranhängen. do always kann gesetzt werden, wenn ohne Zustandswechsel geschaltet werden soll.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

vbs

#21
Zitat von: Damian am 28 Februar 2017, 22:59:18
richtig.
falsch, es wird das Internal state abgefragt und nicht das Reading state, das ist aber normalerweise bei den sauber programmierten Modulen das Gleiche.
Oh, mMn besteht ein großer Unterschied zwischen STATE (dem Internal) und state (dem Reading). STATE wird hauptsächlich für die Darstellung im Frontend verwendet. Das Modul selbst sollte nur das Reading state belegen. Der User kann dann über das Attribut stateFormat entscheiden, wie er das Internal STATE befüllen möchte. Wenn es das Attribut nicht gibt, kopiert FHEM automatisch state nach STATE.

Quelle:
https://wiki.fhem.de/wiki/DevelopmentState

Wäre es in dem Licht (vorausgesetzt ich liege nicht völlig falsch) evtl besser, wenn DOIF wirklich state und nicht STATE heranziehen würde?

Zitat von: Damian am 28 Februar 2017, 22:59:18
Es kommt darauf an, was du möchtest. Hier wird kein virtuelles DOELSE eingefügt, das es ja schon zwei Fälle gibt, die sich abwechseln können.
Ich muss mir noch überlegen was ich möchte :) Aber das heißt, dass es ein virtuelles DOELSE immer gibt, wenn es nur eine Bedingung gibt? Sobald es mehr als eine gibt, wird darauf verzichtet?

vbs

Momentan mal! Das heißt dass die Bedingung ([dum] eq "on") ebenfalls auf STATE und nicht auf state vergleicht?

In der commandref ist meistens nur von "Status" die Rede, was mMn Raum für Spekulationen lässt. Und sorry schonmal fürs erwähnen aber der Plural von Status ist ebenfalls Status (nicht Stati) :) nicht dass das wichtig wäre...

Deckoffizier

#23
Hallo vbs,

Deine beiden Post sind für mich hoch interessant und tue mich mit der Frontend Darstellung als Hilfs,Anzeige,Text neben  z.B. einer Dropdownliste bei verschiedenen Zuständen schwer.

Vermute mal wenn STATE je nach bedarf durch Code geändert wird und state im selben Zusammenhang genutzt wird, es schnell mal zu kuddel muddel kommen kann ?

Könntest Du da noch etwas mehr Licht in mein dunkles Verständnis bringen.
Achso dieser Begriff Stati hat mich auch immer etwas verwirrt!

Danke

Hans-Jürgen
FHEM 5.8 auf "yakkaroo Emu A1FL.1" mit CUL 868MHz, SIGNALduino,2 1Wire USB Busmaster, diverse 1 Wire Sensoren,Landroid,Aeotec USB Dongle Z-Wave Plus

Damian

1) Der Normalfall ist, dass Status (Internal) gleich (Status) (Reading) ist. Das hat etwas mit FHEM zu tun und nicht mit DOIF. Statusabfrage entspricht der FHEM-Perlfunktion Value() und Reading-Statusabfrage ReadingsVal(). Da beide normalerweise identisch sind, ist es egal, was man abfragt.


2) Merkregel: das virtuelle DOELSE gibt es nur in einem einzigen Fall:

Ein definierter Zustand ohne do always
DOIF (Bedingung)(Befehl) entspricht intern DOIF (Bedingung)(Befehl)DOELSE, sonst wäre die Definition nicht sinnvoll, weil das Modul nur einmal schalten würde und aus dem Zustand nicht mehr herauskäme. Für alle anderen Fälle muss man selbst DOELSE angeben, wenn man diesen Fall haben möchte.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

vbs

Zitat von: Deckoffizier am 01 März 2017, 08:34:40
Vermute mal wenn STATE je nach bedarf durch Code geändert wird und state im selben Zusammenhang genutzt wird, es schnell mal zu kuddel muddel kommen kann ?
Könntest Du da noch etwas mehr Licht in mein dunkles Verständnis bringen.
Also eigentlich soll STATE nie durch Code verändert werden. Ich kann nochmal versuchen, in meinen Worten zu beschreiben, wie sich state und STATE verhält:
- das Reading state stellt einen Zustand des Devices dar und wird vom Modul belegt
- das Internal STATE ist ein String, der (primär) zur Anzeige in der Frontends benutzt wird. Mit dem Attribut "stateFormat" kann der Benutzer entscheiden, welchen String er in STATE sehen will. STATE ist also unter Kontrolle des Benutzers, state unter Kontrolle des Moduls. Wenn das Attribut nicht existiert, dann wird automatisch einfach state nach STATE kopiert 1:1.

Beispiel:
Ich hab ein CO2-Sensor, mein Gerät dazu heißt wz_co2mini. Das sieht dann bei mir so aus bzgl. state/STATE:

Internals:
   STATE      505 ppm

Readings:
     2017-03-01 11:55:47   co2             505
     2017-02-28 21:31:27   state           opened

Attributes:
   stateFormat co2 ppm


Also state ist nur "opened", was natürlich für die Anzeige im Frontend ziemlich sinnlos ist. Daher hab ich das Attribut stateFormat auf "co2 ppm" gesetzt, was dazu führt, dass STATE mit dem Wert aus Reading "co2" und dem String "ppm" befüllt wird.

- das Modul selbst sollte nicht das Internal STATE anfassen (würde ansonsten dem Benutzer die Chance nehmen, dort selbst ein Format per stateFormat zu definieren)

Zitat von: Damian am 01 März 2017, 09:56:37
1) Der Normalfall ist, dass Status (Internal) gleich (Status) (Reading) ist. Das hat etwas mit FHEM zu tun und nicht mit DOIF. Statusabfrage entspricht der FHEM-Perlfunktion Value() und Reading-Statusabfrage ReadingsVal(). Da beide normalerweise identisch sind, ist es egal, was man abfragt.
Ahh ok, das ist gut zu wissen! Value() liefert ja den Wert von STATE. Also in FHEM liefert
{Value("wz_co2mini")}
den Wert
520 ppm

Also ich notiere:
([dum]) eq "on"
prüft, ob STATE gleich "on" ist während
([dum:state]) eq "on"
prüft, ob das Reading "state" gleich "on" ist.

Danke, sehr aufschlussreich!

Deckoffizier

Hallo vbs,

Danke für Deine Mühe mit mir!
Im Groben verstehe ich schon wie es sich verhalten soll.

Wo für mich der Hase im Pfeffer liegt ist dies  von dir angeführte. "Also eigentlich soll STATE nie durch Code verändert werden."
Um bei Deinem Beispiel zu bleiben  stateFormat co2 ppm ist ja immer statisch.

Fürs Frontend möchte ich gerne ganz was anderes zu sehen angezeigt bekommen und dies wechselhaft, wie Fenster ist auf, Fenster geschlossen, Zustand aktiv etc. hat also gar kein Zusammenhang mit dem Reading state oder bei Dir  Reading co2.

Eventuell falscher Forumsbereich...
besonders krass wird es ersichtlich bei einem Dummy mit setlist wo neben dem Dropdownfeld der ausgewählte wert identisch angezeigt wird.

Vermutlich bin ich durch RISC-OS und Datenbankanwendung mit Templateeditor geschädigt wo man sich seine Felder in der Ansicht nach Wunsch angelegt und befüllt hat .
Man lernt ja immer noch gerne dazu und werde schon noch die richtige Herangehensweise finden.

Gruß
Hans-Jürgen
FHEM 5.8 auf "yakkaroo Emu A1FL.1" mit CUL 868MHz, SIGNALduino,2 1Wire USB Busmaster, diverse 1 Wire Sensoren,Landroid,Aeotec USB Dongle Z-Wave Plus

vbs

Zitat von: Deckoffizier am 01 März 2017, 19:13:22
Um bei Deinem Beispiel zu bleiben  stateFormat co2 ppm ist ja immer statisch.
Fürs Frontend möchte ich gerne ganz was anderes zu sehen angezeigt bekommen und dies wechselhaft, wie Fenster ist auf, Fenster geschlossen, Zustand aktiv etc. hat also gar kein Zusammenhang mit dem Reading state oder bei Dir  Reading co2.
Guck dir das Attribut mal in der commandref an: https://fhem.de/commandref_DE.html#stateFormat
Du kannst dort auch Perl-Code hinterlegen in geschweiften Klammern, sprich: du bist da völlig frei in der Generierung eines Strings und kannst jede beliebigen Daten mit einbeziehen. Muss also nicht statisch sein.

Deckoffizier

Hallo vbs,

spiele dann noch mal Mephisto....

aus der Referenz:
Falls der Wert in {} eingeschlossen ist, dann wird es als Perl Ausdruck ausgewertet. Die Auswertung passiert bei jeder Änderung eines Readings.

Wenn sich aber  momentan gar kein Reading an DIESEM Gerät ändert und ich für STATE etwas anderes anzeigen möchte ??

Hatte auch erst gedacht in diesem Perlcode den Wert geholt aus einem Dummy  zur Anzeige zu bringen. Hmm künstlich ein Reading auslösen ? Obwohl von addLog muste ich schon Abstand nehmen.

Wenn Dich meine Einfalt zu sehr nervt lass es erstmal gut sein.

Vielen Dank

Hans-Juergen

FHEM 5.8 auf "yakkaroo Emu A1FL.1" mit CUL 868MHz, SIGNALduino,2 1Wire USB Busmaster, diverse 1 Wire Sensoren,Landroid,Aeotec USB Dongle Z-Wave Plus

vbs

Ach gerne doch... freu mich ja, falls ich auch mal wem helfen kann...

Sicherlich kann man sich in deinem Fall beliebige Konstrukte überlegen, um das irgendwie doch noch mit STATE hinzubekommen, aber wenn du im Frontend irgendwie gesammelt Readings verschiedener Geräte anzeigen möchtest, dann guck dir doch mal readingsGroup an. Wenn ich dich richtig verstanden habe, dann könnte das genau das sein was du suchst.