Openhab3-Rule: Problem mit Map of Timers
Verfasst: 5. Dez 2021 12:20
Hallo zusammen,
ich habe eine Rule geschrieben, die verwendet werden soll, um zeitverzögert Benachrichtigungen nach Statusänderungen beliebiger Items zu verschicken. Hierzu wird für jedes getriggerte Item ein Timer angelegt, welcher in einer Map<String,Timer> gespeichert wird. Die Map-Einträge werden verwendet, um die Timer abbrechen zu können, wenn sich der Status des Items vor Ablauf des Timers wieder ändert.
Die Timer werden auch erfolgreich angelegt und zeitverzögert ausgeführt. Mein Problem ist jetzt, dass das Speichern der Timer in der Map nicht funktioniert und damit ein Timer nie abgebrochen werden kann. Hat irgendjemand eine Idee, warum das Speichern in der Map nicht funktioniert?
Hier die Regel:
Und hier die zugehörige LOG-Ausgabe:
Der Timer wird zwischen den Meldungen und erzeugt und in der Map abgelegt. Wie man im log sieht, steht dort aber dann nichts. Nichtsdestotrotz wird der Timer erzeugt, da die Meldung auf dem Smartphone kommt.
Hat irgendjemand eine Idee, was ich falsch mache?
ich habe eine Rule geschrieben, die verwendet werden soll, um zeitverzögert Benachrichtigungen nach Statusänderungen beliebiger Items zu verschicken. Hierzu wird für jedes getriggerte Item ein Timer angelegt, welcher in einer Map<String,Timer> gespeichert wird. Die Map-Einträge werden verwendet, um die Timer abbrechen zu können, wenn sich der Status des Items vor Ablauf des Timers wieder ändert.
Die Timer werden auch erfolgreich angelegt und zeitverzögert ausgeführt. Mein Problem ist jetzt, dass das Speichern der Timer in der Map nicht funktioniert und damit ein Timer nie abgebrochen werden kann. Hat irgendjemand eine Idee, warum das Speichern in der Map nicht funktioniert?
Hier die Regel:
Code: Alles auswählen
//
// Benachrichtigung auf das Smartphone aller in der cloud registrierten Benutzer,
// wenn ein Fenster zu lange offen steht.
//
import org.openhab.core.model.script.ScriptServiceUtil
import java.util.Map
val logger = "notification.rules"
val notificationConf =
newHashMap(
"Badfenster_State" -> (
newHashMap(
"trigger" -> "OPEN",
"maxOpenMinutes" -> "15",
"timerMsg" -> "Das Badfenster ist seit %d Minuten offen",
"triggerLog" -> "Badfenster wurde geöffnet",
"nonTriggerLog" -> "Badfenster wurde geschlossen"
)
),
"BuerofensterLinks_State" -> (
newHashMap(
"trigger" -> "OPEN",
"maxOpenMinutes" -> "1",
"timerMsg" -> "Das linke Bürofenster ist seit %d Minuten offen",
"triggerLog" -> "linkes Bürofenster wurde geöffnet",
"nonTriggerLog" -> "linkes Bürofenster wurde geschlossen"
)
)
)
var Map<String, Timer> timers = newHashMap
rule "Benachrichtigung"
when
Item Badfenster_State changed or
Item BuerofensterLinks_State changed
then
logInfo(logger, "rule for " + triggeringItemName + " called");
var item = ScriptServiceUtil.getItemRegistry.getItem(triggeringItemName);
if (item===null) {
throw new Exception("item " + triggeringItemName + " does not exist");
}
logInfo(logger, "state = " + item.state);
var conf = notificationConf.get(triggeringItemName);
var trigger = conf.get("trigger");
logInfo(logger, "trigger=" + trigger);
var maxOpenMinutes = Integer::parseInt(conf.get("maxOpenMinutes"));
logInfo(logger, "maxOpenMinutes=" + maxOpenMinutes);
var timerMsg = conf.get("timerMsg");
logInfo(logger, "timerMsg=" + timerMsg);
var triggerLog = conf.get("triggerLog");
logInfo(logger, "triggerLog=" + triggerLog);
var nonTriggerLog = conf.get("nonTriggerLog");
logInfo(logger, "nonTriggerLog=" + nonTriggerLog);
// einen eventuell laufenden timer abbrechen
var timer = timers.get("triggeringItemName");
logInfo(logger, "timer=" + timer);
timer?.cancel();
if (item.state == trigger) {
logInfo(logger, triggerLog);
// aktuelle Uhrzeit beim Öffnen in Millisekunden
var openTime = (new java.util.Date()).getTime();
logInfo(logger, "creating timer");
timers.put(triggeringItemName, createTimer(now.plusMinutes(maxOpenMinutes),
[|
// aktuelle Uhrzeit beim Start des timers
var curTime = (new java.util.Date()).getTime();
// Anzahl Minuten seit dem Öffnen des Fensters
var openDuration = ((curTime - openTime) / 60000);
// auszugebende Meldung
var msg = String::format(timerMsg, openDuration);
// ... ins log schreiben
logInfo(logger, msg);
// ... auf die Smartphones senden
sendBroadcastNotification(msg);
]
));
logInfo(logger, "stored timer: " + timers.get("triggeringItemName"));
}
else {
logInfo(logger, nonTriggerLog);
}
end
Code: Alles auswählen
2021-12-05 12:00:39.086 [INFO ] [core.model.script.notification.rules] - rule for BuerofensterLinks_State called
2021-12-05 12:00:39.093 [INFO ] [core.model.script.notification.rules] - state = OPEN
2021-12-05 12:00:39.100 [INFO ] [core.model.script.notification.rules] - trigger=OPEN
2021-12-05 12:00:39.106 [INFO ] [core.model.script.notification.rules] - maxOpenMinutes=1
2021-12-05 12:00:39.110 [INFO ] [core.model.script.notification.rules] - timerMsg=Das linke Bürofenster ist seit %d Minuten offen
2021-12-05 12:00:39.115 [INFO ] [core.model.script.notification.rules] - triggerLog=linkes Bürofenster wurde geöffnet
2021-12-05 12:00:39.120 [INFO ] [core.model.script.notification.rules] - nonTriggerLog=linkes Bürofenster wurde geschlossen
2021-12-05 12:00:39.125 [INFO ] [core.model.script.notification.rules] - timer=null
2021-12-05 12:00:39.129 [INFO ] [core.model.script.notification.rules] - linkes Bürofenster wurde geöffnet
2021-12-05 12:00:39.134 [INFO ] [core.model.script.notification.rules] - creating timer
2021-12-05 12:00:39.147 [INFO ] [core.model.script.notification.rules] - stored timer: null
Code: Alles auswählen
creating timer
Code: Alles auswählen
stored timer: null
Hat irgendjemand eine Idee, was ich falsch mache?