Die Rule ist eine "alte" Rule aus openHAB2 Zeiten. der openHAB Core war eine Zeit lang als Eclipse SmartHome offen für Fremdimplementierungen.
Nur als kleine geschichtliche Einordnung: openHAB hat seinen Code in Eclipse zur Verfügung gestellt und die eigene Codebasis auf Eclipse umgestellt. Man erhoffte sich davon eine schnellere Entwicklung, weil Firmen so den Code selbst weiter entwickeln konnten. Leider kam aber nur sehr mäßige Resonanz und das Projekt wurde wieder zurückgebaut, weil der Aufwand, gegen Eclipse zu entwickeln schon erheblich ist.
Aus meiner Sicht hat dieser Schritt das Projekt locker um etwa ein Jahr verzögert, wobei ich natürlich nicht weiß, wie viel Code durch die Aktion "gewonnen" wurde.
Für Dich bedeutet es letztlich, dass Imports niemals das Schlüsselwort eclipse beinhalten. Im vorliegenden Code wären aber beide Imports ohnehin niemals notwendig gewesen (unter openHAB 1 musste man die Grundklassen importieren, aber da gab es noch keine Bindung an eclipse...)
Die Verwendung von Primitives ist eher ungünstig, die Rule Engine braucht unverhältnismäßig lang, um diesen Typ zu initialisieren. Besser ist es, die äquivalenten Objekte zu nutzen.
Die Prüfung auf NULL als Inhalt eines Items ist leider auch nicht hinreichend, um sicherzustellen, dass der Code nicht scheitert. Besser ist es, auf den enthaltenen Datentyp zu testen. DecimalType ist Teil von Number, die Prüfung auf Number ist hier ausreichend.
Die Berechnung von Stunde und Minute ist unverhältnismäßig aufwändig, einzig die Logausgabe verlangt diese Daten, das kann man aber leicht abwandeln. Man könnte sogar die Ausgabe in Stunden und Minuten vornehmen, aber das braucht Niemand wirklich.
Du hast zwei Rules, welche auf das selbe Item triggern und jeweils changed als Trigger nutzen. DAbei wird einmal auf ON eingegrenzt, das andere Mal auf OFF. Da in beiden Rules Teile des Codes doppelt vorkommen, ist es sinnvoller, beide Rules zu einer zusammenzufassen.
Die Dimmschritte mit minimal einer Minute Abstand auszuführen, erscheint mir etwas grob. Sinnvoller wären hier Sekunden. Natürlich muss das entsprechende Item WakeUpTimeStep in der UI angepasst werden, um Sekunden statt Minuten zu verwenden.
Minimal optimiert sehen die Rules also so aus:
Code: Alles auswählen
var Boolean mAlaramTriggered = false
var Integer mCurrentDimLevel = 0
val String LOG = "wakeUp"
var Timer mWakeUpTimer = null
var Timer mDimmerTimer = null
var Integer mDimStep = 2
var Integer mTimeStep = 60
val Integer DEFAULT_DIM_STEP = 2
val Integer DEFAULT_TIME_STEP = 60
rule "WakeUp Alarm Switch"
when
Item WakeUpAlarmSwitch changed
then
WakeUpAlarmTriggered.postUpdate(OFF)
mDimmerTimer?.cancel
mDimmerTimer = null
mWakeUpTimer.cancel
mWakeUpTimer = null
if(newState == OFF) {
logInfo(LOG, "Switch off wakeup")
return;
}
if(!(WakeUpHour.state instanceof Number)) {
logInfo(LOG, "WakeUpAlarmHour not set, alarm not processed")
return;
}
var Integer iWakeUpTime = (WakeUpHour.state as Number).intValue * 60
if(!(WakeUpMinute.state instanceof Number)) {
logInfo(LOG, "WakeUpAlarmMinute not set, alarm not processed")
return;
}
iWakeUpTime = iWakeUpTime + (WakeUpMinute.state as Number).intValue
val Integer iNow = now.getHour*60 + now.getMinute
var Integer iDiff = iWakeUpTime - iNow
if(iDiff <= 0)
iDiff = iDiff + 24 * 60
logInfo(LOG, "creating Timer in {} minutes",iDiff)
mWakeUpTimer = createTimer(now.plusMinutes(iDiff), [|
logInfo(LOG, "Alarm triggered! ")
WakeUpAlarmTriggered.postUpdate(ON)
])
end
rule "WakeUp Alarm triggered ON"
when
Item WakeUpAlarmTriggered changed to ON
then
logInfo(LOG, "Alarm trigger starting to dim")
mCurrentDimLevel = 0
mDimStep = DEFAULT_DIM_STEP
if(!(WakeUpDimStep.state instanceof Number))
logInfo(LOG, "Dimstep not defined using default")
else
mDimStep = (WakeUpDimStep.state as Number).intValue
mTimeStep = DEFAULT_TIME_STEP
if(!(WakeUpTimeStep.state instanceof Number))
logInfo(LOG, "Dimstep not defined using default")
else
mTimeStep = (WakeUpTimeStep.state as Number).intValue
mDimmerTimer = createTimer(now.plusSeconds(mTimeStep), [|
mCurrentDimLevel = mCurrentDimLevel + mDimStep
logInfo(LOG, "Dimming {}", mCurrentDimLevel)
if(mCurrentDimLevel >= 100) {
logInfo(LOG,"Dimming is at its max, finished")
mCurrentDimLevel = 100
} else {
logInfo(LOG, "Reschedule dimmer in {} Seconds", mTimeStep)
mDimmerTimer.reschedule(now.plusSeconds(mTimeStep))
}
dRGB1.sendCommand(mCurrentDimLevel)
if (mCurrentDimLevel == 100) {
WakeUpAlarmSwitch.sendCommand(OFF)
}
])
end
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet