Code bitte immer als Code posten

einfach der Lesbarkeit wegen.
Wo ist die Definition von
var_switch_WZ?
Wo ist die Definition von
soll1EinWZ,
soll1AusWZ,
soll2EinWZ und
soll2AusWZ?
Das logInfo mag funktionieren, ist aber in dieser Form nicht korrekt. Die Funktion ist als logInfo(String,String) definiert, Du übergibst aber als 2. Parameter eine Zahl. Dass das eventuell trotzdem funktioniert, liegt nur daran, dass openHAB die Zahl als Bestandteil von Number betrachtet, und Number hat eine Methode .toString, die automatisch verwendet wird.
Deine Rule wird jede Minute aufgerufen, falls die Abarbeitung der Rule aus irgendeinem Grund länger dauert, könnte die Rule auch mehrfach gestartet werden und sich dann selbst in die Quere kommen.
Der Ansatz hinter dem Code ist zumindest ungünstig, denn Du musst jede Minute einmal die Variablen neu berechnen. Besser wäre es, Timer einzusetzen. Grundsätzlich geht das so:
Code: Alles auswählen
// globale Variablen
var Timer timer1 = null
var Timer timer2 = null
// Rules
rule "timer setzen"
when
Time cron "0 0 0 ? * 1-5" or // Mitternacht, Montag bis Freitag
Item Uhr1_M_Ein_WZ changed or // Zeit wurde geändert
Item Uhr1_H_Ein_WZ changed or // "
Item Uhr1_M_Aus_WZ changed or // "
Item Uhr1_H_Aus_WZ changed // "
then
logInfo("timer","Rule getriggert!")
if(now.getDayOfWeek < 6) { // Montag bis Freitag, wegen weiteren Triggern
logInfo("timer","Wochentag ist {}",now.getDayOfWeek)
var Number soll1EinWZ = (Uhr1_M_Ein_WZ.state as Number) + 60 * (Uhr1_H_Ein_WZ.state as Number)
var Number soll1AusWZ = (Uhr1_M_Aus_WZ.state as Number) + 60 * (Uhr1_H_Aus_WZ.state as Number)
logInfo("timer","Einschaltzeit {}",now.withTimeAtStartOfDay.plusMinutes(soll1EinWZ.intValue))
logInfo("timer","Ausschaltzeit {}",now.withTimeAtStartOfDay.plusMinutes(soll1AusWZ.intValue))
if(timer1 !== null) timer1.cancel // Timer aktiv, also zuerst löschen
timer1 = createTimer(now.withTimeAtStartOfDay.plusMinutes(soll1EinWZ.intValue), [
if (Schalter_manu_WZ.state == OFF) {
logInfo("timer","Einschaltzeit erreicht und Automatik aktiv!")
if ((Thermostat_WZ.state as Number) != 1) Thermostat_WZ.sendCommand(1)
}
timer1 = null
])
if(timer2 !== null) timer2.cancel // Timer aktiv, also zuerst löschen
timer2 = createTimer(now.withTimeAtStartOfDay.plusMinutes(soll1AusWZ.intValue), [
if (Schalter_manu_WZ.state == OFF) {
logInfo("timer","Ausschaltzeit erreicht und Automatik aktiv!")
if ((Thermostat_WZ.state as Number) != 11) Thermostat_WZ.sendCommand(11)
}
timer2 = null
])
}
end
Die Erweiterung auf vier Timer läuft natürlich genauso. Die Idee dahinter ist folgende:
Zu Beginn eines Werktages (Nun ja, Montag bis Freitag) oder auch jedesmal, wenn eine der zwei Schaltzeiten angepasst wird, werden die Timer angelegt. Falls die Timer bereits aktiv sind, werden sie vorher gelöscht (timer1.cancel). Die Timer werden mit der korrekten Schaltzeit angelegt. Wenn der Timer abläuft, wird das Lambda (der Teil zwischen [ und ]) ausgeführt. Konkret prüft der Code, ob der Timer ausgeführt werden soll (Manuell OFF), und falls das der Fall ist wird der Status gesetzt, falls er vom Soll abweicht. Ich habe hier bewusst auf eine variable verzichtet, das hat keinen Mehrwert...
Am Ende des Lambdas wird der Timer deinitialisiert. (timer1 = null)
Was ist jetzt der Unterschied? Die Rule wird nur dann getriggert, wenn es entweder Mitternacht ist oder Minuten bzw. Stunden verstellt werden. Der auszuführende Code wird exakt zur gewünschten Zeit exakt einmal ausgeführt.
EDIT: Code ein 2. Mal von Fehlern befreit (wegen Referenzierung)