Liebe DOIF-User,
da es immer wieder vorkommt, dass man unabsichtlich Loops (Schleifen) einbaut, habe ich nun eine DOIF-Version erstellt, die Rekursionen erkennt und verhindert.
Solcher Code z. B. führt mit der aktuellen Version zu einer endlosen Wiederholung, mit der neuen Version wird sie unterbunden:
define di_loop DOIF ([test_1] eq "off") (set test_1 on) DOELSE (set test_2 off)
attr di_loop wait 1,1
attr di_loop do always
set test_1 on
Diese Version ist voll abwärtskompatibel zur bisherigen, sie kann hier geladen und getestet werden.
Wenn keine Beschwerden kommen, werde ich sie einchecken.
Edit: Die Version wurde eingecheckt und wird per Update installiert.
Gruß
Damian
Ich hab diese Version jetzt mal installiert.
Werde berichten, wenn es zu unerwarteten Fehlern kommen sollte ;-)
Zitat von: Toto1973 am 09 Oktober 2015, 11:54:08
Ich hab diese Version jetzt mal installiert.
Werde berichten, wenn es zu unerwarteten Fehlern kommen sollte ;-)
ja,
insb. können jetzt getriggerte Abfragen und Ausführungen auf gleiches Device bedenkenlos benutzt werden:
z. B.
DOIF ([Steckdose:power]<5) (set Steckdose off)
Gruß
Damian
Cool, das vereinfacht einiges!
Hallo Damian,
wieder mal ganz großes Kino von Dir! Ich teste und werde berichten.
Viele Grüße und besten Dank für die Anpassung,
Max
Das DOIF Steuert meinen automatische Werkersteuerung. Der Dummy wecker_manu steht auf Auto und dennoch würde es seit dem 06.10. nicht mehr ausgeführt!
Internals:
DEF ([00:30|7] and [?wecker_manu] eq "auto" and [?Technoclub] eq "nein") (set wakeUp_dummy 09:00,set tag Wochenende)
DOELSEIF ([00:33|8] and [?wecker_manu] eq "auto" and [?Schicht_dummy] eq "Frueh") (set wakeUp_dummy 04:00,set tag Werktags)
DOELSEIF ([00:34|8] and [?wecker_manu] eq "auto" and [?Schicht_dummy] eq "Mittel") (set wakeUp_dummy 08:00,set tag Werktags)
DOELSEIF ([00:31|7] and [?wecker_manu] eq "auto" and [?Technoclub] eq "ja") (set wakeUp_dummy 14:00,set tag Wochenende,set 4917685026123 send Noch viel Spaß beim feiern im Technoclub!)
DOELSEIF ([00:32] and [?Urlaub] eq "on") (set tag aus)
DOELSEIF ([08:35|8] and [?Schicht_dummy] eq "Mittel" and [?sz_Fenster:position] eq "100") (set wakeUp_dummy 9:00,set tag Werktags)
NAME wecker_stellen
NR 94
NTFY_ORDER 50-wecker_stellen
STATE 9_00WE
TYPE DOIF
Readings:
2015-10-06 00:30:00 cmd_event timer_1
2015-10-06 00:30:00 cmd_nr 1
2015-10-06 00:30:00 state 9_00WE
2015-10-10 00:30:00 timer_1_c1 11.10.2015 00:30:00|7
2015-10-10 00:33:00 timer_2_c2 11.10.2015 00:33:00|8
2015-10-10 00:34:00 timer_3_c3 11.10.2015 00:34:00|8
2015-10-10 00:31:00 timer_4_c4 11.10.2015 00:31:00|7
2015-10-10 00:32:00 timer_5_c5 11.10.2015 00:32:00
2015-10-10 08:35:00 timer_6_c6 11.10.2015 08:35:00|8
Condition:
0 DOIF_time_once($hash,$hash->{timer}{0},$wday,"7") and InternalDoIf('wecker_manu','STATE','') eq "auto" and InternalDoIf('Technoclub','STATE','') eq "nein"
1 DOIF_time_once($hash,$hash->{timer}{1},$wday,"8") and InternalDoIf('wecker_manu','STATE','') eq "auto" and InternalDoIf('Schicht_dummy','STATE','') eq "Frueh"
2 DOIF_time_once($hash,$hash->{timer}{2},$wday,"8") and InternalDoIf('wecker_manu','STATE','') eq "auto" and InternalDoIf('Schicht_dummy','STATE','') eq "Mittel"
3 DOIF_time_once($hash,$hash->{timer}{3},$wday,"7") and InternalDoIf('wecker_manu','STATE','') eq "auto" and InternalDoIf('Technoclub','STATE','') eq "ja"
4 DOIF_time_once($hash,$hash->{timer}{4},$wday,"") and InternalDoIf('Urlaub','STATE','') eq "on"
5 DOIF_time_once($hash,$hash->{timer}{5},$wday,"8") and InternalDoIf('Schicht_dummy','STATE','') eq "Mittel" and ReadingValDoIf('sz_Fenster','position','') eq "100"
Days:
0 7
1 8
2 8
3 7
5 8
Devices:
Do:
0:
0 set wakeUp_dummy 09:00,set tag Wochenende
1:
0 set wakeUp_dummy 04:00,set tag Werktags
2:
0 set wakeUp_dummy 08:00,set tag Werktags
3:
0 set wakeUp_dummy 14:00,set tag Wochenende,set 4917685026123 send Noch viel Spaß beim feiern im Technoclub!
4:
0 set tag aus
5:
0 set wakeUp_dummy 9:00,set tag Werktags
6:
Helper:
globalinit 1
last_timer 6
sleeptimer -1
Internals:
Itimer:
Readings:
Realtime:
0 00:30:00
1 00:33:00
2 00:34:00
3 00:31:00
4 00:32:00
5 08:35:00
State:
Time:
0 00:30:00
1 00:33:00
2 00:34:00
3 00:31:00
4 00:32:00
5 08:35:00
Timecond:
0 0
1 1
2 2
3 3
4 4
5 5
Timer:
0 0
1 0
2 0
3 0
4 0
5 0
Timerfunc:
Timers:
0 0
1 1
2 2
3 3
4 4
5 5
Attributes:
cmdState 9_00WE|Fr_4_00WO|Mi_8_00WO|TE_14_00WE|Urlaub|Mi_9_00WO
group Wecker
room DOIFs
Weis jemand, warum das nicht mehr läuft?
Zitatwecker_manu steht auf Auto
Das reicht nicht, dann wird wohl eine der and-Verknüpfungen nicht wahr sein.
Vielleicht arbeitest du mit Aliasnamen oder hast den Status von Schicht_dummy irgendwie (z. B. per devStateIcon) umgebogen.
So etwas kannst du leicht testen, z. B.
define di_test DOIF ([wecker_manu] eq "auto" and [?Schicht_dummy] eq "Frueh") (set blabla on)
trigger wecker_manu
Gruß
Damian
Ich weis jetzt, warum es nicht ging!
Ich habe eine Holiday-Datei eingerichtet. Und die letzte Woche hatte ich Urlaub, der auch in der Holiday-Datei eingetragen war.
Somit wurde jeden Tag State 1 getriggert und da dies ja schon gesetzt war, wurde nichts mehr gemacht.
Das ganze sollte ich ja mit do always beheben können.
Denn der Wecker soll jeden Tag gesetzt werden.
Ich hätte man noch ein Problem.
In diesem Beitrag hier habe ich dazu was geschrieben. http://forum.fhem.de/index.php/topic,42029.0.html (http://forum.fhem.de/index.php/topic,42029.0.html)
Es geht darum, das wenn man Zeitdummys benutzt, das DOIF nicht nach ändern der Zeit im Dummy die Timer neu setzt, sondern erst, wenn die Timerzeit (am nächsten Tag), neu gesetzt wird.
Könnte man denn DOIF so umprogrammieren, das ein Zeitdummy quasi DOIF triggert, wenn sich der wert ändert und so die Timer neu gesetzt werden?
Damian, ich hoffe Du verstehst, was ich meine!
Zitat von: Toto1973 am 10 Oktober 2015, 20:36:43
Ich hätte man noch ein Problem.
In diesem Beitrag hier habe ich dazu was geschrieben. http://forum.fhem.de/index.php/topic,42029.0.html (http://forum.fhem.de/index.php/topic,42029.0.html)
Es geht darum, das wenn man Zeitdummys benutzt, das DOIF nicht nach ändern der Zeit im Dummy die Timer neu setzt, sondern erst, wenn die Timerzeit (am nächsten Tag), neu gesetzt wird.
Könnte man denn DOIF so umprogrammieren, das ein Zeitdummy quasi DOIF triggert, wenn sich der wert ändert und so die Timer neu gesetzt werden?
Damian, ich hoffe Du verstehst, was ich meine!
Wenn man eine indirekte Zeit angibt z. B. [[my_time]], dann wird sie bei Änderung sofort aktualisiert. Funktionsaufrufe dagegen werden einfach zum Ausführungszeitpunkt ausgeführt, sie werden vom Modul nicht verwaltet, daher kann das Modul nicht erkennen, ob sich am Aufruf etwas ändert oder nicht, insb. nicht bei der Angabe von Value("my_time").
Gruß
Damian
Nach erfolgreichen Tests habe ich nun diese Version eingecheckt, da es gehäuft vorkommt, dass die User sich unbewusst (meistens indirekt) Rekursionen einbauen. FHEM unterbindet zwar auch Rekursionen, allerdings bei DOIF-Definitionen greift es oft einen Schritt zu spät.
Dieser Absatz aus der Commandref zu DOIF wurde entfernt, da er jetzt keine Bedeutung hat:
ZitatRekursionen vermeiden
Das Verändern des Status eines Devices z. B. durch set-Befehl, welches in der Bedingung bereits vorkommt, würde das Modul erneut triggern. Solche Rekursionen (Loops) werden zwar von FHEM unterbunden, können jedoch elegant durch Abfragen mit Fragezeichen [?...] gelöst werden:
statt:
define di_lamp ([brightness] < 50 and [lamp] eq "off")(set lamp on)
mit Fragezeichen abfragen:
define di_lamp ([brightness] < 50 and [?lamp] eq "off")(set lamp on)
Abfragen, die grundsätzlich nicht triggern sollen, sollten dagegen weiterhin mit Fragezeichen angegeben werden.
Gruß
Damian
Zitat von: Damian am 10 Oktober 2015, 20:47:45
Wenn man eine indirekte Zeit angibt z. B. [[my_time]], dann wird sie bei Änderung sofort aktualisiert. Funktionsaufrufe dagegen werden einfach zum Ausführungszeitpunkt ausgeführt, sie werden vom Modul nicht verwaltet, daher kann das Modul nicht erkennen, ob sich am Aufruf etwas ändert oder nicht, insb. nicht bei der Angabe von Value("my_time").
Dankeschön!
Ich habe meine sub nun so umgebaut, das die "errechnete" Zeit in ein dummy geschrieben wird.
Nachts um 1 Uhr lassen ich die Sub laufen und jetzt aktualisiert sich auch die Zeit im Timer der DOIF.
Ich möchte meine Heizkörperventile im Wohnzimmer erst nach dem Lüften auf Tagbetrieb setzen. Damit der Türkontakt nicht jedes mal beim Schließen den Tagbetrieb triggert, frage ich "state" des DOIF ab. Das klappt auch alles, wie es soll, auch nach dem hier beschriebenen Unterbinden von Loops.
Meine Frage ist: Wird ein Rückbezug, wie [?meindi] !~ "cmd_2" zukünftig weiterhin erlaubt sein.
define meindi DOIF (...) (...)
DOELSEIF ([?06:00-08:00] and [Türkontakt] eq "closed" and [?meindi] !~ "cmd_2") (set WZventil Tagbetrieb)
DOELSEIF (...) (...)
.
.
.
DOELSEIF (...) (...)
attr meindi do always
Falls das weiterhin möglich sein wird, werde ich auf auf diese Weise einen 3-fach Schrittschalter realisieren, der dann etwa so aussieht:
define step_di DOIF ([step_du] and [step_di] =~ "cmd_3|initialized") ({Log 3, "[step_di]"})
DOELSEIF ([step_du] and [?step_di] =~ "cmd_1") ({Log 3, "[step_di]"})
DOELSEIF ([step_du] and [?step_di] =~ "cmd_2") ({Log 3, "[step_di]"})
"step_du" triggert das Weiterschalten.
Zitat von: Ellert am 01 Dezember 2015, 13:21:27
Ich möchte meine Heizkörperventile im Wohnzimmer erst nach dem Lüften auf Tagbetrieb setzen. Damit der Türkontakt nicht jedes mal beim Schließen den Tagbetrieb triggert, frage ich "state" des DOIF ab. Das klappt auch alles, wie es soll, auch nach dem hier beschriebenen Unterbinden von Loops.
Meine Frage ist: Wird ein Rückbezug, wie [?meindi] !~ "cmd_2" zukünftig weiterhin erlaubt sein.
define meindi DOIF (...) (...)
DOELSEIF ([?06:00-08:00] and [Türkontakt] eq "closed" and [?meindi] !~ "cmd_2") (set WZventil Tagbetrieb)
DOELSEIF (...) (...)
.
.
.
DOELSEIF (...) (...)
attr meindi do always
Falls das weiterhin möglich sein wird, werde ich auf auf diese Weise einen 3-fach Schrittschalter realisieren, der dann etwa so aussieht:
define step_di DOIF ([step_du] and [step_di] =~ "cmd_3|initialized") ({Log 3, "[step_di]"})
DOELSEIF ([step_du] and [?step_di] =~ "cmd_1") ({Log 3, "[step_di]"})
DOELSEIF ([step_du] and [?step_di] =~ "cmd_2") ({Log 3, "[step_di]"})
"step_du" triggert das Weiterschalten.
Zur Zeit steht im Status der Zustand der letzten Ausführung. Ich denke, dass das so bleiben wird, alles andere wäre aus heutiger Sicht nicht sinnvoll.
Gruß
Damian