Verzweigung in DOIF bei Trigger anders als mit "set checkall"

Begonnen von q50_treiber, 19 Dezember 2022, 17:08:40

Vorheriges Thema - Nächstes Thema

q50_treiber

Hallo,
ich bin mit meinem Latein am Ende.
Für die Heizungsteuerung setze ich einen Merker wenn 3 Frosttage vorhergesagt werden.
Getriggert wird alle 2 Stunden, da sich die Vorhersagen ändern können.
Ist der Merker bereits gesetzt und ist auch der heutige Folgetag frostig, bleibt der Merker gesetzt.

Die Vorhersagewerte im Test sind: -6.90 / 0.30 / 3.40  , der Merker war von den Vortagen bereits gesetzt.

Problem:
Beim triggern springt DOF nach cmd3,  mit "set checkall" aber korrekt nach cmd2.

Wo liegt mein Denkfehler ?

Gruss

define DOIF_FH_Kalt DOIF ([+02:00] and [?DWD:fc1_Tm] <0 and [?DWD:fc2_Tm] <0 and [?DWD:fc3_Tm] <0 )\
(set Merk_FH on )\
DOELSEIF\
([?Merk_FH:state] eq "on" and [?DWD:fc1_Tm] <2)\
( set Merk_FH on ) \
DOELSE\
(set Merk_FH off)
attr DOIF_FH_Kalt do always
attr DOIF_FH_Kalt room 94_Heizung
attr DOIF_FH_Kalt stateFormat [$name:state]: Merk:[Merk_FH:state]  [DWD:fc1_Tm] / [DWD:fc2_Tm] / [DWD:fc3_Tm]
#   DEF        ([+02:00] and [?DWD:fc1_Tm] <0 and [?DWD:fc2_Tm] <0 and [?DWD:fc3_Tm] <0 )
#(set Merk_FH on )
#DOELSEIF
#([?Merk_FH:state] eq "on" and [?DWD:fc1_Tm] <2)
#( set Merk_FH on )
#DOELSE
#(set Merk_FH off)
#   FUUID      61a53826-f33f-3cce-8434-faae029413453040
#   MODEL      FHEM
#   NAME       DOIF_FH_Kalt
#   NOTIFYDEV  global
#   NR         165
#   NTFY_ORDER 50-DOIF_FH_Kalt
#   STATE      initialized: Merk:off  -6.90 / 0.30 / 3.40
#   TYPE       DOIF
#   VERSION    26703 2022-11-14 16:43:41
#   eventCount 253
#   READINGS:
#     2022-12-19 17:04:34   cmd             0
#     2022-12-19 17:04:34   mode            enabled
#     2022-12-19 17:04:34   state           initialized
#     2022-12-19 17:04:34   timer_01_c01    19.12.2022 19:04:34
#   Regex:
#     accu:
#     collect:
#   attr:
#     cmdState:
#     wait:
#     waitdel:
#   condition:
#     0          ::DOIF_time_once($hash,0,$wday) and ::ReadingValDoIf($hash,'DWD','fc1_Tm') <0 and ::ReadingValDoIf($hash,'DWD','fc2_Tm') <0 and ::ReadingValDoIf($hash,'DWD','fc3_Tm') <0
#     1          ::ReadingValDoIf($hash,'Merk_FH','state') eq "on" and ::ReadingValDoIf($hash,'DWD','fc1_Tm') <2
#   days:
#   do:
#     0:
#       0          set Merk_FH on
#     1:
#       0           set Merk_FH on
#     2:
#       0          set Merk_FH off
#   helper:
#     NOTIFYDEV  global
#     globalinit 1
#     last_timer 1
#     sleeptimer -1
#   intervalfunc:
#   localtime:
#     0          1671473074
#   realtime:
#     0          19:04:34
#   time:
#     0          +02:00
#   timeCond:
#     0          0
#   timer:
#     0          0
#   timers:
#     0           0
#   triggertime:
#     1671473074:
#       localtime  1671473074
#       hash:
#   uiState:
#   uiTable:
#
setstate DOIF_FH_Kalt initialized: Merk:off  -6.90 / 0.30 / 3.40
setstate DOIF_FH_Kalt 2022-12-19 17:04:34 cmd 0
setstate DOIF_FH_Kalt 2022-12-19 17:04:34 mode enabled
setstate DOIF_FH_Kalt 2022-12-19 17:04:34 state initialized
setstate DOIF_FH_Kalt 2022-12-19 17:04:34 timer_01_c01 19.12.2022 19:04:34


Damian

Aus der Einleitung der Commandref zu DOIF
Zitat
Die Angaben werden immer von links nach rechts abgearbeitet. Logische Abfragen werden in DOIF/DOELSEIF-Bedingungen vornehmlich mit Hilfe von and/or-Operatoren erstellt. Zu beachten ist, dass nur die Bedingungen überprüft werden, die zum ausgelösten Event das dazughörige Device bzw. die dazugehörige Triggerzeit beinhalten. Kommt ein Device in mehreren Bedingungen vor, so wird immer nur ein Kommando ausgeführt, und zwar das erste, für das die dazugehörige Bedingung in der abgearbeiteten Reihenfolge wahr ist.

und https://fhem.de/commandref_DE.html#DOIF_checkall
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

q50_treiber

Danke Damian,
Treffer
Pensionierter Informatiker, 40 Jahre Programmierung, aber auf sowas wäre ich nicht gekommen.
Welche Anwendungen gibt es dafür? Warum nicht immer "checkall all" ??  ???

Damian

Zitat von: q50_treiber am 19 Dezember 2022, 18:57:00
Danke Damian,
Treffer
Pensionierter Informatiker, 40 Jahre Programmierung, aber auf sowas wäre ich nicht gekommen.
Welche Anwendungen gibt es dafür? Warum nicht immer "checkall all" ??  ???

Das ist "Ereignisgesteuerte Programmierung" :)

Ich habe persönlich noch nie check all benötigt. Warum das so ist. Nun beim Eintreffen eines Ereignisses ändern sich nicht die Bedingungen, bei denen das Ereignis nicht vorkommt, warum sollte man diese dann prüfen. Im Gegenteil, ich hoffe, dass du dich beim Einschalten von check all nicht wunderst, warum der "eigentliche" Zweig nicht ausgeführt wird, sondern unverhofft einer davor.

Wenn du programmieren kannst, dann kannst du dir gleich den Perl-Modus im DOIF anschauen, da wird nämlich immer ein ganzer Block mit allen if-elsif-Zweigen ausgeführt.




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

q50_treiber

Danke Damian,

damit muss ich mich bei Gelegenheit befassen.
Komme halt aus der Maschinencode, Assembler, Fortran, Algol, Basic, Pascal, C ,  "4GL"   Programmierung.

Natürlich könnte ich auch auf die Temperatur-Readings triggern statt auf Intervalle, dann hätte ich das Gedöns nicht.

Gruss

Damian

#5
Zitat von: q50_treiber am 20 Dezember 2022, 11:54:52
Danke Damian,

damit muss ich mich bei Gelegenheit befassen.
Komme halt aus der Maschinencode, Assembler, Fortran, Algol, Basic, Pascal, C ,  "4GL"   Programmierung.

Natürlich könnte ich auch auf die Temperatur-Readings triggern statt auf Intervalle, dann hätte ich das Gedöns nicht.

Gruss

Das würde ich dir auch empfehlen. Wenn die Temperatur im Minutentakt kommt, dann ist das unkritisch. Zusätzlich kannst du beim Temperatursensor evnet-on-change Attribut setzen, so dass nur noch Änderungen der Temperatur Events produzieren und damit das Modul triggern. Über Zeit zu pollen ist in FHEM nicht erforderlich, weil das System schon ereignisorientiert arbeitet.

PS
Übrigens, wenn man set check all ausführt, ist eine Zeitangabe nie wahr, Zeitangaben sind im DOIF nur zur Triggerzeit wahr und sonst nicht.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

q50_treiber

Danke ,
Temperaturvorhersage kommt vom DWD für die nächsten Tage .
Aktualisierung der Vorhersage ca. alle 2 - 5 Stunden