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
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
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.
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.
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?
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.
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!
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
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?
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