Hauptmenü

Mein DOIF spinnt gelegentlich

Begonnen von FHEMAN, 20 August 2016, 16:14:08

Vorheriges Thema - Nächstes Thema

FHEMAN

Hallo,

ich mache meine ersten Gehversuche mit dem scheinbar Alleskönner DOIF.
Dazu will ich zwecks Beschattung einige Rolläden runterfahren, wenn es heiß ist und die Sonne scheint und wir nicht da sind und wenn es Tag ist.


([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>6 and [TempDiffSen.01:Aussentemperatur]>22) (
  set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off
) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>4 and [TempDiffSen.01:Aussentemperatur]>20) (
  set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off
) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]<4 and [?TempDiffSen.01:rolloTrigger] eq "off") (
  set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=on on, setreading TempDiffSen.01 rolloTrigger on
)

Ein wenig verschachtelt ist das Ganze, weil ich ich bei nur geringem Sonnenschein (Tempdiff des Temperaturdifferenzsensors zw. 4 und 6 Grad) weniger Rollos runterfahren lassen möchte. Ebenso sollen die Rollos nur hochgefahren werden, wenn die Rollos vom Doif heruntergefahren wurden. Die Bedingungen sollen nur bei ausreichend langer Dauer eintreten, was ich mittels
attr doif wait 900:900:2700
(hoffentlich korrekt) gelöst habe.

Die Geschichte funktioniert zwar, wenn wir weg sind, aber leider auch manchmal, wenn wir da sind.
Heute morgen um 6.15 Uhr gingen die Rollläden hoch, obwohl wenn überhaupt nur eine Bedingung (vermutlich rolloTrigger) erfüllt war. Meine Liebste, die gerade mit unserer 4 Tage alten Tochter stillend im Wohnzimmer gesessen hatte, bat mich nun zurecht dringend um ein Bugfix... ;)

//Nachtrag, hier noch ein list vom doif:
Internals:
   DEF        ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>6 and [TempDiffSen.01:Aussentemperatur]>22) (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>4 and [TempDiffSen.01:Aussentemperatur]>20) (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]<4 and [?TempDiffSen.01:rolloTrigger] eq "off") (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=on on, setreading TempDiffSen.01 rolloTrigger on)
   NAME       doif.Autobeschattung
   NR         642
   NTFY_ORDER 50-doif.Autobeschattung
   STATE      cmd_3
   TYPE       DOIF
   Readings:
     2016-08-20 16:15:49   Device          TempDiffSen.01
     2016-08-20 09:54:18   cmd             3
     2016-08-20 09:54:18   cmd_event       TempDiffSen.01
     2016-08-20 09:54:18   cmd_nr          3
     2016-08-20 09:18:31   e_Abwesend_STATE off
     2016-08-20 16:15:49   e_TempDiffSen.01_Aussentemperatur 26.7
     2016-08-20 16:15:49   e_TempDiffSen.01_T2_T1 0.9
     2016-08-20 16:15:49   e_TempDiffSen.01_rolloTrigger on
     2016-08-20 09:54:18   state           cmd_3
     2016-08-20 09:54:17   wait_timer      no timer
   Condition:
     0          InternalDoIf($hash,'isDay','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and InternalDoIf($hash,'Abwesend','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and ReadingValDoIf($hash,'TempDiffSen.01','T2_T1','','',AttrVal($hash->{NAME},'notexist',undef))>6 and ReadingValDoIf($hash,'TempDiffSen.01','Aussentemperatur','','',AttrVal($hash->{NAME},'notexist',undef))>22
     1          InternalDoIf($hash,'isDay','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and InternalDoIf($hash,'Abwesend','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and ReadingValDoIf($hash,'TempDiffSen.01','T2_T1','','',AttrVal($hash->{NAME},'notexist',undef))>4 and ReadingValDoIf($hash,'TempDiffSen.01','Aussentemperatur','','',AttrVal($hash->{NAME},'notexist',undef))>20
     2          InternalDoIf($hash,'isDay','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and InternalDoIf($hash,'Abwesend','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and ReadingValDoIf($hash,'TempDiffSen.01','T2_T1','','',AttrVal($hash->{NAME},'notexist',undef))<4 and ReadingValDoIf($hash,'TempDiffSen.01','rolloTrigger','','',AttrVal($hash->{NAME},'notexist',undef)) eq "off"
   Devices:
     0           Abwesend TempDiffSen.01
     1           Abwesend TempDiffSen.01
     2           Abwesend TempDiffSen.01
     all         Abwesend TempDiffSen.01
   Do:
     0:
       0          set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off
     1:
       0          set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off
     2:
       0          set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=on on, setreading TempDiffSen.01 rolloTrigger on
     3:
   Helper:
     event      battery: ok,Aussentemperatur: 26.7,T1_T2: -0.9,T2_T1: 0.9
     globalinit 1
     last_timer 0
     sleepdevice TempDiffSen.01
     sleepsubtimer -1
     sleeptimer -1
     timerdev   TempDiffSen.01
     timerevent battery: ok,Aussentemperatur: 22.4,T1_T2: -2.3,T2_T1: 2.3
     triggerDev TempDiffSen.01
     timerevents:
       battery: ok
       Aussentemperatur: 22.4
       T1_T2: -2.3
       T2_T1: 2.3
     timereventsState:
       battery: ok
       Aussentemperatur: 22.4
       T1_T2: -2.3
       T2_T1: 2.3
     triggerEvents:
       battery: ok
       Aussentemperatur: 26.7
       T1_T2: -0.9
       T2_T1: 0.9
     triggerEventsState:
       battery: ok
       Aussentemperatur: 26.7
       T1_T2: -0.9
       T2_T1: 0.9
   Internals:
     0           isDay:STATE Abwesend:STATE
     1           isDay:STATE Abwesend:STATE
     2           isDay:STATE Abwesend:STATE
     all         isDay:STATE Abwesend:STATE
   Itimer:
   Readings:
     0           TempDiffSen.01:T2_T1 TempDiffSen.01:Aussentemperatur
     1           TempDiffSen.01:T2_T1 TempDiffSen.01:Aussentemperatur
     2           TempDiffSen.01:T2_T1 TempDiffSen.01:rolloTrigger
     all         TempDiffSen.01:T2_T1 TempDiffSen.01:Aussentemperatur TempDiffSen.01:rolloTrigger
   Regexp:
     0:
     1:
     2:
     All:
   State:
   Trigger:
Attributes:
   room       Klima,Rollladen
   wait       900:900:2700


Was kann da bei meiner doif Konstruktion schief laufen? Hat es etwas mit dem wait zu tun?

Danke und Gruß
Ronny
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Zitat von: derron am 20 August 2016, 16:14:08
Hallo,

ich mache meine ersten Gehversuche mit dem scheinbar Alleskönner DOIF.
Dazu will ich zwecks Beschattung einige Rolläden runterfahren, wenn es heiß ist und die Sonne scheint und wir nicht da sind und wenn es Tag ist.


([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>6 and [TempDiffSen.01:Aussentemperatur]>22) (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>4 and [TempDiffSen.01:Aussentemperatur]>20) (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]<4 and [?TempDiffSen.01:rolloTrigger] eq "off") (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=on on, setreading TempDiffSen.01 rolloTrigger on)

Ein wenig verschachtelt ist das Ganze, weil ich ich bei nur geringem Sonnenschein (Tempdiff des Temperaturdifferenzsensors zw. 4 und 6 Grad) weniger Rollos runterfahren lassen möchte. Ebenso sollen die Rollos nur hochgefahren werden, wenn die Rollos vom Doif heruntergefahren wurden. Die Bedingungen sollen nur bei ausreichend langer Dauer eintreten, was ich mittels
attr doif wait 900:900:2700
(hoffentlich korrekt) gelöst habe.

Die Geschichte funktioniert zwar, wenn wir weg sind, aber leider auch manchmal, wenn wir da sind.
Heute morgen um 6.15 Uhr gingen die Rollläden hoch, obwohl wenn überhaupt nur eine Bedingung (vermutlich rolloTrigger) erfüllt war. Meine Liebste, die gerade mit unserer 4 Tage alten Tochter stillend im Wohnzimmer gesessen hatte, bat mich nun zurecht dringend um ein Bugfix... ;)

//Nachtrag, hier noch ein list vom doif:
Internals:
   DEF        ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>6 and [TempDiffSen.01:Aussentemperatur]>22) (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]>4 and [TempDiffSen.01:Aussentemperatur]>20) (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off) DOELSEIF ([?isDay] eq "on" and [Abwesend] eq "on" and [TempDiffSen.01:T2_T1]<4 and [?TempDiffSen.01:rolloTrigger] eq "off") (set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=on on, setreading TempDiffSen.01 rolloTrigger on)
   NAME       doif.Autobeschattung
   NR         642
   NTFY_ORDER 50-doif.Autobeschattung
   STATE      cmd_3
   TYPE       DOIF
   Readings:
     2016-08-20 16:15:49   Device          TempDiffSen.01
     2016-08-20 09:54:18   cmd             3
     2016-08-20 09:54:18   cmd_event       TempDiffSen.01
     2016-08-20 09:54:18   cmd_nr          3
     2016-08-20 09:18:31   e_Abwesend_STATE off
     2016-08-20 16:15:49   e_TempDiffSen.01_Aussentemperatur 26.7
     2016-08-20 16:15:49   e_TempDiffSen.01_T2_T1 0.9
     2016-08-20 16:15:49   e_TempDiffSen.01_rolloTrigger on
     2016-08-20 09:54:18   state           cmd_3
     2016-08-20 09:54:17   wait_timer      no timer
   Condition:
     0          InternalDoIf($hash,'isDay','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and InternalDoIf($hash,'Abwesend','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and ReadingValDoIf($hash,'TempDiffSen.01','T2_T1','','',AttrVal($hash->{NAME},'notexist',undef))>6 and ReadingValDoIf($hash,'TempDiffSen.01','Aussentemperatur','','',AttrVal($hash->{NAME},'notexist',undef))>22
     1          InternalDoIf($hash,'isDay','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and InternalDoIf($hash,'Abwesend','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and ReadingValDoIf($hash,'TempDiffSen.01','T2_T1','','',AttrVal($hash->{NAME},'notexist',undef))>4 and ReadingValDoIf($hash,'TempDiffSen.01','Aussentemperatur','','',AttrVal($hash->{NAME},'notexist',undef))>20
     2          InternalDoIf($hash,'isDay','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and InternalDoIf($hash,'Abwesend','STATE','','',AttrVal($hash->{NAME},'notexist',undef)) eq "on" and ReadingValDoIf($hash,'TempDiffSen.01','T2_T1','','',AttrVal($hash->{NAME},'notexist',undef))<4 and ReadingValDoIf($hash,'TempDiffSen.01','rolloTrigger','','',AttrVal($hash->{NAME},'notexist',undef)) eq "off"
   Devices:
     0           Abwesend TempDiffSen.01
     1           Abwesend TempDiffSen.01
     2           Abwesend TempDiffSen.01
     all         Abwesend TempDiffSen.01
   Do:
     0:
       0          set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off
     1:
       0          set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED:FILTER=STATE!=off off, setreading TempDiffSen.01 rolloTrigger off
     2:
       0          set Rollo.(E|O)G.*:FILTER=Himmelsrichtung=SUED|WEST|OST:FILTER=STATE!=on on, setreading TempDiffSen.01 rolloTrigger on
     3:
   Helper:
     event      battery: ok,Aussentemperatur: 26.7,T1_T2: -0.9,T2_T1: 0.9
     globalinit 1
     last_timer 0
     sleepdevice TempDiffSen.01
     sleepsubtimer -1
     sleeptimer -1
     timerdev   TempDiffSen.01
     timerevent battery: ok,Aussentemperatur: 22.4,T1_T2: -2.3,T2_T1: 2.3
     triggerDev TempDiffSen.01
     timerevents:
       battery: ok
       Aussentemperatur: 22.4
       T1_T2: -2.3
       T2_T1: 2.3
     timereventsState:
       battery: ok
       Aussentemperatur: 22.4
       T1_T2: -2.3
       T2_T1: 2.3
     triggerEvents:
       battery: ok
       Aussentemperatur: 26.7
       T1_T2: -0.9
       T2_T1: 0.9
     triggerEventsState:
       battery: ok
       Aussentemperatur: 26.7
       T1_T2: -0.9
       T2_T1: 0.9
   Internals:
     0           isDay:STATE Abwesend:STATE
     1           isDay:STATE Abwesend:STATE
     2           isDay:STATE Abwesend:STATE
     all         isDay:STATE Abwesend:STATE
   Itimer:
   Readings:
     0           TempDiffSen.01:T2_T1 TempDiffSen.01:Aussentemperatur
     1           TempDiffSen.01:T2_T1 TempDiffSen.01:Aussentemperatur
     2           TempDiffSen.01:T2_T1 TempDiffSen.01:rolloTrigger
     all         TempDiffSen.01:T2_T1 TempDiffSen.01:Aussentemperatur TempDiffSen.01:rolloTrigger
   Regexp:
     0:
     1:
     2:
     All:
   State:
   Trigger:
Attributes:
   room       Klima,Rollladen
   wait       900:900:2700


Was kann da bei meiner doif Konstruktion schief laufen? Hat es etwas mit dem wait zu tun?

Danke und Gruß
Ronny

Ich würde die Definition logisch einrücken, dann kann man den Code besser nachvollziehen, um eine Aussage dazu machen zu können.

Gruß

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

Brockmann

#2
Wenn ich das richtig sehe, gehört zu allen drei Bedingungen [Abwesend] eq "on".
Wenn diese Bedingung heute morgen zu keinem Zeitpunkt erfüllt war (und so hört es sich an), dann kann das DOIF eigentlich nicht der Schuldige sein. Kommt nicht noch ein anderer Auslöser in Frage?

Ansonsten: Definier Dir ein Filelog auf das DOIF, das alle Events dieses DOIFs aufzeichnet. Dann kannst beim nächsten Mal genau nachvollziehen, wer das DOIF ausgelöst hat und welche Bedingungen erfüllt waren.

FHEMAN

OK, schon mal beruhigend, dass ihr keinen banalen Syntaxfehler entdeckt habt. Da die Rollläden hochfuhren, konzentriere ich mich mal auf den Dummy "Abwesend", um auszuschließen, dass der nicht aus irgend einem Grund doch "on" war.
Weil DOIF allgemein so komplex ist samt ungewöhnlicher Syntax, denkt ich immer gleich, dort liegt der Fehler.
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

FHEMAN

Ich habe die letzten Tage das DOIF beobachtet und das Abwesend Attribut beobachtet. Nun, heute Morgen wieder dieser Fehler!
Wobei sich der Zustand der Bedingungsvariable "Abwesend" zwischen Start und Ende des Wait Zählers geändert hat.
Heißt das nun, dass innerhalb von wait die Bedingungen nicht erneut geprüft werden, das Wait dann also nur ein einfaches Sleep darstellt?
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Brockmann

Zitat von: derron am 24 August 2016, 13:46:40
Heißt das nun, dass innerhalb von wait die Bedingungen nicht erneut geprüft werden, das Wait dann also nur ein einfaches Sleep darstellt?
Jein.
Ein wait läuft solange, wie das DOIF seinen Zustand beibehält. Erreicht es sein Ende, wird es ohne weitere Prüfung ausgeführt. Wechselt das DOIF seinen Zustand, während das wait läuft, wird das wait abgebrochen.

Dein Problem: Alle Bedingungen Deines DOIFs beinhalten [Abwesend] eq "on".
Wenn Abwesend auf einen anderen Wert als "on" wechselt, gilt die Bedingung zwar nicht mehr, es passt aber auch keine der anderen Bedingungen. Folglich kann das DOIF seinen Zustand nicht wechseln und bleibt deshalb im alten Zustand und der Timer läuft weiter. Dadurch dass Du in allen Bedingungen dieselbe Teilbedingung verwendest, hebelst Du das wait-Konstrukt quasi selbst aus.

Abhilfe: Du könntest ein einfach ein leeres DOELSE() ans Ende hängen. Das würde einen Zustandswechsel ermöglichen, wenn keine der IF-Bedingungen erfüllt ist. Ob das unerwünschte Nebeneffekte für Dein Konstrukt hat, kann ich nicht beurteilen. Alternativ kannst Du auch irgendeine DOELSEIF ([Abwesend] ne "on" ...)(...) einfügen, die diesen speziellen Fall abfängt.

FHEMAN

Wenn ich kein DOELSE(IF) verwende, dann wird das Wait bzw. DOIF auch nie abgebrochen, weil kein alternativer Zustand definiert wurde? Vielleicht verstehe ich es ja noch nicht richtig, aber für mich ist das ein merkwürdiges Verhalten.

Ich teste einmal den leeren DOELSE() Zweig. Danke für den Tip!
NUC7i5 | PROXMOX | FHEM 6.2 | 1 HMLAND | 2 UART | HM | LMS | HIFIBERRY | DOORBIRD | BLINK | BUDERUS | HUE | ALEXA | MILIGHT | LUFTDATENINFO | MQTT| ZIGBEE2MQTT | INDEGO | ROBOROCK | SMA | APC | OPENWB

Damian

Zitat von: derron am 24 August 2016, 16:06:18
Wenn ich kein DOELSE(IF) verwende, dann wird das Wait bzw. DOIF auch nie abgebrochen, weil kein alternativer Zustand definiert wurde? Vielleicht verstehe ich es ja noch nicht richtig, aber für mich ist das ein merkwürdiges Verhalten.


Das stimmt nicht.

Wenn du kein do always hast, dann wird bei Nichterfüllung der Bedingung cmd_2 gesetzt, es erfolgt also ein Zustandswechsel und ein laufender Timer wird zurückgesetzt. Bsp.:

([mydummy] eq "on") (set bla on)

entspricht ohne do always

([mydummy] eq "on") (set bla on) DOELSE

Gruß

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

Brockmann

Zitat von: Damian am 24 August 2016, 16:16:44
Wenn du kein do always hast, dann wird bei Nichterfüllung der Bedingung cmd_2 gesetzt, es erfolgt also ein Zustandswechsel und ein laufender Timer wird zurückgesetzt. Bsp.:
Zur Klarstellung: Das gilt nur für einfache DOIFs ohne DOELSEIF. Da wird das leere DOELSE implizit durch das Modul gesetzt.
Wenn man aber wie in diesem Fall ein DOIF mit mindestens einem DOELSEIF hat, wird kein leeres DOELSE implizit gesetzt, sondern man muss es explizit setzen, wenn man es haben möchte.

DOIF -> DOELSE() ist implizit definiert
DOIF...DOELSEIF... -> DOELSE(...) muss bei Bedarf explizit definiert werden

Korrekt?

Damian

Zitat von: Brockmann am 25 August 2016, 08:32:15
Zur Klarstellung: Das gilt nur für einfache DOIFs ohne DOELSEIF. Da wird das leere DOELSE implizit durch das Modul gesetzt.
Wenn man aber wie in diesem Fall ein DOIF mit mindestens einem DOELSEIF hat, wird kein leeres DOELSE implizit gesetzt, sondern man muss es explizit setzen, wenn man es haben möchte.

DOIF -> DOELSE() ist implizit definiert
DOIF...DOELSEIF... -> DOELSE(...) muss bei Bedarf explizit definiert werden

Korrekt?

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