Hauptmenü

DOIF ohne Loops

Begonnen von Damian, 06 Oktober 2015, 13:52:55

Vorheriges Thema - Nächstes Thema

Damian

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
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Toto1973

Ich hab diese Version jetzt mal installiert.
Werde berichten, wenn es zu unerwarteten Fehlern kommen sollte ;-)
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

Damian

#2
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
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Toto1973

Cool, das vereinfacht einiges!
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

Sirel

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

Toto1973

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?
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

Damian

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
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Toto1973

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.
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

Toto1973

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

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!
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

Damian

#9
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

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

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

#10
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
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Toto1973

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.
Raspberry PI2, Rademacher DuoFern Stick, CUL, 2 x SCC,  JeeLink 868 Mhz, JeeLink 433 Mhz, 3x Magic UFO LED WiFi Controller, 4x MAX BC-RT-TRX-CyG, 2x MAX Fensterkontakt, 5x Rademacher Gurtwickler, 6x TX29DTH-it, 2x TX25-it als Helligkeitssensor, 1X HM-ES-PM, 6x Sonoff, 7x G-Homa, PIR-1000

Ellert

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.

Damian

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

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF