[SOLVED] Issue in group based window timer rule

Hey guys,

I have a little issue with my windows notification rule. I’ve just chnaged it, so that it is group based and this works very well, but I had the issue that there was only one timer which have been created for all the windows in the gFenster group. I’ve tried to change it now, but this ends in errors.

import java.util.Map
import org.openhab.model.script.actions.*

val Map<String, Timer> windowtimer = newHashmap
val currMonth = now.getMonthOfYear
	
var int windowtime = 0
//var windowsmessage = "Fehler"
	
    rule "Fenster Meldung"
    when
    	Member of gFenster received update
    then
		val window = triggeringItem
		//var Timer windowtimer = null
				
    	if(window.state.toString=="OPEN") {
			gFenster.members.filter[window | window.state.toString=="OPEN"].forEach[window |
				if(windowtimer.get(window.name) !== null) {
					windowtimer.get(window.name).cancel()//cancel windowtimer
					windowtimer.put(window.name, null) // remove the timer from the Hashmap
				}
				else {
					if(currMonth == 1 || currMonth == 2 || currMonth == 12) {
						windowtime = 5
					}
					else if(currMonth == 3 || currMonth == 11) {
						windowtime = 10
					}
					else if(currMonth == 4 || currMonth == 9) {
						windowtime = 15
					}
					else if(currMonth == 5 || currMonth == 10) {
						windowtime = 20
					}
					else if(currMonth == 6 || currMonth == 7 || currMonth == 8) {
						windowtime = 25
					}
					windowtimer.put(window.name, createTimer(now.plusMinutes(windowtime))) [|
						val StringBuilder windowsmessage = new StringBuilder
							windowsmessage.append(windowtime + " Minuten Lüftung abgeschlossen.")
							windowsmessage.append(transform("MAP", "Fensterkontakt.map", window.name) + " Fenster schließen.")
				
						logInfo("Fenstermeldung",transform("MAP", "Fensterkontakt.map", window.name) + "Fenster ist länger als {} Minuten geöffnet!",windowtime)
						sendPushbulletNote("DEFAULT", "riza@as-lan.eu", "Badezimmer Fenster offen", windowsmessage.toString)
						sendBroadcastNotification(windowsmessage.toString)
						say(windowsmessage, null, "chromecast:audio:kueche")
					
						windowtimer.get(window.name).cancel()  //cancel windowtimer
						windowtimer.put(window.name, null) // remove the timer from the Hashmap
						
					]
				}
			]
		}
		else if (window.state.toString == "CLOSED") {
			if(windowtimer.get(window.name) !== null)	windowtimer.get(window.name).cancel()  //cancel windowtimer
			windowtimer.put(window.name, null) // remove the timer from the Hashmap
		}
end

This is my current rule. The first thing is, that I’m using a wildcard import and I don’t know what exactly do I have to import it the right way?

[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'komfort_fenster-timer.rules', using it anyway:
The use of wildcard imports is deprecated.

But the more important thing is, that my rule is not working. If i open my “virtual window”, i’m getting the following errors

[WARN ] [me.internal.engine.RuleContextHelper] - Variable 'windowtimer' on rule file 'komfort_fenster-timer.rules' cannot be initialized with value 'newHashmap': The name 'newHashmap' cannot be resolved to an item or type; line 4, column 38, length 10
[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Fenster Meldung': cannot invoke method public abstract java.lang.Object java.util.Map.get(java.lang.Object) on null

I think for you guys it should be a little to solve this issue. I would be very happy if you could help me.

Regards,

Riza

First of all, this is just a warning.

Second of all, you do not need to import anything from org.openhab.

Remove that line and the warning will go away. But the warning is indicating that you must import just the classes you are using. You shouldn’t use * in an import statement.

I can’t tell what the error is. Add logging to narrow the error down to a specific line of code. The error implies that either windowtimer is null, or window.name is null or not a String on one of the windowtimer.get calls.

1 Like

Shouldn’t that be “newHashMap”, capital M?

1 Like

First of all…thank you for your help!

I’ve removed the org.openhab. import now. I took this from another thread where you (@rlkoshak ) helped someone with a similar problem, but this thread was from 2016. So maybe it is a little bit outdated.

I’ve also changed “newHashmap” to “newHashMap”. My rule looks now like below:

import java.util.Map

val Map<String, Timer> windowtimer = newHashMap
val currMonth = now.getMonthOfYear
	
var int windowtime = 0
//var windowmessage = "Fehler"
	
    rule "Fenster Meldung"
    when
    	Member of gFenster received update
    then
		val window = triggeringItem
		//var Timer windowtimer = null
		logInfo("Fenstermeldung","Status Änderung erkannt")		
    	if(window.state.toString=="OPEN") {
			logInfo("Fenstermeldung","Fenster geöffnet")
			gFenster.members.filter[window | window.state.toString=="OPEN"].forEach[window |
				if(windowtimer.get(window.name) !== null) {
					windowtimer.get(window.name).cancel()//cancel windowtimer
					windowtimer.put(window.name, null) // remove the timer from the Hashmap
				}
				else {
					if(currMonth == 1 || currMonth == 2 || currMonth == 12) {
						windowtime = 5
					}
					else if(currMonth == 3 || currMonth == 11) {
						windowtime = 10
					}
					else if(currMonth == 4 || currMonth == 9) {
						windowtime = 15
					}
					else if(currMonth == 5 || currMonth == 10) {
						windowtime = 20
					}
					else if(currMonth == 6 || currMonth == 7 || currMonth == 8) {
						windowtime = 25
					}
					windowtimer.put(window.name, createTimer(now.plusMinutes(windowtime)), [|
						val StringBuilder windowmessage = new StringBuilder
							windowmessage.append(windowtime + " Minuten Lüftung abgeschlossen.")
							windowmessage.append(transform("MAP", "Fensterkontakt.map", window.name) + " Fenster schließen.")
				
						logInfo("Fenstermeldung",transform("MAP", "Fensterkontakt.map", window.name) + "Fenster ist länger als {} Minuten geöffnet!",windowtime)
						sendPushbulletNote("DEFAULT", "riza@as-lan.eu", "Badezimmer Fenster offen", windowmessage.toString)
						sendBroadcastNotification(windowmessage.toString)
						say(windowmessage, null, "chromecast:audio:kueche")
					
						windowtimer.get(window.name).cancel()  //cancel windowtimer
						windowtimer.put(window.name, null) // remove the timer from the Hashmap
						
					])
				}
			]
		}
		else if (window.state.toString == "CLOSED") {
			logInfo("Fenstermeldung","Fenster geschlossen")
			if(windowtimer.get(window.name) !== null)	windowtimer.get(window.name).cancel()  //cancel windowtimer
			windowtimer.put(window.name, null) // remove the timer from the Hashmap
		}
end

And I get the follwing error now:

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Fenster Meldung': index=1, size=1

What do I have to do, to add logging? Do I need to change the loglevel in the Karaf console. If yes…which package and to which loglevel? Or do you mean i should add some logging to the rule to see where the rule stops working?

Sorry guys. I’m no developer. Just very interested in openHAB and all my rules are based on other rules which I’ve found in the community

That’s a horrible error to track down, often to do with missing brackets and the like.

That will set currMonth once only, when the rules file is first loaded. You probably want to actually calculate current month during the running of the rule , unless your system is being reloaded every midnight.

1 Like

Good point! Thank you for that.

Also good to know, that it is most likely a missing bracket. I’ve already searched for missing brackets, but I will check that again to be sure.

Or I had a typo. Many of my replies are written on my phone without benefit of VSCode.

Does VSCode tell you anything?

I was using Notepad++ with the Syntax files but have installed VSCode now. But everything looked okay in VSCode.

I’ve found the issue (and some others too). The , in windowtimer.put(window.name, createTimer(now.plusMinutes(windowtime)), [| caused this issue.

Thank you for your help. My rule seems to work now. If it should be useful for somebody…feel free :

import java.util.Map

val Map<String, Timer> windowtimer = newHashMap
var int windowtime = 0

//var windowmessage = "Fehler"
	
    rule "Fenster Meldung"
    when
    	Member of gFenster received update
    then
		val window = triggeringItem
		val currMonth = now.getMonthOfYear
		//var Timer windowtimer = null
    	if(window.state.toString=="OPEN") {
			logInfo("Fenstermeldung", window.name + "Fenster geöffnet")
			gFenster.members.filter[window | window.state.toString=="OPEN"].forEach[window |
				if(windowtimer.get(window.name) !== null) {
					windowtimer.get(window.name).cancel()//cancel windowtimer
					windowtimer.put(window.name, null) // remove the timer from the Hashmap
				}
				if(currMonth == 1 || currMonth == 2 || currMonth == 12) {
					windowtime = 5
				}
				else if(currMonth == 3 || currMonth == 11) {
					windowtime = 10
				}
				else if(currMonth == 4 || currMonth == 9) {
					windowtime = 15
				}
				else if(currMonth == 5 || currMonth == 10) {
					windowtime = 20
				}
				else if(currMonth == 6 || currMonth == 7 || currMonth == 8) {
					windowtime = 25
				}
				logInfo("Fenstermeldung","Fensterzeit = " + windowtime)
				windowtimer.put(window.name, createTimer(now.plusMinutes(windowtime)) [|
					val StringBuilder windowmessage = new StringBuilder
						windowmessage.append(windowtime + " Minuten Lüftung abgeschlossen.")
						windowmessage.append(transform("MAP", "Fensterkontakt.map", window.name) + " Fenster schließen.")
				
						logInfo("Fenstermeldung",transform("MAP", "Fensterkontakt.map", window.name) + "Fenster ist länger als {} Minuten geöffnet!",windowtime)
						sendPushbulletNote("DEFAULT", "riza@as-lan.eu", "Badezimmer Fenster offen", windowmessage.toString)
						sendBroadcastNotification(windowmessage.toString)
						say(windowmessage, null, "chromecast:audio:kueche")
					
						windowtimer.get(window.name).cancel()  //cancel windowtimer
						windowtimer.put(window.name, null) // remove the timer from the Hashmap
					])
			]
			}
		else if (window.state.toString == "CLOSED") {
			logInfo("Fenstermeldung",transform("MAP", "Fensterkontakt.map", window.name) + "Fenster geschlossen. " + windowtime + " Minuten Timer gelöscht.")
			if(windowtimer.get(window.name) !== null)	windowtimer.get(window.name).cancel()  //cancel windowtimer
			windowtimer.put(window.name, null) // remove the timer from the Hashmap
		}
end

Thanks to Riza_Aslan for share your rule.

I have a problem, question.

I am trying to implement the transform("MAP.
So Alexa Dot can speak the right name of the item and not the technical one.

But it doesn’t matter what I put in my Fensterkontakt.map, the technical name will always come up.
I have in the Fensterkontaktt.map
the name from .item, from the channel and and the name that is displayed in the log ,nothing works.

Fensterkontakt.map entry:
GFOfficeWindow=EG Büro
GFOfficeWindowFenster=EG Büro
GF_Office_Window=EG Büro

Hope someone can help me.

Thanks a lot

Best regards
Angelo

Just to be sure…did you’ve installed the MAP transformation? Please doublecheck the spelling of your MAP-file.

It looks like you have 3 different items forthe same thing?

GFOfficeWindow=EG Büro
GFOfficeWindowFenster=EG Büro
GF_Office_Window=EG Büro

Do you have created all of this Items? And are those part of your window-Group?

The tip with the missing addons helped a lot.
Now it’s working.

many thanks