Nicht deterministisches DOIF-Verhalten (zumindest für mich)

Begonnen von tobi01001, 18 März 2025, 13:33:55

Vorheriges Thema - Nächstes Thema

tobi01001

Hi,

entweder ist mein Horizont zu begrenzt oder irgendwas passt nicht.... (oder beides ;-)). zumindest fehlen mir Events und die Ausführung eines ganzen Blocks.
Zum Nachstellen folgendes Konstrukt bzw. Konstrukte:
define di_TestEvents_DOIF DOIF testBlock {\
fhem("set $SELF testBlockTriggered ".([?$SELF:testBlockTriggered]+1));;\
if([$SELF:event1] eq "gerade")\
{\
Log(0, "$SELF testBlock $EVENT");; \
}\
elsif([$SELF:event2] eq "gerade")\
{\
Log(0, "$SELF testBlock $EVENT");; \
}\
else\
{\
Log(0, "$SELF testBlock $EVENT");; \
}\
}\
\
\
\
timerBlock {\
fhem("set $SELF timerBlockTriggered ".([?$SELF:timerBlockTriggered]+1));;\
if([+00:00:10]) {\
fhem("set $SELF counter ".([?$SELF:counter] + 1));;\
Log(0, "$SELF timerBlock $EVENT und counter ".[?$SELF:counter]);;\
}\
if([?$SELF:counter] % 2) {\
fhem("set dmy_TestEvents_DUMMY event1 ungerade");;\
}\
else {\
fhem("set dmy_TestEvents_DUMMY event1 gerade");;\
}\
if(([?$SELF:counter] + 1) % 2) {\
fhem("set dmy_TestEvents_DUMMY event2 ungerade");;\
}\
else {\
fhem("set dmy_TestEvents_DUMMY event2 gerade");;\
}\
}
attr di_TestEvents_DOIF DOIF_Readings event2:{if(([$SELF:counter]+1) % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF DbLogExclude .*
attr di_TestEvents_DOIF event_Readings event1:{if([$SELF:counter] % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF readingList counter testBlockTriggered timerBlockTriggered testBlockDmyTriggered
attr di_TestEvents_DOIF setList counter:0 timerBlockTriggered:0 testBlockTriggered:0 testBlockDmyTriggered:0
#   CFGFN     
#   DEF        testBlock {
# fhem("set $SELF testBlockTriggered ".([?$SELF:testBlockTriggered]+1));
# if([$SELF:event1] eq "gerade")
# {
# Log(0, "$SELF testBlock $EVENT");
# }
# elsif([$SELF:event2] eq "gerade")
# {
# Log(0, "$SELF testBlock $EVENT");
# }
# else
# {
# Log(0, "$SELF testBlock $EVENT");
# }
#}
#
#
#
#timerBlock {
# fhem("set $SELF timerBlockTriggered ".([?$SELF:timerBlockTriggered]+1));
# if([+00:00:10]) {
# fhem("set $SELF counter ".([?$SELF:counter] + 1));
# Log(0, "$SELF timerBlock $EVENT und counter ".[?$SELF:counter]);
# }
# if([?$SELF:counter] % 2) {
# fhem("set dmy_TestEvents_DUMMY event1 ungerade");
# }
# else {
# fhem("set dmy_TestEvents_DUMMY event1 gerade");
# }
# if(([?$SELF:counter] + 1) % 2) {
# fhem("set dmy_TestEvents_DUMMY event2 ungerade");
# }
# else {
# fhem("set dmy_TestEvents_DUMMY event2 gerade");
# }
#}
#   FUUID      67d95482-f33f-bc77-303e-23c7ae1d6359363e
#   MODEL      Perl
#   NAME       di_TestEvents_DOIF
#   NOTIFYDEV  global,di_TestEvents_DOIF
#   NR         796
#   NTFY_ORDER 50-di_TestEvents_DOIF
#   STATE      initialized
#   TYPE       DOIF
#   VERSION    29460 2024-12-29 20:25:48
#   eventCount 715
#   DOIF_Readings:
#     event2     {if((::ReadingValDoIf($hash,'di_TestEvents_DOIF','counter')+1) % 2) { "ungerade"; } else {"gerade";} }
#   Helper:
#     DBLOG:
#       cmd:
#         myDbLog:
#           TIME       1742296194.08755
#           VALUE      0
#       mode:
#         myDbLog:
#           TIME       1742296194.08755
#           VALUE      enabled
#       state:
#         myDbLog:
#           TIME       1742296194.08755
#           VALUE      initialized
#   READINGS:
#     2025-03-18 13:01:31   block_testBlock executed
#     2025-03-18 13:11:30   block_timerBlock executed
#     2025-03-18 13:11:30   counter         74
#     2025-03-18 13:01:00   e_di_TestEvents_DOIF_event1 ungerade
#     2025-03-18 13:01:31   e_di_TestEvents_DOIF_event2 ungerade
#     2025-03-18 13:11:30   event1          gerade
#     2025-03-18 13:11:30   event2          ungerade
#     2025-03-18 13:01:00   mode            enabled
#     2025-03-18 13:01:00   state           initialized
#     2025-03-18 13:00:55   testBlockDmyTriggered 62
#     2025-03-18 13:01:31   testBlockTriggered 12
#     2025-03-18 13:11:30   timerBlockTriggered 73
#     2025-03-18 13:11:30   timer_01_c02    18.03.2025 13:11:40
#   Regex:
#     DOIF_Readings:
#       di_TestEvents_DOIF:
#         event2:
#           counter    ^di_TestEvents_DOIF$:^counter:
#     accu:
#     bar:
#     barAvg:
#     collect:
#     cond:
#       di_TestEvents_DOIF:
#         0:
#           event1     ^di_TestEvents_DOIF$:^event1:
#           event2     ^di_TestEvents_DOIF$:^event2:
#         1:
#     event_Readings:
#       di_TestEvents_DOIF:
#         event1:
#           counter    ^di_TestEvents_DOIF$:^counter:
#   condition:
#     0         
# fhem("set di_TestEvents_DOIF testBlockTriggered ".(::ReadingValDoIf($hash,'di_TestEvents_DOIF','testBlockTriggered')+1));
# if(::ReadingValDoIf($hash,'di_TestEvents_DOIF','event1') eq "gerade")
# {
# Log(0, "di_TestEvents_DOIF testBlock $EVENT");
# }
# elsif(::ReadingValDoIf($hash,'di_TestEvents_DOIF','event2') eq "gerade")
# {
# Log(0, "di_TestEvents_DOIF testBlock $EVENT");
# }
# else
# {
# Log(0, "di_TestEvents_DOIF testBlock $EVENT");
# }
#
#     1         
# fhem("set di_TestEvents_DOIF timerBlockTriggered ".(::ReadingValDoIf($hash,'di_TestEvents_DOIF','timerBlockTriggered')+1));
# if(::DOIF_time_once($hash,0,$wday)) {
# fhem("set di_TestEvents_DOIF counter ".(::ReadingValDoIf($hash,'di_TestEvents_DOIF','counter') + 1));
# Log(0, "di_TestEvents_DOIF timerBlock $EVENT und counter ".::ReadingValDoIf($hash,'di_TestEvents_DOIF','counter'));
# }
# if(::ReadingValDoIf($hash,'di_TestEvents_DOIF','counter') % 2) {
# fhem("set dmy_TestEvents_DUMMY event1 ungerade");
# }
# else {
# fhem("set dmy_TestEvents_DUMMY event1 gerade");
# }
# if((::ReadingValDoIf($hash,'di_TestEvents_DOIF','counter') + 1) % 2) {
# fhem("set dmy_TestEvents_DUMMY event2 ungerade");
# }
# else {
# fhem("set dmy_TestEvents_DUMMY event2 gerade");
# }
#
#   days:
#   event_Readings:
#     event1     {if(::ReadingValDoIf($hash,'di_TestEvents_DOIF','counter') % 2) { "ungerade"; } else {"gerade";} }
#   helper:
#     NOTIFYDEV  global,di_TestEvents_DOIF
#     event      counter: 74,event2: ungerade
#     globalinit 1
#     last_timer 1
#     sleeptimer -1
#     triggerDev di_TestEvents_DOIF
#     DOIF_Readings_events:
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#     DOIF_Readings_eventsState:
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#     triggerEvents:
#       counter: 74
#       event2: ungerade
#       event1: gerade
#     triggerEventsState:
#       counter: 74
#       event2: ungerade
#       event1: gerade
#   hmccu:
#   internals:
#   interval:
#   intervalfunc:
#   localtime:
#     0          1742299900
#   perlblock:
#     0          testBlock
#     1          timerBlock
#   readings:
#     all         di_TestEvents_DOIF:event1 di_TestEvents_DOIF:event2
#   realtime:
#     0          13:11:40
#   time:
#     0          +00:00:10
#   timeCond:
#     0          1
#   timer:
#     0          0
#   timers:
#     1           0
#   trigger:
#   triggertime:
#     1742299900:
#       localtime  1742299900
#       hash:
#   uiState:
#   uiTable:
#
Erwartet hätte ich Log-Einträge mit 2025.03.18 13:00:45 0: di_TestEvents_DOIF timerBlock timer_1 und counter 10
2025.03.18 13:00:45 0: di_TestEvents_DOIF testBlock event1: gerade
2025.03.18 13:00:45 0: di_TestEvents_DOIF testBlock event2: ungerade
2025.03.18 13:00:55 0: di_TestEvents_DOIF timerBlock timer_1 und counter 11
2025.03.18 13:00:15 0: di_TestEvents_DOIF testBlock event1: ungerade
2025.03.18 13:00:15 0: di_TestEvents_DOIF testBlock event2: gerade
2025.03.18 13:00:15 0: di_TestEvents_DOIF testBlock event1: gerade
Es kommen allerdings nur
2025.03.18 13:01:40 0: di_TestEvents_DOIF timerBlock timer_1 und counter 15
2025.03.18 13:01:50 0: di_TestEvents_DOIF timerBlock timer_1 und counter 16
2025.03.18 13:02:00 0: di_TestEvents_DOIF timerBlock timer_1 und counter 17
2025.03.18 13:02:10 0: di_TestEvents_DOIF timerBlock timer_1 und counter 18
2025.03.18 13:02:20 0: di_TestEvents_DOIF timerBlock timer_1 und counter 19
2025.03.18 13:02:30 0: di_TestEvents_DOIF timerBlock timer_1 und counter 20

Sprich: Der komplette Block testBlock wird nie ausgeführt.

Mache ich aus dem DOIF eine Kombination mit Dummy:
defmod di_TestEvents_DOIF DOIF testBlock {\
fhem("set $SELF testBlockTriggered ".([?$SELF:testBlockTriggered]+1));;\
if([$SELF:event1] eq "gerade")\
{\
Log(0, "$SELF testBlock $EVENT");; \
}\
elsif([$SELF:event2] eq "gerade")\
{\
Log(0, "$SELF testBlock $EVENT");; \
}\
else\
{\
Log(0, "$SELF testBlock $EVENT");; \
}\
}\
\
testBlock_dmy {\
fhem("set $SELF testBlockDmyTriggered ".([?$SELF:testBlockDmyTriggered]+1));;\
if([dmy_TestEvents_DUMMY:event1] eq "gerade")\
{\
Log(0, "$SELF testBlock_dmy $EVENT");; \
}\
elsif([dmy_TestEvents_DUMMY:event2] eq "gerade")\
{\
Log(0, "$SELF testBlock_dmy $EVENT");; \
}\
else\
{\
Log(0, "$SELF testBlock_dmy $EVENT");; \
}\
}\
\
timerBlock {\
fhem("set $SELF timerBlockTriggered ".([?$SELF:timerBlockTriggered]+1));;\
if([+00:00:10]) {\
fhem("set $SELF counter ".([?$SELF:counter] + 1));;\
Log(0, "$SELF timerBlock $EVENT und counter ".[?$SELF:counter]);;\
}\
if([?$SELF:counter] % 2) {\
fhem("set dmy_TestEvents_DUMMY event1 ungerade");;\
}\
else {\
fhem("set dmy_TestEvents_DUMMY event1 gerade");;\
}\
if(([?$SELF:counter] + 1) % 2) {\
fhem("set dmy_TestEvents_DUMMY event2 ungerade");;\
}\
else {\
fhem("set dmy_TestEvents_DUMMY event2 gerade");;\
}\
}
attr di_TestEvents_DOIF DOIF_Readings event2:{if(([$SELF:counter]+1) % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF DbLogExclude .*
attr di_TestEvents_DOIF event_Readings event1:{if([$SELF:counter] % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF readingList counter testBlockTriggered timerBlockTriggered testBlockDmyTriggered
attr di_TestEvents_DOIF setList counter:0 timerBlockTriggered:0 testBlockTriggered:0 testBlockDmyTriggered:0

defmod dmy_TestEvents_DUMMY dummy
attr dmy_TestEvents_DUMMY DbLogExclude .*
attr dmy_TestEvents_DUMMY event-on-change-reading .*
attr dmy_TestEvents_DUMMY readingList event1 event2
attr dmy_TestEvents_DUMMY setList event1:0 event2:0

Dann bekomme ich:
2025.03.18 13:20:11 0: di_TestEvents_DOIF timerBlock timer_1 und counter 126
2025.03.18 13:20:11 0: di_TestEvents_DOIF testBlock_dmy event1: gerade
2025.03.18 13:20:11 0: di_TestEvents_DOIF testBlock event2: ungerade
2025.03.18 13:20:11 0: di_TestEvents_DOIF testBlock_dmy event2: ungerade
2025.03.18 13:20:21 0: di_TestEvents_DOIF timerBlock timer_1 und counter 127
2025.03.18 13:20:21 0: di_TestEvents_DOIF testBlock_dmy event1: ungerade
2025.03.18 13:20:21 0: di_TestEvents_DOIF testBlock event2: gerade
2025.03.18 13:20:21 0: di_TestEvents_DOIF testBlock_dmy event2: gerade
2025.03.18 13:20:31 0: di_TestEvents_DOIF timerBlock timer_1 und counter 128
2025.03.18 13:20:31 0: di_TestEvents_DOIF testBlock_dmy event1: gerade
2025.03.18 13:20:31 0: di_TestEvents_DOIF testBlock event2: ungerade
2025.03.18 13:20:31 0: di_TestEvents_DOIF testBlock_dmy event2: ungerade
????

Warum triggert im ersten Falls nichts außer der Timer und im zweiten zwar der "dummy", aber innerhalb des DOIF nur event2?

Kanns nicht besser ausdrücken und hoffe das Beispiel genügt?
In der Doku hatte ich noch was mit Selbsttriggerung gelesen, gibt es aber im Perl Modus nicht - zumal über DOIF-Readings oder Event-Readings ja ausgelöst werden sollte?

Danke im voraus,
Tobi
FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

Otto123

#1
Hallo Tobi,

hat es was damit zu tun?

https://fhem.de/commandref_DE.html#setreading

Sprich das setzen eigener Readings erzeugen sicherheitshalber keine Events?
Dann könnte vor dem fraglichen set ein sleep 0.1; helfen.

Aber kann sein ich überblicke das Konstrukt nicht. ;)

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

tobi01001

Zitat von: Otto123 am 18 März 2025, 18:10:42Hallo Tobi,

hat es was damit zu tun?

https://fhem.de/commandref_DE.html#setreading

Sprich das setzen eigener Readings erzeugen sicherheitshalber keine Events?
Dann könnte vor dem fraglichen set ein sleep 0.1; helfen.

Aber kann sein ich überblicke das Konstrukt nicht. ;)

Gruß Otto

Hi Otto,
danke für die Rückmeldung. Das habe ich mir angeschaut. Der einzige set-Befehl im Konstukt ist ja der counter im timerBlock. Dem habe ich sleep 1; spendiert. (das wäre aber auch deterministisch ;-)).

Dann sehe ich im Event-Monitor z.B.:
2025-03-18 20:06:29 DOIF di_TestEvents_DOIF timerBlockTriggered: 923
2025-03-18 20:06:30 DOIF di_TestEvents_DOIF counter: 924
2025-03-18 20:06:30 DOIF di_TestEvents_DOIF event2: ungerade
2025-03-18 20:06:30 DOIF di_TestEvents_DOIF event1: gerade
2025-03-18 20:06:39 DOIF di_TestEvents_DOIF timerBlockTriggered: 924
2025-03-18 20:06:40 DOIF di_TestEvents_DOIF counter: 925
2025-03-18 20:06:40 DOIF di_TestEvents_DOIF event2: gerade
2025-03-18 20:06:40 DOIF di_TestEvents_DOIF event1: ungerade
Aber im Log (das Konstrukt schreibt eig. nur ins Log um das Verhalten zu verifizieren):
2025.03.18 20:06:29 0: di_TestEvents_DOIF timerBlock timer_1 und counter 923
2025.03.18 20:06:39 0: di_TestEvents_DOIF timerBlock timer_1 und counter 924
2025.03.18 20:06:49 0: di_TestEvents_DOIF timerBlock timer_1 und counter 925
sleep verzögert, ändert aber darüber hinaus nichts am Verhalten.

Eigentlich sollten die Event-Readings und/oder UserReadings das DOIF triggern können (so auch vielfältig in der Doku / Wiki).
Die Event-Readings funktionieren auch (siehe Event-Monitor), lösen aber den DOIF-Block nicht aus. Seltsamerweise landet auch das DOIF-Reading event2 im Event-Monitor obwohl es doch laut Doku keine externen Events auslösen sollte...

Jedenfalls, wenn ich einen block hinzufüge, der von einem dummy getriggert wird (und der dummy aus dem DOIF-heraus beschrieben), funktioniert dieser Block problemlos - sprich: events des dummy's triggern den DOIF-Block. - soweit so deterministisch.
Aber: Ohne etwas anderes zu ändern, wird plötzlich auch der erste Block getriggert, aber nur vom DOIF-Reading event2... Und das erschließt sich mir ganz und gar nicht.

2025.03.18 20:29:08 0: di_TestEvents_DOIF testBlock_dmy event2: ungerade
2025.03.18 20:29:18 0: di_TestEvents_DOIF timerBlock timer_1 und counter 1059
2025.03.18 20:29:18 0: di_TestEvents_DOIF testBlock_dmy event1: ungerade
----->   2025.03.18 20:29:18 0: di_TestEvents_DOIF testBlock event2: gerade
2025.03.18 20:29:18 0: di_TestEvents_DOIF testBlock_dmy event2: gerade
2025.03.18 20:29:28 0: di_TestEvents_DOIF timerBlock timer_1 und counter 1060
2025.03.18 20:29:28 0: di_TestEvents_DOIF testBlock_dmy event1: gerade
----->   2025.03.18 20:29:28 0: di_TestEvents_DOIF testBlock event2: ungerade
2025.03.18 20:29:28 0: di_TestEvents_DOIF testBlock_dmy event2: ungerade
2025.03.18 20:29:38 0: di_TestEvents_DOIF timerBlock timer_1 und counter 1061
2025.03.18 20:29:38 0: di_TestEvents_DOIF testBlock_dmy event1: ungerade
----->   2025.03.18 20:29:38 0: di_TestEvents_DOIF testBlock event2: gerade
2025.03.18 20:29:38 0: di_TestEvents_DOIF testBlock_dmy event2: gerade

Gruß,
Tobi

P.S.: Das Konstrukt ist nur zum Nachstellen des "Problems". Hier ist das in einer etwas (teilweise unnötig) viel komplexeren Berechnung ob und wann ich denn den PV-Start der Wärmepumpe aktiviere. Und nachdem der irgendwie nach Sonnenuntergang bei leerer Batterie noch aktiv war bin ich etwas stutzig aber leider nicht selbst fündig geworden.....
FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

Damian

Das sieht mir nach einer Rekursion aus:

DOIF_Readings_events:
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#     DOIF_Readings_eventsState:
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade
#       event2: gerade
#       event2: ungerade

Es ist in FHEM immer problematisch auf eigene Events zu reagieren.

Ich habe DOIF_Readings programmiert, die ohne Events funktionieren, diese rufen intern im DOIF die Hauptroutine auf.

Kannst du mal damit probieren.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

tobi01001

Zitat von: Damian am 18 März 2025, 20:48:48Das sieht mir nach einer Rekursion aus:

DOIF_Readings_events:
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#    DOIF_Readings_eventsState:
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade
#      event2: gerade
#      event2: ungerade

Es ist in FHEM immer problematisch auf eigene Events zu reagieren.

Ich habe DOIF_Readings programmiert, die ohne Events funktionieren, diese rufen intern im DOIF die Hauptroutine auf.

Kannst du mal damit probieren.


Danke, das sind soo viele, weil ich die mit Timer im 10 Sekundentakt wechseln lasse... nur um das "Problem" nachzustellen". Wenn ich das DOIF nach zwei timern anhalte, sind da auch nur zwei Werte drin.

event1 ist ein event-Reading, event2 ist ein DOIF-Reading:
attr di_TestEvents_DOIF DOIF_Readings event2:{if(([$SELF:counter]+1) % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF event_Readings event1:{if([$SELF:counter] % 2) { "ungerade";; } else {"gerade";;} }
Wüsste auch nicht, wo da die rekursion sein sollte. Der counter (readingList im DOIF) wird im timerBlock alle 10 sekunden inkrementiert. Die counter-Änderung triggert die DOIF/event-Readings und die werden (samt event im Eventmonitor) geschrieben / geändert.

Ich hätte jetzt erwartet, dass diese den ersten DOIF block (testBlock) triggern und daurch irgendwas im Log landet. Das passiert aber nicht.

Baue ich neben den TestBlock einen zweiten Block ein, der auf einen dummy triggert, funktioniert das wunderbar und event2 löst den ersten Block (testBlock) aus - siehe erster Beitrag.


In der einfachsten Form (in der nur der timerBlock und testBlock sind) kannst du das gerne mal probieren:
defmod di_TestEvents_DOIF DOIF testBlock {\
    fhem("set $SELF testBlockTriggered ".([?$SELF:testBlockTriggered]+1));;\
    Log(0, "$SELF testBlock $DEVICE $EVENT");;    \
    if([$SELF:event1] eq "gerade")\
    {\
        Log(0, "$SELF testBlock if $DEVICE $EVENT");;    \
    }\
    elsif([$SELF:event2] eq "gerade")\
    {\
        Log(0, "$SELF testBlock elseif $DEVICE $EVENT");;    \
    }\
    else\
    {\
        Log(0, "$SELF testBlock else $DEVICE $EVENT");;    \
    }\
}\
\
timerBlock {\
    fhem("set $SELF timerBlockTriggered ".([?$SELF:timerBlockTriggered]+1));;\
    Log(0, "$SELF timerBlock $DEVICE $EVENT");;\
    if([+00:00:10]) {\
        fhem("sleep 1;; set $SELF counter ".([?$SELF:counter] + 1));;\
        Log(0, "$SELF timerBlock $DEVICE $EVENT und counter ".[?$SELF:counter]);;\
    }\
}
attr di_TestEvents_DOIF DOIF_Readings event2:{if(([$SELF:counter]+1) % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF event_Readings event1:{if([$SELF:counter] % 2) { "ungerade";; } else {"gerade";;} }
attr di_TestEvents_DOIF readingList counter testBlockTriggered timerBlockTriggered testBlockDmyTriggered

setstate di_TestEvents_DOIF 2025-03-18 22:41:56 counter 0
setstate di_TestEvents_DOIF 2025-03-18 22:39:06 testBlockTriggered 0
setstate di_TestEvents_DOIF 2025-03-18 22:41:55 timerBlockTriggered 0

Das Verhalten mit dem zusätzlichen dummy gibts im ersten Beitrag.

Ich möchte nur verstehen was da passiert und warum (bzw warum nicht). Trifft das nur den perl modus? Passiert das auch im DOIF-Modus? Oder passiert das gar nur bei mir?

Dann könnte ich meine DOIFs durchsuchen und schauen ob das auch woanders zu "Problemen" führen kann.
FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

Damian

Ich werde das Beispiel mit DOIF_Readings bei mir ausprobieren, wenn ich zuhause bin.

Allerdings hast du programmiert:


DOIF setzt counter
DOIF reagiert auf counter und setzt event
DOIF reagiert auf event

alleine die Tatsache, dass man im gleichen Modul ein Event erzeugt, auf das man selbst reagiert ist grundsätzlich in FHEM schon problematisch (ich weiß ja, dass du es per sleep bereits versucht hast zu entkoppeln)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

tobi01001

Zitat von: Damian am 19 März 2025, 12:12:42alleine die Tatsache, dass man im gleichen Modul ein Event erzeugt, auf das man selbst reagiert ist grundsätzlich in FHEM schon problematisch
Ja, aber ist das nicht die "ureigene Funktion der DOIF-Readings (und evtl. event-Readings mit Trigger nach außen)?

Der counter ist nur zum Nachstellen - vielleicht nicht optimal gewählt. Im eigentlichen Quelldevice setze ich nichts in der DOIF DEF sondern lediglich Event-Readings auf die das DOIF triggern soll.

Danke schonmal fürs nachschauen. Probier gerne auch mal die Ergänzung mit dem Dummy Device und dem zusätzlichen Dummy-Block aus dem ersten Beitrag aus, da dieser wie gesagt nochmal ein "separates" Verhalten hervorruft.
FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

Damian

#7
Ich glaube, das Problem ist, dass von der Idee her event_Readings bzw. DOIF_Readings dazu gedacht sind auf externe Events zu reagieren und diese dann im Anschluss in den eigentlichen DOIF-Blöcken zu nutzen und nicht umgekehrt. In dieser Reihenfolge erfolgt auch die Abfrage intern.

Bei dir entsteht das Event im DOIF-Block, auf das du in event_Reading bzw. DOIF_Reading reagieren willst, also genau umgekehrt - das funktioniert nicht.

Eventuell würde es mit user_Readings gehen. Wenn FHEM nicht dazwischen funkt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

tobi01001

OK, das ist dann doch etwas komplexer als gedacht....

Mein Problem liegt ja nicht darin, im DOIF selbst die Trigger auszulösen, sondern in den Event-Readings bzw. DOIF-Readings, die im DOIF etwas auslösen sollen. Und da hatte ich eben "kaskadierte" Readings, also welche die durch andere Event-Readings oder DOIF-Readings getriggert und berechnet werden sollten.

Folgendes Verhalten:
Die Readings werden allesamt immer berechnet, d.h. als solche auch getriggert. Es lösen nur nicht alle einen entsprechenden DOIF-Block aus.


Ein Event-Reading oder DOIF-Reading mit externen trigger wie:
attr DOIF_dev DOIF_Readings DIRextTrg:{([extdev:extread])},
attr DOIF_devevent_Readings EVRextTrg:{([extdev:extread])},
werden immer getriggert.

Ein Kaskade solcher, also z.B.:
attr DOIF_dev DOIF_Readings DIRextTrg:{([extdev:extread])},
attr DOIF_dev DOIF_Readings DIRintTrg:{([$SELF:DIRextTrg])},
attr DOIF_devevent_Readings EVRextTrg:{([extdev:extread])},
attr DOIF_devevent_Readings EVRintTrg:{([$SELF:EVRextTrg])},
wird zwar berechnet, löst aber den DOIF-Block nicht aus.

ZitatDOIF-Readings (wenn kaskadiert) haben noch die Eigenheit, dass sie nach einer Sekunde zum vorherigen aktualisiert werden.

userReadings funktionieren in soweit zuverlässig, dass sie sich gegenseitig triggern können und ihrerseits auch den DOIF-Block auslösen.
Allerdings funktioniert das nur solange wie ein userReading nicht zwischenzeitlich (Reihenfolge in der Definition) durch ein Eventreading / DOIF-Reading berechnet werden soll. Ist das der Fall, wird das entsprechende userReading noch berechnet, das darauffolgende allerdings nicht.

Mit Ausnahme des vorherigen, lösen userReadings innerhalb eines DOIFs zuverlässig aus. Sie werden dabei gemeinsam als ein Event als trigger verwendet, sprich DEVICE: userReading1: xy, userReading 2: xy,...

In einem notify funktionieren die userReadings ebvenfalls wie erwartet. Im Unterschied zu DOIF werden hier mehrere Events erzeugt (für jedes Reading einzeln).

Meine Aufgabe besteht jetzt darin, alle DOIF-Device Definitionen durchzugehen und zu schauen, wo ich auf kaskadierte DOIF-Readsings oder Event-Readings reagieren muss. Diese gilt es zu korrigieren (entweder DOIF oder notify oder wenn hinreichend komplex evtl. auch myUtils...

Das Verhalten fällt übrigens dann nicht direkt auf, wenn man mehr als einen Trigger hat.....

Danke für die Mühe,
Tobias

P.S.: Falls das jemand nachbauen möchte (schreibt dir dann das Log dann voll - also das timer DOIF nach ein paar durchläufen wieder beenden), findest ihr hier die raw definition - der timer muss dann enabled werden:
defmod di_TestEventsCounter DOIF counter \
{\
if([+00:00:10]) \
{\
Log(0, "\n\t$SELF triggered:\n");;\
fhem("set $SELF counter ".((ReadingsNum("$SELF", "counter",0)+1) % 100));;\
fhem("sleep 1;; set $SELF counterEV ".ReadingsNum("$SELF", "counter",0));;\
fhem("sleep 2;; set $SELF counterDI ".ReadingsNum("$SELF", "counter",0));;\
fhem("sleep 3;; set $SELF counterUS ".ReadingsNum("$SELF", "counter",0));;\
fhem("sleep 4;; set $SELF counterUSDOIF ".ReadingsNum("$SELF", "counter",0));;\
fhem("sleep 5;; set $SELF counterUSNotify ".ReadingsNum("$SELF", "counter",0));;\
}\
}
attr di_TestEventsCounter event-on-change-reading .*
attr di_TestEventsCounter readingList counter counterEV counterDI counterUS counterUSDOIF counterUSNotify
attr di_TestEventsCounter room testDIEvents
attr di_TestEventsCounter webCmd enable disable
defmod di_TestEvents_DOIF DOIF DIReadingTrigger {\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tDIReadingTrigger:\n\t\t\t".$text);;\
if([$SELF:DIreading_external_trigger] or [$SELF:DIreading_DIreading_trigger] or [$SELF:DIreading_eventReading_trigger])\
{\
\
}\
}\
EVReadingTrigger {\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tEVReadingTrigger:\n\t\t\t".$text);;\
if([$SELF:eventReading_eventReading_trigger] or [$SELF:eventReading_external_trigger] or [$SELF:eventReading_DIreading_trigger])\
{\
}\
}\
UserReadingTrigger {\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tUserReadingTrigger:\n\t\t\t".$text);;\
if([$SELF:userReading_extToInt_trigger] or [$SELF:userReading_userReading_trigger] or [$SELF:userReading_DOIFReading_trigger] or [$SELF:userReading_eventReading_trigger])\
{\
}\
}\
userReadingExtToIntTrg {\
if([di_TestEventsCounter:counter])\
{}\
my $cnt = ([$SELF:userTrgCount,0] + 1) % 9;;\
fhem("set $SELF userTrgCount $cnt");;\
}
attr di_TestEvents_DOIF DOIF_Readings DIreading_external_trigger:{([di_TestEventsCounter:counter])},\
DIreading_DIreading_trigger:{([$SELF:DIreading_external_trigger])},\
DIreading_eventReading_trigger:{([$SELF:eventReading_eventReading_trigger])},
attr di_TestEvents_DOIF event_Readings eventReading_external_trigger:{([di_TestEventsCounter:counter]) },\
eventReading_eventReading_trigger:{([$SELF:eventReading_external_trigger])},\
eventReading_DIreading_trigger:{([$SELF:DIreading_DIreading_trigger])},
attr di_TestEvents_DOIF readingList userTrgCount
attr di_TestEvents_DOIF room testDIEvents
attr di_TestEvents_DOIF userReadings userReading_extToInt_trigger:userTrgCount.* {ReadingsVal("di_TestEventsCounter", "counter", 0);; },\
userReading_userReading_trigger:userReading_extToInt_trigger.* {ReadingsVal("$name", "userReading_extToInt_trigger", 0);;},\
userReading_cascade1:userReading_userReading_trigger.* {ReadingsVal("$name", "userReading_userReading_trigger", 0);;},\
userReading_cascade2:userReading_cascade1.* {ReadingsVal("$name", "userReading_cascade1", 0);;},\
userReading_eventReading_trigger:eventReading_external_trigger.*{ReadingsVal("$name", "eventReading_external_trigger", 0);;},\
userReading_DOIFReading_trigger:DIreading_external_trigger.*{ReadingsVal("$name", "DIreading_external_trigger", 0);;},\
userReading_cascade3:userReading_cascade2.* {ReadingsVal("$name", "userReading_cascade2", 0);;},
defmod di_TestEvents_DI DOIF ([$SELF:DIreading_external_trigger] or [$SELF:DIreading_DIreading_trigger] or [$SELF:DIreading_eventReading_trigger]) ( { \
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tDIReadingTrigger:\n\t\t\t".$text);;\
})
attr di_TestEvents_DI DOIF_Readings DIreading_external_trigger:{([di_TestEventsCounter:counterDI])},\
DIreading_DIreading_trigger:{([$SELF:DIreading_external_trigger])},\
DIreading_cascade_1:{([$SELF:DIreading_DIreading_trigger])},\
DIreading_cascade_2:{([$SELF:DIreading_cascade_1])},\
DIreading_cascade_3:{([$SELF:DIreading_cascade_2])},
attr di_TestEvents_DI room testDIEvents

defmod di_TestEvents_EV DOIF EVReadingTrigger {\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tEVReadingTrigger:\n\t\t\t".$text);;\
if([$SELF:eventReading_eventReading_trigger] or [$SELF:eventReading_external_trigger] or [$SELF:eventReading_DIreading_trigger])\
{\
}\
else\
{\
}\
}
attr di_TestEvents_EV event_Readings eventReading_external_trigger:{([di_TestEventsCounter:counterEV]) },\
eventReading_eventReading_trigger:{([$SELF:eventReading_external_trigger])},
attr di_TestEvents_EV room testDIEvents

defmod di_TestEvents_EV DOIF EVReadingTrigger {\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tEVReadingTrigger:\n\t\t\t".$text);;\
if([$SELF:eventReading_eventReading_trigger] or [$SELF:eventReading_external_trigger] or [$SELF:eventReading_DIreading_trigger])\
{\
}\
}
attr di_TestEvents_EV event_Readings eventReading_external_trigger:{([di_TestEventsCounter:counterEV]) },\
eventReading_eventReading_trigger:{([$SELF:eventReading_external_trigger])},
attr di_TestEvents_EV room testDIEvents
defmod di_TestEvents_UserReadings DOIF UserReadingTrigger {\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tUserReadingTrigger:\n\t\t\t".$text);;\
if([$SELF:userReading_extToInt_trigger] or [$SELF:userReading_userReading_trigger] or [$SELF:userReading_DOIFReading_trigger] or [$SELF:userReading_eventReading_trigger])\
{\
}\
}\
userReadingExtToIntTrg {\
if([di_TestEventsCounter:counterUSDOIF])\
{}\
else\
{}\
my $cnt = [$SELF:userTrgCount,0] + 1;;\
fhem("set $SELF userTrgCount $cnt");;\
}
attr di_TestEvents_UserReadings readingList userTrgCount
attr di_TestEvents_UserReadings room testDIEvents
attr di_TestEvents_UserReadings userReadings userReading_extToInt_trigger:userTrgCount.* {ReadingsVal("di_TestEventsCounter", "counterUSDOIF", 0);; },\
userReading_userReading_trigger:userReading_extToInt_trigger.* {ReadingsVal("$name", "userReading_extToInt_trigger", 0);;},\
userReading_cascade1:userReading_userReading_trigger.* {ReadingsVal("$name", "userReading_userReading_trigger", 0);;},\
userReading_cascade2:userReading_cascade1.* {ReadingsVal("$name", "userReading_cascade1", 0);;},\
userReading_cascade3:userReading_cascade2.* {ReadingsVal("$name", "userReading_cascade2", 0);;},

defmod no_TestEvents_UserReadings notify di_TestEventsCounter:counterUSNotify.*|no_TestEvents_UserReadings:.* \
{\
if("$NAME" eq "di_TestEventsCounter")\
{ \
my $cnt = (ReadingsNum("$SELF", "userTrgCount",0 ) + 1) % 9;;\
fhem("set $SELF userTrgCount $cnt");;\
}\
if("$NAME" eq "$SELF")\
{\
my $text = "$EVENT";;\
$text =~ s/,/\n\t\t\t/g;;\
Log(0, "$SELF \n\t\tUserReadingTrigger:\n\t\t\t".$text);;\
}\
}\

attr no_TestEvents_UserReadings room testDIEvents
attr no_TestEvents_UserReadings setList userTrgCount
attr no_TestEvents_UserReadings userReadings userReading_extToInt_trigger:userTrgCount.* {ReadingsVal("di_TestEventsCounter", "counterUS", 0);;},\
userReading_userReading_trigger:userReading_extToInt_trigger.* {ReadingsVal("$name", "userReading_extToInt_trigger", 0);; },\
userReading_cascade1:userReading_userReading_trigger.* {ReadingsVal("$name", "userReading_userReading_trigger", 0);;},\
userReading_cascade2:userReading_cascade1.* {ReadingsVal("$name", "userReading_cascade1", 0);;},\
userReading_cascade3:userReading_cascade2.* {ReadingsVal("$name", "userReading_cascade2", 0);;},
set di_TestEventsCounter  disable

FHEM@UbuntuServer on Lenovo ThinkCentre M900 [i5-6500T / 8GB RAM] MySQL-DbLog, Grafana, FTUI3 / HmIP incl. CCU3 / LGESS / Wärempumpe über TA CMI und CANoE / Shellies u.v.m.

Damian

Es ist gut, dass man es reproduzieren kann. Wenn ich etwas Zeit finde, dann kann ich schauen, ob ich das Problem beheben kann.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF