Ich klemme mich mal dazu... Ich denke, Du machst Dir Dein Leben zu kompliziert.
Du hast ursprünglich ein Item uhrzeit_schalten_sd03, welches als Ausschaltzeitpunkt dienen soll. Dann bräuchtest Du aber auch zwingend ein zweites Item mit einem Eionschaltzeitpunkt. Nein, ich meine jetzt nicht, dass dann eingeschaltet wird. Stattdessen ist das Ganze ja ein dreistufiges Enable/Disable.
1. Stufe: Automatik aktiv
2. Stufe: Zeitfenster aktiv
3. Stufe Helligkeit passt.
Ich erkläre mal, wie ich das umsetzen würde (ohne Google Calendar):
Code: Alles auswählen
Number time_enable_sd03 // in Minuten nach Mitternacht
Number time_disable_sd03 // in Minuten nach Mitternacht
Number setLevel_sd03
Number Daemmerungswert
Switch automatik_sd03
Switch Sd_03_EZ01_2OG
Code: Alles auswählen
rule "Auto Switch SD03"
when
Item time_enable_sd03 changed or
Item time_disable_sd03 changed or
Item setLevel_sd03 changed or
Item Daemmerungswert changed
then
if(automatik_sd03.state != ON) { // Automatik aus?
return; // dann Abbruch!
}
var Number nEnable = 0 // Defaultwert, falls noch nichts eingestellt ist
var Number nDisable = 60*24 // Defaultwert, falls noch nichts eingestellt ist
var Number nSetLevel = 100 // Defaultwert, falls noch nichts eingestellt ist
var Number nLevel = 200 // Defaultwert, falls noch kein Messwert kommt
var sSoll = OFF // Soll Schaltstellung
val Number mNow = now.getMinuteOfDay // Minute des Tages
if(time_enable_sd03.state instanceof Number) nEnable = time_enable_sd03.state as Number // Wert lesen
if(time_disable_sd03.state instanceof Number) nDisable = time_disable_sd03.state as Number // Wert lesen
if(setLevel_sd03.state instanceof Number) nDisable = setLevel_sd03.state as Number // Wert lesen
if(Daemmerungswert.state instanceof Number) nDisable = Daemmerungswert.state as Number // Wert lesen
if(mNow >= nEnable && mNow < nDisable && nLevel <= nSetLevel) { // Im Zeitfenster und Wert unterschritten?
sSoll = ON // Dann Solltustand ändern
}
if(Sd_03_EZ01_2OG.state != sSoll) // Falls aktueller Status von Sollzustand abweicht
Sd_03_EZ01_2OG.sendCommand(sSoll.toString) // umsteuern
end
Die Rule triggert also bei etlichen Itemänderungen, eben alle, die Einfluss auf den Sollzustand des Aktors haben.
Der erste Schritt ist, zu überprüfen, ob die Automatik eingeschaltet ist. Und da kommt schon eine Frage auf... Was soll passieren, wenn der Aktor aktiv ist, und von Automatikmodus nach Manuell gewechselt wird? Meine Regel tut dann einfach gar nichts, man könnte dann aber auch gezielt abschalten, dann müsste halt zusätzlich der Wechsel des Modus in die Trigger und ein paar zusätzliche Zeilen Code in den ersten if-Block rein.
Nach dem ersten if-Block ist klar, dass der Automatik Modus aktiv ist. Nun werden also alle Werte abgeholt, die für die Betrachtung relevant sind. Da jedes der Items auch NULL enthalten kann, müssen Vorkehrungen getroffen werden, hier der Einfachheit halber über lokale Variablen.
Nun folgt eine Grenzwertbetrachtung, zum einen, befinden wir uns im festgelegten Zeitfenster? Und zum anderen, wurde der eingestellte Grenzwert unterschritten? Anhand der Defaultwerte kannst Du erkennen, dass bei fehlenden Werten der Sollzustand OFF sein wird. Fehlen nur die Zeitwerte, so reagiert die Rule auf die Helligkeitswerte, die Zeitgrenzen sind also inaktiv.
Sind alle Bedingungen erfüllt, so wird lediglich der Sollwert geändert, sonst nichts.
Zum Schluss prüft die Rule, ob der Sollwert vom Istwert abweicht. Nur wenn das der Fall ist, wird auch ein Schaltbefehl abgesetzt. Damit werden unnötige Schaltbefehle vermieden, die nur das log vollmüllen.