Also, mal abgesehen vom Sinn (Warum sollte man den Offset ständig anpassen wollen? Die Idee des Offset zum Sonnenuntergang ist doch gerade, ein gleichbleibendes Ergebnis zu erhalten?) ist es fürchterlich, eine Rule alle 30 Sekunden Items setzen zu lassen, die sich maximal einmal täglich ändern.
Korrekt löst man das Problem mit einem Timer. Dazu benötigst Du eine Rule. In dieser Rule wird die korrekte Schaltzeit in ein Item gespeichert, immer, wenn sich die Astrozeit ändert (das passiert einmal täglich um Mitternacht) oder sich das Offsetitem ändert. Weiterhin errechnet die Rule, ob der gewünschte Schaltzeitpunkt bereits überschritten wurde (dann wird der Timer für den nächsten Tag gesetzt) oder noch nicht, dann wird der Timer für den aktuellen Tag gesetzt.
Ungetestete Rule:
Code: Alles auswählen
// globale Variablen zu Beginn der Datei definieren!
var Timer tSunset = null
rule "Sonnenungergang mit variablem Offset"
when
Time cron "0 1 0 * * ?" or // täglich um 00:01:00 Uhr
Item mDifferenz changed // Offset geändert
then
if(!(Sunset_Time.state instanceof DateTimeType)) { // keine Zeit gesetzt?
logWarn("sunsetvar","Astro Binding liefert keine gültige Zeit! Abbruch!")
return; // Rule beenden
}
var Integer nDiff = 0 // Default Wert
if(mDifferenz.state instanceof Number) // wurde ein Wert gesetzt?
nDiff = (mDifferenz.state as Number).intValue // dann übernehmen
tSunset?.cancel // alten Timer löschen, falls vorhanden
val Integer iMinutes = Integer::parseInt(Sunset_Time.state.format("%1$tM")) + Integer::parseInt(Sunset_Time.state.format("%1$tH"))*60 + nDiff // Startzeit berechnen
val Integer iMinute = iMinutes % 60 // reale Minute berechnen
val Integer iHour = (iMinutes / 60).intValue // reale Stunde berechen
tRealTime.postUpdate(iHour.toString + ":" + iMinute.toString + " Uhr") // in ein String Item speichern (nur Anzeige)
tSunset = createTimer(now.withTimeAtStartOfDay.plusMinutes(iMinutes).plusDays(if(iMinutes > now.getMinuteOfDay) 0 else 1),[| // neuen Timer erzeugen
// Wenn der Timer abläuft
if(S_Sonoff_POW_A.state != ON) // Falls S_Sonoff_POW_A.state nicht ON
Sonoff_Pow_Switch.sendCommand(ON) // send Kommando ON
tSunset = null // lösche Timer
])
end
Zur Anzeige der realen Schaltzeit wird nur das String Item tRealTime benötigt. Man kann natürlich auch ein DateTime Item verwenden, aber die Umwandlung ist komplizierter und ich bin grad zu faul, das nachzuschauen...
Der Punkt ist, diese Rule wird einmal täglich und bei jeder Änderung des Offsets ausgeführt. Sie erzeugt einen Timer, der zur gewünschten Zeit abläuft. Mehr braucht es nicht.
Zu Beginn der Rule werden noch ein paar Fehlerquellen abgefangen, nur für den Fall. Bei der Prüfung auf DateTimeType bin ich mir nicht 100% sicher, notfalls kann man den Teil auch weg lassen, besser wäre es aber, statt einfach davon auszugehen, dass das Binding schon ein Datum zurückliefern wird...