hello, i’m becoming crazy to move these rules from OH2 to OH3.
i’m not a programmer, and especially in rules structure i find many difficulties, so i have to ask you.
i have these rules that from sitemap can set timer to activate and set running-time for my conditioners.
i have searched a lot on forum post to find sothing that can hekp but nothing found.
better is to set this rule from webUI instead from file, but main thing is that this rule works.
can anyone help?
actually the error is:
[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'alarm-2' failed: cannot invoke method public abstract org.openhab.core.types.State org.openhab.core.items.Item.getState() on null in alarm
here is the rule code:
var Timer timerPERSON1Wecker = null
rule "Presets Mattina-Sera"
when
Item PRESETS_MATTINA_SERA received command
then
var int sollMinute
var int sollStunde
var int RunTime
switch (PRESETS_MATTINA_SERA.state)
{
//MATTINA
case 1: {
sollStunde=7
sollMinute=0
RunTime=30
}
//SERA
case 2: {
sollStunde=20
sollMinute=30
RunTime=30
}
}
//set hour,minute,runtime items for each day
var i = 7
var Giorno= "NA"
//don't change saturday/sunday. set i max=7 and uncomment cases if you have to work weekends, you unlucky soul
while ((i=i+1) <= 5)
{
switch i
{
case 1: Giorno = "LUNEDI"
case 2: Giorno = "MARTEDI"
case 3: Giorno = "MERCOLEDI"
case 4: Giorno = "GIOVEDI"
case 5: Giorno = "VENERDI"
case 6: Giorno = "SABATO"
case 7: Giorno = "DOMENICA"
}
//set all hours
gPERSON1Wecker.members.filter(s|s.name == "PERSON1_"+Giorno+"_H").forEach[s | s.postUpdate(sollStunde)]
//set all minutes
gPERSON1Wecker.members.filter(s|s.name == "PERSON1_"+Giorno+"_M").forEach[s | s.postUpdate(sollMinute)]
//set runtimes
gPERSON1Wecker.members.filter(s|s.name == "PERSON1_"+Giorno+"_RUN").forEach[s | s.postUpdate(RunTime)]
}
end
rule "Wecker PERSON1"
when
Time cron "0 0/1 * * * ?"
then
var Oggi = ""
var boolean Wecken = false
var int sollMinute
var int sollStunde
var int RunTime
switch now.getDayOfWeek
{
case 1: Oggi = "LUNEDI"
case 2: Oggi = "MARTEDI"
case 3: Oggi = "MERCOLEDI"
case 4: Oggi = "GIOVEDI"
case 5: Oggi = "VENERDI"
case 6: Oggi = "SABATO"
case 7: Oggi = "DOMENICA"
}
if (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_"+Oggi].head.state == ON)
{
sollMinute = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_"+Oggi+"_M"].head.state as Number).intValue
sollStunde = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_"+Oggi+"_H"].head.state as Number).intValue
RunTime = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_"+Oggi+"_RUN"].head.state as Number).intValue
Wecken = true
}
if (sollMinute == now.getMinuteOfHour && sollStunde == now.getHourOfDay && Wecken==true && PERSON1_WECKER_PRESETS.state==1)
{
//WECKER_AKTIV to ON, so you can react to a move sensor downstairs or in the kitchen
// i use this for a squeezeboxspeak "Good morning. it is soandsomuch degrees"
sendCommand(PERSON1_WECKER_AKTIV,ON)
sendCommand(DaikinSoggiorno_Power, ON)
//Do Stuff here, like turn on lights,coffee machine and/or radio
timerPERSON1Wecker = createTimer(now.plusMinutes(RunTime)) [|
//turn lights,radio etc. of after defined time for day.
//sanity check turn off wecker_aktiv
sendCommand(PERSON1_WECKER_AKTIV,OFF)
sendCommand(DaikinSoggiorno_Power, OFF)
timerPERSON1Wecker = null
]
}
else if (sollMinute == now.getMinuteOfHour && sollStunde == now.getHourOfDay && Wecken==true && PERSON1_WECKER_PRESETS.state==2)
{
//WECKER_AKTIV to ON, so you can react to a move sensor downstairs or in the kitchen
// i use this for a squeezeboxspeak "Good morning. it is soandsomuch degrees"
sendCommand(PERSON1_WECKER_AKTIV,ON)
sendCommand(DaikinCamera_Power, ON)
//Do Stuff here, like turn on lights,coffee machine and/or radio
timerPERSON1Wecker = createTimer(now.plusMinutes(RunTime)) [|
//turn lights,radio etc. of after defined time for day.
//sanity check turn off wecker_aktiv
sendCommand(PERSON1_WECKER_AKTIV,OFF)
sendCommand(DaikinCamera_Power, OFF)
timerPERSON1Wecker = null
]
}
else if (sollMinute == now.getMinuteOfHour && sollStunde == now.getHourOfDay && Wecken==true && PERSON1_WECKER_PRESETS.state==3)
{
//WECKER_AKTIV to ON, so you can react to a move sensor downstairs or in the kitchen
// i use this for a squeezeboxspeak "Good morning. it is soandsomuch degrees"
sendCommand(PERSON1_WECKER_AKTIV,ON)
sendCommand(DaikinCameretta_Power, ON)
//Do Stuff here, like turn on lights,coffee machine and/or radio
timerPERSON1Wecker = createTimer(now.plusMinutes(RunTime)) [|
//turn lights,radio etc. of after defined time for day.
//sanity check turn off wecker_aktiv
sendCommand(PERSON1_WECKER_AKTIV,OFF)
sendCommand(DaikinCameretta_Power, OFF)
timerPERSON1Wecker = null
]
}
end
The error comes from the second rule defined in alarm.rules.
The error is complaining about a call to getState().
So look at all the lines containing .getState, .state. Add some logging to see what all the parts of those lines exist. Add logging to see which of those lines it’s really failing on.
Let’s say it’s
sollMinute = (gPERSON1Wecker.members.filter[s | s.name == "PERSON1_"+Oggi+"_M"].head.state as Number).intValue
What’s Oggi?
What’s "Person1_"+Oggi+"_M" evaluate to? Do you in fact have an Item of that name and is that Item a member of gPERSON1Wecker?
If that Item exists, what’s it’s state? Is it a number or is it NULL or UNDEFINED?
Hi Rich I have the same set of rules which work nicely on OH2 but somehow fall over on OH3. It is the Morning Alarm code example posted a few years back here: alarm clock
All the items exist and I have made sure none of them are Null values but it still gives the same error.
script execution of rule with UID 'alarm_masterbed-2' failed: cannot invoke method public abstract org.openhab.core.types.State org.openhab.core.items.Item.getState() on null in alarm_masterbed
Can you give an example of how we can debug these lines using logging? There is something about OH3 which has caused this to stop working.
It might be worth looking at the Alarm Clock rule template in the Marketplace. No code. Installs like an add-on. You don’t need a separate Item for hour, minute, second. Uses DateTime Items that can be populated from anywhere: Astro, iCal binding, MainUI Widgets, Android Alarm, etc. Seven Items with seven rules you don’t even have to write, just install and configure. Way less work than trying to make that old and complicated example work.
Not really because debugging a rule isn’t something you can just copy and paste. You have to understand what the rule does, how it does it, and from there you can focus in on where things are going wrong.
How do you know what line of code it’s failing on? Use the clues in the error message. If that doesn’t provide enough information, litter your rule with log statements. The last log statement you see before the error tells you that the error takes place between that log entry and the next log entry. If you have to put a log statement every other line of code.
What’s alarm_masterbed? If it’s an Item what’s its state in the rule? Log that out.
thanks the Marketplace rule looks like it may be useful but ideally I’d just like to get this working - Im still using regular sitemaps which work fine.
I’ve got alarms set up for 4 bedrooms so quite a lot of code already in place. I can see all the items in Visual Basic and they are populated fine.
This is the Masterbed_alarm rule file, there are 3 others but they all get the same error
var Timer timerMasterbedAlarm = null
rule "Masterbed preset load"
when
Item MASTERBED_ALARM_PRESETS received command
then
var int shiftMinute
var int shiftHour
var int RunTime
switch (MASTERBED_ALARM_PRESETS.state){
//early shift
case 1:{
shiftHour=6
shiftMinute=35
RunTime=30
}
//late shift
case 2:{
shiftHour=9
shiftMinute=0
RunTime=30
}
}
//set hour,minute,runtime items for each day
var i = 0
var Day= "NA"
//don't change saturday/sunday. set i max=7 and uncomment cases if you have to work weekends, you unlucky soul
while ((i=i+1) <= 5) {
switch i{
case 1: Day = "MO"
case 2: Day = "TU"
case 3: Day = "WE"
case 4: Day = "TH"
case 5: Day = "FR"
//case 6: Day = "SA"
//case 7: Day= "SU"
}
//set all hours
gMasterbedAlarm.members.filter(s|s.name == "MASTERBED_ALARM_"+Day+"_H").forEach[s | s.postUpdate(shiftHour)]
//set all minutes
gMasterbedAlarm.members.filter(s|s.name == "MASTERBED_ALARM_"+Day+"_M").forEach[s | s.postUpdate(shiftMinute)]
//set runtimes
gMasterbedAlarm.members.filter(s|s.name == "MASTERBED_ALARM_"+Day+"_RUN").forEach[s | s.postUpdate(RunTime)]
}
end
rule "Alarm MASTERBED"
when
Time cron "0 0/1 * * * ?" //every minute of the hour
then
var Today = ""
var boolean Alarm = false
var int shiftMinute
var int shiftHour
var int RunTime
switch now.getDayOfWeek{ //function to check what day of week it is 1 = Monday
case 1: Today= "MO"
case 2: Today= "TU"
case 3: Today= "WE"
case 4: Today= "TH"
case 5: Today= "FR"
case 6: Today= "SA"
case 7: Today= "SU"
}
if (gMasterbedAlarm.members.filter[s | s.name == "MASTERBED_ALARM_"+Today].head.state == ON) {
shiftMinute = (gMasterbedAlarm.members.filter[s | s.name == "MASTERBED_ALARM_"+Today+"_M"].head.state as Number).intValue
shiftHour = (gMasterbedAlarm.members.filter[s | s.name == "MASTERBED_ALARM_"+Today+"_H"].head.state as Number).intValue
RunTime = (gMasterbedAlarm.members.filter[s | s.name == "MASTERBED_ALARM_"+Today+"_RUN"].head.state as Number).intValue
Alarm = true
}
if (shiftMinute == now.getMinuteOfHour && shiftHour == now.getHourOfDay && Alarm==true) {
//ALARM_AKTIV to ON, so you can react to a move sensor downstairs or in the kitchen
// i use this for a squeezeboxspeak "Good morning. it is soandsomuch degrees"
// see rule "react to move"
//remove all references if you don't want/need this
sendCommand(MASTERBED_ALARM_AKTIV,ON)
//Do Stuff here, like turn on lights,coffee machine and/or radio
Masterbed_open_blinds.sendCommand(ON)
Lt_Masterbed_Bath_Ceiling.sendCommand(ON)
MasterbedwcShutter.sendCommand(UP)
if (Sonos_State.state != "PLAYING") //if not already playing
{
All_Zones.sendCommand(OFF) //just in case zones on
Sonos_Volume.sendCommand(20)
Sonos_Shuffle.sendCommand(ON)
Sonos_Favorite.sendCommand("Alarm")
}
masterbed_music.sendCommand(ON)
timerMasterbedAlarm = createTimer(now.plusMinutes(RunTime)) [|
//turn lights,radio etc. off after defined time for day.
//sanity check turn off wecker_aktiv
masterbed_music.sendCommand(OFF)
Lt_Masterbed_Bath_Ceiling.sendCommand(OFF)
//Lt_Masterbed_Mezz.sendCommand(OFF)
sendCommand(MASTERBED_ALARM_AKTIV,OFF)
timerMasterbedAlarm = null
]
}
end
Well, I provided you with all the steps necessary to narrow the problem down to a specific line of code and then to figure out what is going on on that line of code.
You will not be able to solve this without examining these rules one by one, determining which line of code is failing, and gather more information about why that line could be failing. No one else can do that for you.
debugging a rule isn’t something you can just copy and paste. You have to understand what the rule does, how it does it, and from there you can focus in on where things are going wrong.
How do you know what line of code it’s failing on? Use the clues in the error message. If that doesn’t provide enough information, litter your rule with log statements. The last log statement you see before the error tells you that the error takes place between that log entry and the next log entry. If you have to put a log statement every other line of code.
I did add some logging which helped to some extent - so I learnt that to output Var you do the following:
logInfo("alarm.rule", "Today=" + Today)
This was coming up null so that lead me to search for problems with the getdayofweek issue.
Anyway these seem to be working now which is the main thing - I was not looking forward to changing 5 Alarms and all the code that goes with them. I’ll put a note on the original post for the code in case others have the same problem.
yes that’s it! i was near to solution, because i found too that now has been changed in fact i have used that in another script but not this one: now.getDayOfWeek.getValue.intValue