FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Bytechanger am 03 Juli 2016, 21:40:16

Titel: DOIF Frage zu wait
Beitrag von: Bytechanger am 03 Juli 2016, 21:40:16
Hallo,

ich habe eine Verständnisfrage zu DOIF.

Wenn ich in DOIF eine Bedingung angebe, die sich auf den state zweier devices bezieht und als attribut ein wait von 30 Sekunden angebe,
wird das DOIF ausgeführt, wenn die Bedingung wahr ist und 30 Sekunden unverändert wahr bleibt???

Meine Test ergaben, dass das DOIF nicht ausgeführt wird, wenn die Bedingung zutrifft und nach der Wait Zeit nicht mehr zutrifft...
[btnTest] eq "on" and [btnTest2] eq "on" ) ( {  fhem("set Test1 on");; }

Das ergibt die Frage, wie das Verhalten ist, wenn ich nicht auf den State die Bedingung ziehe, sondern auf ein notify...
([btnTest:"on"]) ( {   fhem("set Test1 on");; } )

Hätte erwartet, dass nach dem eintreffen des Events nach der Wartezeit der Befehl ausgeführt wird, egal welchen Zustand nun der btnTest hat.
Weit gefehlt, das Konstrukt verhält sich wie der erste Test, löst also nur aus, wenn der btnTest noch auf on steht?!

Ich habe also für mich jetzt festgestellt: Sobald die Bedingung (oder das Event??) nicht mehr wahr ist, bricht der Timer ab?!
Wie könnte ich mit doif realisieren, dass ein Befehl verzögert ausgeführt wird, wenn z.B. eine Bedingung eintraf, jetzt aber nicht mehr gilt?


Und das Attribut timerWithWait habe ich auch nicht verstanden...



Greets

Byte

Titel: Antw:DOIF Frage zu wait
Beitrag von: automatisierer am 03 Juli 2016, 22:45:44
wenn du mit DOIF auf ein Event reagierst, dann wird das wait nicht gelöscht. Ein Event kann ja nicht "unwahr" werden, es ist eingetreten, das DOIF hat reagiert und das wars.

du kannst es auch mal mit attr xxx do always probieren, dann bleibt der timer auch bestehen...
Titel: Antw:DOIF Frage zu wait
Beitrag von: Bytechanger am 04 Juli 2016, 08:12:16
Das waren auch meine Gedanken. Daher war ich bei diesem Verhalten verwirrt, denn genau dass passiert (der timer wird gelöscht).

([btnTest:"on"]) ( {   fhem("set Test1 on");; } )

Laut doku reagiere ich damit doch auf ein event.
Klicke ich nun btnTest auf on und wieder auf aus, passiert nichts.
Lasse ich es auf on, geht's....

Greets

Byte
Titel: Antw:DOIF Frage zu wait
Beitrag von: Brockmann am 04 Juli 2016, 08:41:55
Bei Verwendung von wait wird das DOIF nach Ablauf der wait-Zeit erneut getriggert. Wenn die Bedingung dann (noch) wahr ist, wird die zugeordnete Aktion ausgeführt.
wait besagt also nur, dass die Bedingung wahr war und nach x Sekunden ebenfalls wahr war. Zwischenzeitlich kann sie prinzipiell sogar unwahr und dann wieder wahr geworden sein.
Wird das DOIF zwischenzeitlich anderweitig getriggert, so dass eine andere Bedingung wahr ist, wird das wait gelöscht.

Um eine Aktion grundsätzlich verzögert auszuführen, selbst wenn das DOIF zwischenzeitlich einen anderen Zustand annimmt, könntest Du das DOIF quasi verlassen, etwa indem die Aktion ein at mit der gewünschten Verzögerung definiert, also etwa so: (define a1 at +00:00:30 set bla blub).

Titel: Antw:DOIF Frage zu wait
Beitrag von: Bytechanger am 04 Juli 2016, 09:07:47
Super, dann habe ich es richtig verstanden. Danke.

Das define at hat das Problem, dass es unbestimmt ist, ob es das define schon gibt. Gibt es eine Möglichkeit per perl darauf zu testen und ggf. den Wert des at zu modifizieren?

Und ein notify ist, wie bereits von automatisierer richtig bemerkt, kein Zustand. Wird aber irgendwie vom DOIF so behandelt. Oder ist meine Abfrage falsch und geht nicht aufs notify??

Da hier die Profis mitlesen, wer kann mir das "timerWithWait" erklären, das commandref lässt sich nicht besonders aussagekräftig darüber aus (Verzögerungen können mit Hilfe des Attributs timerWithWait auf Timer ausgeweitet werden.)


Greets

Byte
Titel: Antw:DOIF Frage zu wait
Beitrag von: Ellert am 04 Juli 2016, 15:04:24
Zitat von: Bytechanger am 04 Juli 2016, 09:07:47
Super, dann habe ich es richtig verstanden. Danke.

Das define at hat das Problem, dass es unbestimmt ist, ob es das define schon gibt. Gibt es eine Möglichkeit per perl darauf zu testen und ggf. den Wert des at zu modifizieren?

Und ein notify ist, wie bereits von automatisierer richtig bemerkt, kein Zustand. Wird aber irgendwie vom DOIF so behandelt. Oder ist meine Abfrage falsch und geht nicht aufs notify??

Da hier die Profis mitlesen, wer kann mir das "timerWithWait" erklären, das commandref lässt sich nicht besonders aussagekräftig darüber aus (Verzögerungen können mit Hilfe des Attributs timerWithWait auf Timer ausgeweitet werden.)


Greets

Byte

Probier mal
([12:00]) (set ...)
mit
wait 30
das wait wird nicht fünktionieren. Erst wenn Du das Attribut timerWithWait setzt geht es. Mit Timer ist eine Zeitangabe im Trigger gemeint.

Zitat von: Bytechanger am 03 Juli 2016, 21:40:16
Hallo,

ich habe eine Verständnisfrage zu DOIF.

Wenn ich in DOIF eine Bedingung angebe, die sich auf den state zweier devices bezieht und als attribut ein wait von 30 Sekunden angebe,
wird das DOIF ausgeführt, wenn die Bedingung wahr ist und 30 Sekunden unverändert wahr bleibt???

Meine Test ergaben, dass das DOIF nicht ausgeführt wird, wenn die Bedingung zutrifft und nach der Wait Zeit nicht mehr zutrifft...
[btnTest] eq "on" and [btnTest2] eq "on" ) ( {  fhem("set Test1 on");; }

Das ergibt die Frage, wie das Verhalten ist, wenn ich nicht auf den State die Bedingung ziehe, sondern auf ein notify...
([btnTest:"on"]) ( {   fhem("set Test1 on");; } )

Hätte erwartet, dass nach dem eintreffen des Events nach der Wartezeit der Befehl ausgeführt wird, egal welchen Zustand nun der btnTest hat.
Weit gefehlt, das Konstrukt verhält sich wie der erste Test, löst also nur aus, wenn der btnTest noch auf on steht?!

Ich habe also für mich jetzt festgestellt: Sobald die Bedingung (oder das Event??) nicht mehr wahr ist, bricht der Timer ab?!
Wie könnte ich mit doif realisieren, dass ein Befehl verzögert ausgeführt wird, wenn z.B. eine Bedingung eintraf, jetzt aber nicht mehr gilt?


Und das Attribut timerWithWait habe ich auch nicht verstanden...



Greets

Byte



Zitat
Meine Test ergaben, dass das DOIF nicht ausgeführt wird, wenn die Bedingung zutrifft und nach der Wait Zeit nicht mehr zutrifft...

Bei einzeiligen DOIF gibt es einen state cmd_2, der eintritt, wenn die Bedingung nicht wahr ist. Daher wird der Timer abgebrochen. Damit sparst Du das DOELSE.
Titel: Antw:DOIF Frage zu wait
Beitrag von: Bytechanger am 04 Juli 2016, 15:11:09
OK, danke für den Hinweis, dann hab ich es glaub ich verstanden (Bis auf die event Geschichte).



Greets

Byte
Titel: Antw:DOIF Frage zu wait
Beitrag von: ht am 05 Juli 2016, 01:07:31
ZitatDas define at hat das Problem, dass es unbestimmt ist, ob es das define schon gibt. Gibt es eine Möglichkeit per perl darauf zu testen und ggf. den Wert des at zu modifizieren?

Verwende einfach defmod anstatt define, das ist genau für solche Fälle mal dazugekommen.

Grüße,
Volker
Titel: Antw:DOIF Frage zu wait
Beitrag von: automatisierer am 05 Juli 2016, 07:47:21
Zitat von: Bytechanger am 04 Juli 2016, 15:11:09
OK, danke für den Hinweis, dann hab ich es glaub ich verstanden (Bis auf die event Geschichte).



Greets

Byte

Beispiel: Fensterkontakt, DOIF triggert wenn Fenster auf:

Wenn du auf einen Device STATE prüfst, wird das DOIF jedes mal getriggert, wenn sich der Zusatnd des device ändert, egal ob das 'open' oder 'closed' ist.
Bei jeder Zustandsänderung, wird aber auch ein Event erzeugt 'Fenster:open' oder 'Fenster:closed' - wenn du also auf ein Event prüfst, wird das DOIF nur getriggert wenn das passende Event kommt. Bei einem '... DOIF ([Fenster:"open"])... also auch nur dann, wenn das Event 'Fenster:open' kommt und nicht bei 'Fenster:closed'

Die Events kannst du natürlich auch beliebig filtern - von trigger auf jedes Event '([""])' bis trigger nur auf genau ein bestimmtes Event eines bestimmten Device (["^Fenster$:^open$"]) - aber, das ist kein Geheimnis, das steht in der Commandref...
Titel: Antw:DOIF Frage zu wait
Beitrag von: Bytechanger am 05 Juli 2016, 08:43:20
Danke, dass Verhalten war mir klar.
Wo ich grübel ist, dass ein event nicht unwahr werden kann, da es statuslos ist. De facto verhält sich doif mit timer aber so.

Hatte bei doif auf event mit wait erwartet, dass nach eintreffen des ebents wait gewartet wird, und dann der befehl ausgeführt wird. Tagsä hlich geht es nur, solange kein weiteres event eintrifft. Das löscht den timer, wenn es dann nicht mehr der bedinging entspricht.

Greets byte
Titel: Antw:DOIF Frage zu wait
Beitrag von: automatisierer am 05 Juli 2016, 09:08:19
Korrekt, wenn du das Event nich so:
[device:"regex"]
abfragst, sondern so:
["device:regex"
dann gehts...

im ersten Fall wird DOIF bei einem Event mit dem device getriggert und überprüft die regex auf wahr/falsch

im zweiten Fall wird offensichtlich nur getriggert, wenn das device und die regex wahr sind.
Titel: Antw:DOIF Frage zu wait
Beitrag von: Bytechanger am 05 Juli 2016, 18:02:52
Na ja, dass commandref sagt etwas anderes, gundsätzlich sollte sich aber das Verhalten gleichen...
(http://fhem.de/commandref_DE.html#DOIF)


Eventauswertung: : [<devicename>:"<regex>"]
Eventauswertung mit regex für verschiedene devices: ["<device regex>:<event regex>"]

Und so ist es auch in Wirklichkeit. Es bleibt dabei, sobald die Bedingung nicht mehr stimmt (also auch für das Device ein anderes Event eintrifft) wird der timer gelöscht!

Es wird auch nicht der Timer bei zutreffender Bedingung gesetzt und nach Ablauf getestet, ob Bedingung immer noch nicht stimmt
SONDER sobald die Bedingung nicht mehr stimmt, der timer gelöscht.

Sieht man im DOIF sehr schön am Reading wait_timer, der sofort auf "no timer" springt, wenn die Bedingung nicht mehr stimmt!

Greets

Byte
Titel: Antw:DOIF Frage zu wait
Beitrag von: Damian am 05 Juli 2016, 19:47:42
Zitat von: Bytechanger am 05 Juli 2016, 18:02:52
Na ja, dass commandref sagt etwas anderes, gundsätzlich sollte sich aber das Verhalten gleichen...
(http://fhem.de/commandref_DE.html#DOIF)


Eventauswertung: : [<devicename>:"<regex>"]
Eventauswertung mit regex für verschiedene devices: ["<device regex>:<event regex>"]

Und so ist es auch in Wirklichkeit. Es bleibt dabei, sobald die Bedingung nicht mehr stimmt (also auch für das Device ein anderes Event eintrifft) wird der timer gelöscht!

Es wird auch nicht der Timer bei zutreffender Bedingung gesetzt und nach Ablauf getestet, ob Bedingung immer noch nicht stimmt
SONDER sobald die Bedingung nicht mehr stimmt, der timer gelöscht.

Sieht man im DOIF sehr schön am Reading wait_timer, der sofort auf "no timer" springt, wenn die Bedingung nicht mehr stimmt!

Greets

Byte

Ein wait-Timer wird immer genau dann gelöscht, wenn das Modul durch ein Ereignis in einen anderen Zustand wechselt bevor der Zustand mit wait eintritt. Insbesondere auch wenn es im bisherigen verbleibt.

Bsp.

aktueller Zustand cmd_1-> Ereignis für cmd_2 ->  wait for cmd_2 -> Ereignis für cmd_1 -> wait-timer für cmd_2 wird gelöscht-> bleibt im  cmd_1


Das Verhalten bzgl. des ELSE-Falls ist unterschiedlich.


Bsp.

DOIF ([DEVICE:"on")(set bla on)

beim Ereignis nicht "on" des DEVICES wechselt das Modul (ohne do always) in cmd_2. Wenn do always gesetzt ist wird kein cmd_2 gesetzt. Es sei denn man definiert:

DOIF ([DEVICE:"on")(set bla on)DOELSE


Beispiel 2:

DOIF (["DEVICE:on")(set bla on)


Hier gibt es grundsätzlich kein cmd_2, da DEVICE nur ein Teil von Regex ist. (Ansonsten würde ein beliebiges Event von einem beliebigen Device cmd_2 auslösen)

Dh. im zweiten Beispiel kann ein wait auf cmd_1 im Gegensatz zum ersten Beispiel nicht unterbrochen werden, weil es keinen anderen Zustand außer cmd_1 gibt.

Gruß

Damian
Titel: Antw:DOIF Frage zu wait
Beitrag von: Bytechanger am 05 Juli 2016, 20:01:15
Ok, jetzt habe ich es, danke!

Bin bei DOIF (["DEVICE:on")(set bla on) nur gescheitert, da es genau 1x ausgeführt wird, es sei denn, man setzt do always.
Mit do always gehts, wie es soll!

Danke nochmal!



Greets

Byte
Titel: Antw:DOIF Frage zu wait
Beitrag von: Damian am 05 Juli 2016, 20:09:17
Zitat von: Bytechanger am 05 Juli 2016, 20:01:15
Ok, jetzt habe ich es, danke!

Bin bei DOIF (["DEVICE:on")(set bla on) nur gescheitert, da es genau 1x ausgeführt wird, es sei denn, man setzt do always.
Mit do always gehts, wie es soll!

ja.

DOIF (["DEVICE:on"])(set bla on)  macht im Gegensatz zu DOIF ([DEVICE:"on"])(set bla on) ohne do always keinen Sinn, weil es wie beschrieben keinen Zustandswechsel gibt.