Seite 1 von 1

Regel Lüften Warnung - Timer basierend auf Item

Verfasst: 5. Jul 2025 17:09
von technick90
Hallo,

ich versuche meine Regel zur Warnung bei geöffneten Fenster anzupassen. Die Zeit bis zur Warnung soll nicht mehr fest definiert sein, sondern pro Fenster mittels Number Item gesteuert werden können.

Grundlage ist folgende Regel:

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil
import java.util.Map
val Map<String, Timer> contactTimers = newHashMap
val Map<String, Boolean> contactList = newHashMap

rule "Fenster Status"
when
    Member of Fenstersensoren changed
then
    val String itemLabel = triggeringItem.label
    val String itemName = triggeringItem.name
    val String itemNameSperren = itemName.replace("Kontakt","Sperren")
    val GenericItem SperrenItem = ScriptServiceUtil.getItemRegistry?.getItem(itemNameSperren) as GenericItem
    var vName = triggeringItem.name.split("_").get(1)
    var vTimerName = "timer_" + vName
    contactTimers.get(vTimerName)?.cancel;
    if((triggeringItem.state == "Offen") && (SperrenItem.state != ON)) {
        contactList.put(vTimerName,true)
        contactTimers.put(vTimerName, createTimer(now.plusMinutes(13)) [|
            var text = itemLabel + " ist "
            if(contactList.get(vTimerName)) {
                contactList.put(vTimerName,false)
                text = text + "seit "
            } else {
                text = text + "länger als " }
            text = text + "13 Minuten geöffnet"
            AlexaWohnzimmer_Ankuendigung.sendCommand(text)
            AlexaBad_TTS.sendCommand(text)
            AlexaArbeitszimmer_TTS.sendCommand(text)
            AlexaKueche_TTS.sendCommand(text)
            if (Anwesenheit == OFF) {sendBroadcastNotification(text, "contact", "Info")}
			else {
				if (UniFiWirelessClientRobert_Online.state == ON) {sendNotification("abc@abc.de", text, "contact", "Info")}
			}
            contactTimers.get(vTimerName)?.reschedule(now.plusMinutes(5))
        ])
    } 
	else if ((triggeringItem.state == "Offen") && (SperrenItem.state != OFF)) {
        contactList.put(vTimerName,true)
        contactTimers.put(vTimerName, createTimer(now.plusMinutes(1440)) [|
            var text = itemLabel + " ist "
            if(contactList.get(vTimerName)) {
                contactList.put(vTimerName,false)
                text = text + "seit "
            } else {
                text = text + "länger als " }
            text = text + "1 Tag geöffnet"
            AlexaWohnzimmer_Ankuendigung.sendCommand(text)
            AlexaBad_TTS.sendCommand(text)
            AlexaArbeitszimmer_TTS.sendCommand(text)
            AlexaKueche_TTS.sendCommand(text)
            if (Anwesenheit == OFF) {sendBroadcastNotification(text, "contact", "Info")}
			else {
				if (UniFiWirelessClientRobert_Online.state == ON) {sendNotification("abc@abc.de", text, "contact", "Info")}
			}
            contactTimers.get(vTimerName)?.reschedule(now.plusMinutes(10))
        ])
    } 	
	else
        contactTimers.get(vTimerName)?.cancel
end
Nach besten Wissen habe ich die Regel wie folgt angepasst, aber es funktioniert nicht. Meine Programmierkenntnisse sind leider echt rudimentär, daher bin ich trotz zahlreichen Googlen nicht in der Regel die Regel zum Laufen zu bekommen.

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil
import java.util.Map
val Map<String, Timer> contactTimers = newHashMap
val Map<String, Boolean> contactList = newHashMap

rule "Fenster Status"
when
    Member of Fenstersensoren changed
then
    val String itemLabel = triggeringItem.label
    val String itemName = triggeringItem.name
    val String itemNameSperren = itemName.replace("Kontakt","SperrenTest")
    val GenericItem SperrenItem = ScriptServiceUtil.getItemRegistry?.getItem(itemNameSperren) as GenericItem
    var vName = triggeringItem.name.split("_").get(1)
    var vTimerName = "timer_" + vName
	var vTimerTime = "13"
    contactTimers.get(vTimerName)?.cancel;
	if (SperrenItem.state instanceof Number) {vTimerTime = SperrenItem.state as Number}
    if(triggeringItem.state == "Offen") {
        logInfo("INFO", "Fenster geöffnet: " + itemName + " seit " + vTimerTime)
		contactList.put(vTimerName,true)
        contactTimers.put(vTimerName, createTimer(now.plusMinutesvTimerTime)) [|
            var text = itemLabel + " ist "
            if(contactList.get(vTimerName)) {
                contactList.put(vTimerName,false)
                text = text + "seit "
            } else {
                text = text + "länger als " }
            text = text + vTimerTime + " Minuten geöffnet"
            AlexaWohnzimmer_Ankuendigung.sendCommand(text)
            AlexaBad_TTS.sendCommand(text)
            AlexaArbeitszimmer_TTS.sendCommand(text)
            AlexaKueche_TTS.sendCommand(text)
            if (Anwesenheit == OFF) {sendBroadcastNotification(text, "contact", "Info")}
			else {
				if (UniFiWirelessClientRobert_Online.state == ON) {sendNotification("abc@abc.de", text, "contact", "Info")}
			}
            contactTimers.get(vTimerName)?.reschedule(now.plusMinutes(5))
        ])
    } 	
	else
        contactTimers.get(vTimerName)?.cancel
end
Es erscheint folgende Fehlermeldung im Log:

Code: Alles auswählen

2025-07-05 16:59:37.035 [ERROR] [.handler.AbstractScriptModuleHandler] - Script execution of rule with UID 'Lueften-test-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.StringExtensions.operator_plus(java.lang.String,java.lang.String) on instance: null in Lueften-test
Kann mir einer helfen? Vielen Dank.

Gruß

Robert

Re: Regel Lüften Warnung - Timer basierend auf Item

Verfasst: 5. Jul 2025 22:22
von Harka
Moin,
auch ohne Ahnung von Rule-DSL fällt mir in "createTimer(now.plusMinutes(vTimerTime)" eine fehlende Klammer auf. Warum behandelst Du vTimerTime erst als String und dann als Number? Das mögen viele Sprachen nicht.

Re: Regel Lüften Warnung - Timer basierend auf Item

Verfasst: 5. Jul 2025 22:54
von technick90
Die fehlende ( ist ein Copy and Paste Fehler. Hatte zum Test Seconds in der Regel und habe es hier im Forum in Minutes geändert. Dabei ist die Klammer gelöscht werden.

Variable habe ich nun wie folgt deklariert:

Code: Alles auswählen

var Number vTimerTime = "13"
Nun erscheint folgende Fehlermeldung.

Code: Alles auswählen

Script execution of rule with UID 'Lueften-test-1' failed: An error occurred during the script execution: Could not invoke method: java.time.ZonedDateTime.plusSeconds(long) on instance: 2025-07-05T22:33:25.335688154+02:00[Europe/Berlin] in Lueften-test
Meine Versuche das zu lösen sind gescheitert. Habe die Variable als int definiert, das Item mit % 0.f formatiert. Aber es bleibt bei dem Fehler.
Ich weiß nicht wie ich das Item korrekt verwende.

Re: Regel Lüften Warnung - Timer basierend auf Item

Verfasst: 6. Jul 2025 06:30
von Harka
Moin,
versuch mal

Code: Alles auswählen

var Integer vTimerTime = 13
Quelle: viewtopic.php?p=63411#p63411