Regel Lüften Warnung - Timer basierend auf Item

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
technick90
Beiträge: 43
Registriert: 24. Jul 2019 16:56
Answers: 1

Regel Lüften Warnung - Timer basierend auf Item

Beitrag 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

Harka
Beiträge: 492
Registriert: 30. Apr 2021 13:13
Answers: 19

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

Beitrag 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.

technick90
Beiträge: 43
Registriert: 24. Jul 2019 16:56
Answers: 1

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

Beitrag 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.

Harka
Beiträge: 492
Registriert: 30. Apr 2021 13:13
Answers: 19

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

Beitrag von Harka »

Moin,
versuch mal

Code: Alles auswählen

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

technick90
Beiträge: 43
Registriert: 24. Jul 2019 16:56
Answers: 1

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

Beitrag von technick90 »

Moin,

das war es wohl nicht, die feste Defintion (Notfall, falls Item nicht gesetzt) hat auch funktioniert.
Habe es dennoch lösen können:

Code: Alles auswählen

if (SperrenItem.state instanceof Number) {vTimerTime = (SperrenItem.state as Number).longValue}
Aber ich glaube ich muss den Namen der vTimerTime Variable auch dynamisch abhängig vom ausgelösten Fenstersensor machen, die Regel gilt ja für die gesamte Gruppe und die Variable wird sonst überschrieben. Das muss ich nochmal testen.
Vielen Dank erstmal.

technick90
Beiträge: 43
Registriert: 24. Jul 2019 16:56
Answers: 1

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

Beitrag von technick90 »

Es scheint zu funktionieren. :-)

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","SperrenTime")
    val GenericItem SperrenItem = ScriptServiceUtil.getItemRegistry?.getItem(itemNameSperren) as GenericItem
    var vName = triggeringItem.name.split("_").get(1)
    var vTimerName = "timer_" + vName
	var Integer vTimerTime = 13
    contactTimers.get(vTimerName)?.cancel;
    if(triggeringItem.state == "Offen") {
		if (SperrenItem.state instanceof Number) {vTimerTime = (SperrenItem.state as Number).longValue}
        logInfo("INFO", "Fenster geöffnet: " + itemName + " seit " + vTimerTime)
		contactList.put(vTimerName,true)
        contactTimers.put(vTimerName, createTimer(now.plusMinutes(vTimerTime)) [|
            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.com", text, "contact", "Info")}
			}
            contactTimers.get(vTimerName)?.reschedule(now.plusMinutes(5))
        ])
    } 	
	else
        contactTimers.get(vTimerName)?.cancel
end

Antworten