Das Problem dabei ist die fehlende Möglichkeit, den Timer abzubrechen, das bräuchte es dafür. In der DSL ist das kein Problem. Nur zur Anschauung:
Code: Alles auswählen
var Timer tShade = null // Globale Variable für Timer
rule "Beschattung Automatik"
when
Item Helligkeit changed // Helligkeit hat sich geändert
then
var Integer iTemp = 0 // definiere Variable für Temperatur
if(Temperatur.state instanceof Number) // falls gültige Temperatur
iTemp = (Temperatur.state as Number).intValue // lade Temperatur in Variable
var Integer iBright = 0 // definiere Variable für Helligkeit
if(Helligkeit.state instanceof Number) // falls gültige Helligkeit
iBright = (Helligkeit.state as Number).intValue // lade Helligkeit in Variable
if(tShade === null && iBright > 60000 && iTemp > 24) // Bedingungen erfüllt? (Timer nicht gestartet, hell genug, warm genug
tShade = createTimer(now.plusMinutes(10),[| // starte Timer. bei Ablauf des Timers:
gShutterSued.sendCommand(55) // schließe Rollos
tShade = null // lösche Timer Variable
]) // Ende Timer
else if(iBright < 59000) { // falls erste Bedingung nicht erfülllt und Helligkeit geringer als 59000
tShade?.cancel // breche Timer ab, falls einer läuft
tShade = null // lösche Timer
}
end
Die Rule löst jedes Mal aus, wenn ein geänderter Helligkeitswert herein kommt.
Zu Beginn werden de benötigten Werte ermittelt, das sind die Helligkeit und die Temperatur.
Es reicht, die Werte als Integer zu verwenden. Bei der Wandlung nach Integer wird außerdem eine evtl. vorhandene Einheit entfernt.
Nun folgt die Prüfung auf Überschreiten der Grenzwerte. Die Integer Werte für Helligkeit und Temperatur müssen passen, außerdem darf der Timer noch nicht gestartet sein. Sind all diese Bedingungen erfüllt, so wird der Timer angelegt und die Rule ist fertig.
Ist eine der Bedingungen nicht erfüllt und gleichzeitig die Helligkeit unter 59000 (man sollte immer eine gewisse Hysterese vorsehen) so wird ein eventuell laufender Timer abgebrochen und die Variable gelöscht. Somit kann die nächste Hell-Phase einen neuen Timer starten.
Wenn der Timer abläuft, ohne dass er gecancelt wurde, kommt der Code im Timer zur Ausführung. Das wäre hier das Schließen der Läden und natürlich das Zurücksetzen der Timer Variablen.
Für Blockly gäbe es eventuell eine Möglichkeit, mit Metadata Expiration zu arbeiten. Vorarbeit:
Ein ungebundenes Item anlegen. Ich nutze hier als Namen "StartShade" (Switch Item passt). In den Metadaten des Items wird die Expiration eingetragen, und zwar 10 Minuten, Command OFF.
Nun brauchst Du drei Rules (oder zwei, je nachdem...).
1. Rule: bei Änderung Helligkeit, aber nur, falls Temperatur über 25 und Helligkeit über 60000 und Status StartShade nicht gleich ON -> Ändere den Status von StartShade auf ON
2. Rule: bei Änderung Helligkeit, aber nur, falls Helligkeit unter 59000 -> Ändere den Status von StartShade auf OFF (es ist essenziell, dass nur der Status gesetzt wird, es darf kein Befehl gesendet werden!!!)
3. Rule sobald das Item StartShade den Befehl (!) OFF empfängt -> Schließe die Läden.
Die drei Rules sind so einfach, dass Du dafür noch nicht mal Blockly bemühen musst. Du kannst natürlich die erste und die zweite Rule zu einer zusammenfassen und die Bedingungen dann innerhalb Blockly abfragen.
Der Knackpunkt ist aber, dass der Code lediglich den Status des ungebundenen Items setzt, während das Ende der Expiration ein Command OFF sendet.
Deshalb triggert die letzte Rule nur, wenn die Expiration abläuft, nicht aber, wenn der Status einfach zurückgesetzt wurde.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet