[Gelöst] DOIF schaltet manchmal nicht

Begonnen von petermiller, 28 Dezember 2018, 14:40:16

Vorheriges Thema - Nächstes Thema

petermiller

Hallo,
Zu einer Bestimmten Uhrzeit (at) wird Funksteckdose3 eingeschaltet, dann über DOIF mit wait 5 Sekunden Funksteckdose2 eingeschaltet und zum Schluss über DOIF mit wait 5 Sekunden Funksteckdose1 eingeschaltet.
Wenn das Licht im Gästezimmer ausgeschaltet wird, sollen nach 5 Sekunden Funksteckdose3, dann nach 5 Sekunden Funksteckdose2 und zum Schluss nach 5 Sekunden Funksteckdose1 ausgeschaltet werden. Dies habe ich durch drei weitere DOIF Einträge gelöst. Das funktioniert auch, wenn die Funksteckdosen eingeschaltet waren.
Sind alle 3 Funksteckdosen jedoch ausgeschaltet, bewirkt ein ausschalten des Lichts im Gästezimmer nur das (nochmalige) ausschalten der Funksteckdose3. Ein Schaltbefehl für Funksteckdose2 und Funksteckdose1 wird nicht erzeugt. Warum ist das so?

Anbei die fhem.cfg Definitionen und die Auszeichnungen des Event Monitors

Hier die DOIF Definitionen:
define Funksteckdose1_an DOIF ([Funksteckdose2:"on"]) (set Funksteckdose1 on)
attr Funksteckdose1_an room Weihnachten
attr Funksteckdose1_an timerWithWait 1
attr Funksteckdose1_an wait 5
define Funksteckdose1_aus DOIF ([Funksteckdose2:"off"]) (set Funksteckdose1 off)
attr Funksteckdose1_aus room Weihnachten
attr Funksteckdose1_aus timerWithWait 1
attr Funksteckdose1_aus wait 5

define Funksteckdose2_an DOIF ([Funksteckdose3:"on"]) (set Funksteckdose2 on)
attr Funksteckdose2_an room Weihnachten
attr Funksteckdose2_an timerWithWait 1
attr Funksteckdose2_an wait 5
define Funksteckdose2_aus DOIF ([Funksteckdose3:"off"]) (set Funksteckdose2 off)
attr Funksteckdose2_aus room Weihnachten
attr Funksteckdose2_aus timerWithWait 1
attr Funksteckdose2_aus wait 5

define Funksteckdose3_an at *{randomtime("16,30,29")} set Funksteckdose3 on
attr Funksteckdose3_an room Weihnachten
define Funksteckdose3_aus DOIF ([Lampe_GZ:"off"]) (set Funksteckdose3 off)
attr Funksteckdose3_aus room Weihnachten
attr Funksteckdose3_aus timerWithWait 1
attr Funksteckdose3_aus wait 5

Event Monitor Ausgabe bei eingeschaltenen Funksteckdosen:
2018-12-28 14:29:20 CUL_TCM97001 NC_WS_93 temperature: 3.7
2018-12-28 14:29:20 CUL_TCM97001 NC_WS_93 T: 3.7 H: 23
2018-12-28 14:29:20 DOIF Funksteckdose3_aus wait_timer: 28.12.2018 14:29:25 cmd_1 Lampe_GZ
2018-12-28 14:29:20 IT Lampe_GZ off
2018-12-28 14:29:20 CUL CUL868 raw: isxxxxxxxxxxxx
2018-12-28 14:29:25 DOIF Funksteckdose3_aus wait_timer: no timer
2018-12-28 14:29:25 DOIF Funksteckdose2_an cmd_nr: 2
2018-12-28 14:29:25 DOIF Funksteckdose2_an cmd: 2
2018-12-28 14:29:25 DOIF Funksteckdose2_an cmd_event: Funksteckdose3
2018-12-28 14:29:25 DOIF Funksteckdose2_an cmd_2
2018-12-28 14:29:25 DOIF Funksteckdose2_aus wait_timer: 28.12.2018 14:29:30 cmd_1 Funksteckdose3
2018-12-28 14:29:25 IT Funksteckdose3 off
2018-12-28 14:29:25 CUL CUL868 raw: isxxxxxxxxxx0101010110011111000000
2018-12-28 14:29:25 DOIF Funksteckdose3_aus cmd_nr: 1
2018-12-28 14:29:25 DOIF Funksteckdose3_aus cmd: 1
2018-12-28 14:29:25 DOIF Funksteckdose3_aus cmd_event: Lampe_GZ
2018-12-28 14:29:25 DOIF Funksteckdose3_aus cmd_1
2018-12-28 14:29:30 DOIF Funksteckdose2_aus wait_timer: no timer
2018-12-28 14:29:30 DOIF Funksteckdose1_an cmd_nr: 2
2018-12-28 14:29:30 DOIF Funksteckdose1_an cmd: 2
2018-12-28 14:29:30 DOIF Funksteckdose1_an cmd_event: Funksteckdose2
2018-12-28 14:29:30 DOIF Funksteckdose1_an cmd_2
2018-12-28 14:29:30 DOIF Funksteckdose1_aus wait_timer: 28.12.2018 14:29:35 cmd_1 Funksteckdose2
2018-12-28 14:29:30 IT Funksteckdose2 off
2018-12-28 14:29:30 CUL CUL868 raw: isxxxxxxxxxx0101010110011110000000
2018-12-28 14:29:30 DOIF Funksteckdose2_aus cmd_nr: 1
2018-12-28 14:29:30 DOIF Funksteckdose2_aus cmd: 1
2018-12-28 14:29:30 DOIF Funksteckdose2_aus cmd_event: Funksteckdose3
2018-12-28 14:29:30 DOIF Funksteckdose2_aus cmd_1
2018-12-28 14:29:35 DOIF Funksteckdose1_aus wait_timer: no timer
2018-12-28 14:29:35 IT Funksteckdose1 off
2018-12-28 14:29:35 CUL CUL868 raw: isxxxxxxxxxx0101010110011100000000
2018-12-28 14:29:35 DOIF Funksteckdose1_aus cmd_nr: 1
2018-12-28 14:29:35 DOIF Funksteckdose1_aus cmd: 1
2018-12-28 14:29:35 DOIF Funksteckdose1_aus cmd_event: Funksteckdose2
2018-12-28 14:29:35 DOIF Funksteckdose1_aus cmd_1

Event Monitor Ausgabe bei ausgeschaltenen Funksteckdosen:
2018-12-28 14:32:15 DOIF Funksteckdose3_aus wait_timer: 28.12.2018 14:32:20 cmd_1 Lampe_GZ
2018-12-28 14:32:15 IT Lampe_GZ off
2018-12-28 14:32:16 CUL CUL868 raw: isxxxxxxxxxxxx
2018-12-28 14:32:20 DOIF Funksteckdose3_aus wait_timer: no timer
2018-12-28 14:32:20 IT Funksteckdose3 off
2018-12-28 14:32:21 CUL CUL868 raw: is00111100110101010110011111000000
2018-12-28 14:32:21 DOIF Funksteckdose3_aus cmd_nr: 1
2018-12-28 14:32:21 DOIF Funksteckdose3_aus cmd: 1
2018-12-28 14:32:21 DOIF Funksteckdose3_aus cmd_event: Lampe_GZ
2018-12-28 14:32:21 DOIF Funksteckdose3_aus cmd_1


KernSani

#1
Hi,
Bitte mal ein "list" der DOIFs und auch einer (nicht schaltenden Steckdose) und codetags (das # oben im Editor über den Emojis) verwenden Ich vermute aber mal stark: Du reagierst in den DOIFs auf Events. Wenn du z.B. bei der Steckdose3 ein "event-on-change-reading" gesetzt hast wird beim erneuten ausschalten einer bereits ausgeschalteten Steckdose kein Event erzeugt auf das das folgende DOIF reagieren könnte.
Grüße,
Oli
Edit: Ich würde das Ganze übrigens in einem DOIF lösen, mit mehreren Ausführungsblöcken und entsprechenden waits.
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

petermiller

#2
list Funksteckdose3_aus
Internals:
   DEF        ([Lampe_GZ:"off"]) (set Funksteckdose3 off)
   MODEL      FHEM
   NAME       Funksteckdose3_aus
   NR         102
   NTFY_ORDER 50-Funksteckdose3_aus
   STATE      cmd_1
   TYPE       DOIF
   READINGS:
     2018-12-28 14:32:15   Device          Lampe_GZ
     2018-12-28 14:32:21   cmd             1
     2018-12-28 14:32:21   cmd_event       Lampe_GZ
     2018-12-28 14:32:21   cmd_nr          1
     2018-12-28 14:32:15   e_Lampe_GZ_events off
     2018-12-28 11:38:59   mode            enabled
     2018-12-28 14:32:21   state           cmd_1
     2018-12-28 14:32:20   wait_timer      no timer
   Regex:
   attr:
     cmdState:
     wait:
       0:
         5
     waitdel:
   condition:
     0          ::EventDoIf('Lampe_GZ',$hash,'off',1)
   devices:
     0           Lampe_GZ
     all         Lampe_GZ
   do:
     0:
       0          set Funksteckdose3 off
     1:
   helper:
     event      off
     globalinit 1
     last_timer 0
     sleepdevice Lampe_GZ
     sleepsubtimer -1
     sleeptimer -1
     timerdev   Lampe_GZ
     timerevent off
     triggerDev Lampe_GZ
     DOIF_eventas:
       cmd_nr: 1
       cmd: 1
       cmd_event: Lampe_GZ
       state: cmd_1
     timerevents:
       off
     timereventsState:
       state: off
     triggerEvents:
       off
     triggerEventsState:
       state: off
   internals:
   itimer:
   perlblock:
   readings:
   trigger:
     all         Lampe_GZ
   uiState:
   uiTable:
Attributes:
   room       Weihnachten
   timerWithWait 1
   wait       5


list Funksteckdose2_aus
Internals:
   DEF        ([Funksteckdose3:"off"]) (set Funksteckdose2 off)
   MODEL      FHEM
   NAME       Funksteckdose2_aus
   NR         99
   NTFY_ORDER 50-Funksteckdose2_aus
   STATE      cmd_1
   TYPE       DOIF
   READINGS:
     2018-12-28 14:32:20   Device          Funksteckdose3
     2018-12-28 14:29:30   cmd             1
     2018-12-28 14:29:30   cmd_event       Funksteckdose3
     2018-12-28 14:29:30   cmd_nr          1
     2018-12-28 14:32:20   e_Funksteckdose3_events off
     2018-12-28 14:29:30   state           cmd_1
     2018-12-28 14:29:30   wait_timer      no timer
   Regex:
   attr:
     cmdState:
     wait:
       0:
         5
     waitdel:
   condition:
     0          ::EventDoIf('Funksteckdose3',$hash,'off',1)
   devices:
     0           Funksteckdose3
     all         Funksteckdose3
   do:
     0:
       0          set Funksteckdose2 off
     1:
   helper:
     event      off
     globalinit 1
     last_timer 0
     sleepdevice Funksteckdose3
     sleepsubtimer -1
     sleeptimer -1
     timerdev   Funksteckdose3
     timerevent off
     triggerDev Funksteckdose3
     DOIF_eventas:
       cmd_nr: 1
       cmd: 1
       cmd_event: Funksteckdose3
       state: cmd_1
     timerevents:
       off
     timereventsState:
       state: off
     triggerEvents:
       off
     triggerEventsState:
       state: off
   internals:
   itimer:
   perlblock:
   readings:
   trigger:
     all         Funksteckdose3
   uiState:
   uiTable:
Attributes:
   room       Weihnachten
   timerWithWait 1
   wait       5


list Funksteckdose1_aus
Internals:
   DEF        ([Funksteckdose2:"off"]) (set Funksteckdose1 off)
   MODEL      FHEM
   NAME       Funksteckdose1_aus
   NR         96
   NTFY_ORDER 50-Funksteckdose1_aus
   STATE      cmd_1
   TYPE       DOIF
   READINGS:
     2018-12-28 14:29:30   Device          Funksteckdose2
     2018-12-28 14:29:35   cmd             1
     2018-12-28 14:29:35   cmd_event       Funksteckdose2
     2018-12-28 14:29:35   cmd_nr          1
     2018-12-28 14:29:30   e_Funksteckdose2_events off
     2018-12-28 14:29:35   state           cmd_1
     2018-12-28 14:29:35   wait_timer      no timer
   Regex:
   attr:
     cmdState:
     wait:
       0:
         5
     waitdel:
   condition:
     0          ::EventDoIf('Funksteckdose2',$hash,'off',1)
   devices:
     0           Funksteckdose2
     all         Funksteckdose2
   do:
     0:
       0          set Funksteckdose1 off
     1:
   helper:
     event      off
     globalinit 1
     last_timer 0
     sleepdevice Funksteckdose2
     sleepsubtimer -1
     sleeptimer -1
     timerdev   Funksteckdose2
     timerevent off
     triggerDev Funksteckdose2
     DOIF_eventas:
       cmd_nr: 1
       cmd: 1
       cmd_event: Funksteckdose2
       state: cmd_1
     timerevents:
       off
     timereventsState:
       state: off
     triggerEvents:
       off
     triggerEventsState:
       state: off
   internals:
   itimer:
   perlblock:
   readings:
   trigger:
     all         Funksteckdose2
   uiState:
   uiTable:
Attributes:
   room       Weihnachten
   timerWithWait 1
   wait       5


list Funksteckdose2
Internals:
   DEF        xxxxxxxxxxxx01010110011110 0 0000
   IODev      CUL868
   NAME       Funksteckdose2
   NR         25
   STATE      on
   TYPE       IT
   XMIT       xxxxxxxxxxxx0101011001111000000
   XMITdimdown 00
   XMITdimup  00
   XMIToff    0
   XMITon     1
   CODE:
     1          xxxxxxxxxxxx0101011001111000000
   READINGS:
     2018-01-17 11:15:44   group           0
     2018-01-17 11:15:44   protocol        V3
     2018-12-28 16:32:51   state           on
     2018-01-17 11:15:44   unit            0000
Attributes:
   IODev      CUL868
   room       Weihnachten

Damian

DOIF arbeitet mit Zuständen. Deine Definitionen haben nur einen Zustand, daher musst du das Attribut do always setzen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Frank_Huber

Zitat von: Damian am 28 Dezember 2018, 17:05:36
DOIF arbeitet mit Zuständen. Deine Definitionen haben nur einen Zustand, daher musst du das Attribut do always setzen.
Du hattest doch vor einer Weile in einem anderen Thread erwähnt dass das bei Einzeilern intern automatisch gesetzt wird?...?

Gesendet von meinem Doogee S60 mit Tapatalk


Damian

#5
Zitat von: Frank_Huber am 28 Dezember 2018, 17:13:30
Du hattest doch vor einer Weile in einem anderen Thread erwähnt dass das bei Einzeilern intern automatisch gesetzt wird?...?

Gesendet von meinem Doogee S60 mit Tapatalk

Es gibt Zustandsabfragen: [bla] eq "on"

und es gibt Ereignisabfragen: [bla:"on"] ["bla:on"]

Das hier ist eine Ereignisabfrage, sie kann immer nur wahr sein, wenn sie getriggert wird, daher kann niemals der Zustand cmd2 vorkommen, während im ersten Beispiel bei bla gleich off ein Zustandswechsel in cmd2 erfolgt.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Frank_Huber

Zitat von: Damian am 28 Dezember 2018, 17:31:49
Es gibt Zustandsabfragen: [bla] eq "on"
und es gibt Ereignisabfragen: [bla:"on"]
Das hier ist eine Ereignisabfrage, sie kann immer nur wahr sein, wenn sie getriggert wird, daher kann niemals der Zustand cmd2 vorkommen, während im ersten Beispiel bei bla gleich off ein Zustandswechsel in cmd2 erfolgt.
das ist klar, aber benötigt man für diese Art "Einzeiler" das do always?

Damian

#7
Zitat von: Frank_Huber am 28 Dezember 2018, 17:38:18
das ist klar, aber benötigt man für diese Art "Einzeiler" das do always?
Man muss es genauer unterscheiden, es kommt auf die genaue Definition an (ich habe meine Erklärung vorhin auf Fall 3 bezogen):
1. Fall
DOIF ([bla] eq "on") (set test on)

2. Fall
DOIF ([bla:"on"]) (set test on)

3. Fall
DOIF (["bla:on"]) (set test on)

folgende Events kommen:

bla: on -> 1., 2. , 3. schalten test on
bla: on -> keiner schaltet test on, da alle drei Definitionen bereits in cmd1 und ohne do always keine Wiederholung möglich
bla: off -> 1., 2., wechseln in cmd2, 3. macht nichts, weil es nur auf "on" reagiert und auf keine anderen Events im Gegensatz zu 1. und 2.
bla: off -> keiner macht etwas, da 1. und 2. bereits in cmd2 und 3. reagiert nur bei "on"
bla: on -> 1.,2., schalten test on, 3. macht nichts weil es cmd1 nicht verlassen hat und ohne do always keine Wiederholung möglich

Bei solchen Definitionen:

([Lampe_GZ:"off"]) (set Funksteckdose3 off)

will man meistens bei jedem Event "off" schalten (entspricht Fall 2) und nicht erst warten bis zwischendurch Lampe_GZ ein anderes Event geliefert hat, damit das Modul den Zustand in cmd2 wechseln konnte und wieder für cmd1 bereit ist.

daher do always.

Edit: Wenn keine zyklisch sendenden Sensoren abgefragt werden, ist do always in allen obigen Fällen sinnvoll (im 3. Fall sogar ein Muss!)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Frank_Huber



Zitat von: Damian am 28 Dezember 2018, 18:25:13
Man muss es genauer unterscheiden, es kommt auf die genaue Definition an (ich habe meine Erklärung vorhin auf Fall 3 bezogen):
1. Fall
DOIF ([bla] eq "on") (set test on)

2. Fall
DOIF ([bla:"on"]) (set test on)

3. Fall
DOIF (["bla:on"]) (set test on)

folgende Events kommen:

bla: on -> 1., 2. , 3. schalten test on
bla: on -> keiner schaltet test on, da alle drei Definitionen bereits in cmd1 und ohne do always keine Wiederholung möglich
bla: off -> 1., 2., wechseln in cmd2, 3. macht nichts, weil es nur auf "on" reagiert und auf keine anderen Events im Gegensatz zu 1. und 2.
bla: off -> keiner macht etwas, da 1. und 2. bereits in cmd2 und 3. reagiert nur bei "on"
bla: on -> 1.,2., schalten test on, 3. macht nichts weil es cmd1 nicht verlassen hat und ohne do always keine Wiederholung möglich

Bei solchen Definitionen:

([Lampe_GZ:"off"]) (set Funksteckdose3 off)

will man meistens bei jedem Event "off" schalten (entspricht Fall 2) und nicht erst warten bis zwischendurch Lampe_GZ ein anderes Event geliefert hat, damit das Modul den Zustand in cmd2 wechseln konnte und wieder für cmd1 bereit ist.

daher do always.

Edit: Wenn keine zyklisch sendenden Sensoren abgefragt werden, ist do always in allen obigen Fällen sinnvoll (im 3. Fall sogar ein Muss!)

Dann habe ich dich "damals" womöglich falsch verstanden.
Um es zu verstehen, nehmen wir einen Fall 4:
DOIF ([bla:"on"]) (set test on-for-timer 30)
Wird hier "do always" benötigt?

Falls ja muss ich echt mal den alten thread rauskramen und nochmal lesen.

Gesendet von meinem Doogee S60 mit Tapatalk


Damian

#9
Zitat von: Frank_Huber am 28 Dezember 2018, 20:41:51

Dann habe ich dich "damals" womöglich falsch verstanden.
Um es zu verstehen, nehmen wir einen Fall 4:
DOIF ([bla:"on"]) (set test on-for-timer 30)
Wird hier "do always" benötigt?

Falls ja muss ich echt mal den alten thread rauskramen und nochmal lesen.

Gesendet von meinem Doogee S60 mit Tapatalk

Dein Fall 4 ist nichts anders als mein Fall 2: festes Device und ein Ereignis. Ohne do always müsste zwischendurch ein Ereignis ungleich "on" kommen, damit das DOIF auf das nächste "on" reagiert. Daher auch hier do always setzen.

Die typischen Definitionen, bei denen do always kontraproduktiv ist, sind Abfragen von zyklisch sendenden Sensoren, z. B.

DOIF ([Aussen:temperature] < 0) (set frost on) DOELSE (set frost off)

hier ist do always nicht sinnvoll, da sonst ständig frost on bzw. frost off gesetzt wird.

Im DOIF-Perlmodus gibt es kein do always (hier gibt es keine Zustände und es wird immer geschaltet).

Das obige Frost-Beispiel wird dann am besten mit DOIF_Readings definiert, um das Schalten von frost vom zyklischen Senden des Temperatur-Sensors zu entkoppeln.

DOIF {if ([$SELF:frost]) {fhem_set("frost on")} else {fhem_set("frost off)}}
attr DOIF_Readings frost:[Aussen:temperature] < 0


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

Frank_Huber

Zitat von: Damian am 29 Dezember 2018, 09:51:57
Dein Fall 4 ist nichts anders als mein Fall 2: festes Device und ein Ereignis. Ohne do always müsste zwischendurch ein Ereignis ungleich "on" kommen, damit das DOIF auf das nächste "on" reagiert. Daher auch hier do always setzen.
Danke Damian, das war es. jetzt ist es klar.
DOELSE wird intern ergänzt, nicht do always. da habe ich mich falsch erinnert.
Bei einem Taster der nach on immer zurück auf off geht reicht das. aber nicht in jedem Fall.
wieder was gelernt. :)

Damian

Zitat von: Frank_Huber am 29 Dezember 2018, 10:48:31
Danke Damian, das war es. jetzt ist es klar.
DOELSE wird intern ergänzt, nicht do always. da habe ich mich falsch erinnert.
Bei einem Taster der nach on immer zurück auf off geht reicht das. aber nicht in jedem Fall.
wieder was gelernt. :)

Das habe ich mir schon gedacht. Was du meintest ist (ohne ein gesetztes do always Attribut):


DOIF ([bla:"on"]) (set test on-for-timer 30)


ist das Gleiche wie:

DOIF ([bla:"on"]) (set test on-for-timer 30) DOELSE

Das ist aber ein anderes Thema.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

petermiller

Vielen Dank für die ausführliche Erklärung. In meinem Fall wechselte Funksteckdose3 durch erneutes einschalten von Lampe_GZ in cmd_2 während die anderen beiden Funksteckdosen in cmd_1 geblieben sind. Beim ausschalten von Lampe_GZ schaltete somit nur das DOIF von Funksteckdose3. Soweit verstanden.
Ich werde jetzt das Ganze jedoch wie vorgeschlagen über ein DOIF, mit mehreren Ausführungsblöcken und entsprechenden waits lösen.
Vielen Dank
Jens