Also, ganz grundsätzlich, Rules, die in einem bestimmten Zeitraum minütlich triggern, lassen sich meist auf andere Art besser triggern.
Du möchtest beispielsweise aufgrund der Helligkeit die Rollläden fahren. Du musst also in der Rule nicht nur prüfen, ob die rule schon gelaufen ist, sondern auch, wie hell es ist. Eine weitere Bedingung ist der Zeitraum, der ist bei Dir über den Trigger abgedeckt. Das eigentliche Ereignis ist aber kein zeitliches, sondern das Unterschreiten eines Messwertes.
Entsprechend sollte die Rule eigentlich auf die Messwertänderung triggern.
Was das Stoppen der Rule nach vollendeter Arbeit betrifft, so gibt es dazu mindestens noch eine Frage, nämlich: gibt es einen Rollladen, der sicher offen ist (also nie von Hand gesteuert wird) und der von der Rule geschlossen wird? Denn dann sollte es ausreichen, den Status dieses Rollladens abzufragen. Ansonsten musst Du Dir merken, ob die Rule bereits ausgelöst wurde. Wenn Du Rules (egal welcher Bauart) in der UI anlegst, kannst Du keine globalen Variablen nutzen, allenfalls kannst Du Variablen definieren, deren Zustand nach dem Durchlauf der Rule erhalten bleiben - aber das hilft Dir hier nicht, denn Du musst die Variable ja auch wieder zurücksetzen, sie muss also zwingend "echt" global sein.
Der Ausweg: Du nutzt ein Item, welches Du nur zu diesem Zweck anlegst. Das Item wird nicht mit einem Channel verlinkt, es bleibt also ungebunden. Da Du die Rule nur maximal einmal am Tag ausführen lassen willst, reicht sogar ein Switch Item aus.
Als klassische DSL Rule sähe es so aus:
Code: Alles auswählen
rule "Rolllaeden zu bei Dunkelheit"
when
Item SonnensensorsudTerrasse_Luminance changed // ein Number Item, welches die Helligkeit enthält
then
if(dunkelAktiv.state == ON) // Rule bereits aktiviert?
return;
if(now.getHour < 16) // zu früh?
return;
if(now.getHour > 18) // zu spät?
return;
if(!(newState instanceof Number)) // liefert Sensor keinen Messwert?
return;
if((newState as Number).intValue > 165) // oberer Grenzwert noch nicht unterschritten?
return;
if((newState as Number).intValue < 65) // unterer Grenzwert bereits unterschritten?
return;
// alle Bedingungen sind erfüllt!
dunkelAktiv.postUpdate(ON)
// hier Rollläden zu
end
Tatsächlich kann es durchaus sein, dass diese Rule häufiger ausgelöst wird (nämlich sobald sich die Helligkeit ändert), dennoch ist diese Variante vorzuziehen.
Nacheinander werden alle Abbruchbedingungen geprüft, wenn keine der Bedingungen zutrifft wird der Merker gesetzt und der Rest des Codes ausgeführt.
In den UI Rules gibt es natürlich den but-only-if-Bereich. All diese Abbruchbedingungen können auch dort hinterlegt werden. Technisch dürfte es zu der klassischen DSL Rule hier keinen Unterschied geben.
Das Changed Ereignis belegt keinen Slot im Scheduler (im Gegensatz zum Time cron Trigger), wobei beliebig viele Slots zur Verfügung stehen, das sollte also keine Rolle spielen, aber: Das Changed Ereignis tritt ohnehin auf, das Time cron Ereignis tritt zusätzlich auf.
Der Zustand des Switch Items muss so oder so ausgelesen werden, ebenso die anderen Zustände. Der Messwert kommt aber als implizite Variable in die Rule hinein (newState), hier wird durch die Wahl des Triggers keine zusätzliche Abfrage der Registry gebraucht.
Now.getHour() steht "einfach" zur Verfügung, also ohne dass dazu weiterer Programmcode gebraucht wird (außer die Methode selbst natürlich).
Im Zweifel ist die Begrenzung des Messwertes nach unten (<65) unnötig, da die Rule vermutlich ohnehin bereits ausgelöst haben wird.
Ein weiterer Gedanke: Du steuerst die Rollläden ja über das Astrobinding. Es wäre also naheliegend, sich die Grenzzeit ebenfalls von Astro zu holen.
Nehemn wir an, Du löst das Schließen der Rollläden mit dem RangeEvent civilDusk triggered START aus,
dann musst Du in der Rule lediglich prüfen, ob die aktuelle Zeit z.B. nicht mehr als 45 Minuten vor DateTime civilDuskStart liegt (und nicht mehr als 1 Minute nach civilDuskStart). Damit funktioniert die Rule dann jahreszeitunabhängig und die Läden werden bis zu 45 Minuten vor dem eigentlichen Zeitpunkt geschlossen. Leider ist das Format des Datetime Items ein anderes als JavaTime, so dass die Formulierung der Bedingungen hier etwas aufwändiger ist, aber es wäre vermutlich "schicker"
