Timer error after oh3 install

hey guys, im slowly working through the issues with oh3 and am getting my rules back up and running. can someone please have a look over the following and let me know how the timers need to work now. I know the time side of it has changed so im hoping it should be an easy fix.

here’s the relevant parts of my rule that’s got the timers and rescheduling the timer.

if	((OfficeLightsTimer !==null) && (BYPASS_Office_LightsTimer.state !== ON) && (Someones_Home.state == ON)) {
		logInfo("Auto Office Lights", "Turning on lights and rescheduling timer")
        	OfficeLightsTimer.reschedule(now.plusMinutes(Office_Timeout_Minutes_Use ))
        	Main_Office_Lights.sendCommand(Office_Main_Lights)
        	Office_Lamp_Left.sendCommand(Office_Desk_Lights)
       	 	Office_Lamp_Back.sendCommand(Office_Desk_Lights)
        	Office_Lamp_Right.sendCommand(Office_Desk_Lights)
		Thread::sleep(300)
        	Office_Lamp_Left_Temp.sendCommand(Office_Desk_Lights_Temp)
       	 	Office_Lamp_Back_Temp.sendCommand(Office_Desk_Lights_Temp)
        	Office_Lamp_Right_Temp.sendCommand(Office_Desk_Lights_Temp)
		postUpdate(All_Lights, ON)
			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])
   	 	}
if	((OfficeLightsTimer === null) && (BYPASS_Office_LightsTimer.state !== ON) && (Someones_Home.state == ON)) {
		logInfo("Auto Office Lights New", "Turning on lights and setting timer")
        	Main_Office_Lights.sendCommand(Office_Main_Lights)
        	Office_Lamp_Left.sendCommand(Office_Desk_Lights)
       	 	Office_Lamp_Back.sendCommand(Office_Desk_Lights)
        	Office_Lamp_Right.sendCommand(Office_Desk_Lights)
		Thread::sleep(300)
        	Office_Lamp_Left_Temp.sendCommand(Office_Desk_Lights_Temp)
       	 	Office_Lamp_Back_Temp.sendCommand(Office_Desk_Lights_Temp)
        	Office_Lamp_Right_Temp.sendCommand(Office_Desk_Lights_Temp)
		postUpdate(All_Lights, ON)
			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])
        	OfficeLightsTimer = createTimer(now.plusMinutes(Office_Timeout_Minutes_Use ), [|
			Rule_Office_Lights.sendCommand(ON)
		logInfo("Auto Office Lights", "Timer finished Turning Lights Off")
	        	Office_Lamp_Left.sendCommand(OFF)
 	      	 	Office_Lamp_Back.sendCommand(OFF)
        		Office_Lamp_Right.sendCommand(OFF)
        		Main_Office_Lights.sendCommand(OFF)
			OfficeLightsTimer = null
			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])
        		])
    		}
end

and in my log it states.

2021-01-09 00:00:03.325 [INFO ] [core.model.script.Auto Office Lights] - Rule triggered
2021-01-09 00:00:03.344 [INFO ] [.model.script.Auto Office Lights New] - Turning on lights and setting timer
2021-01-09 00:00:03.655 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Auto Lights-2' failed: An error occurred during the script execution: Could not invoke method: java.time.ZonedDateTime.plusMinutes(long) on instance: 2021-01-09T00:00:03.654385+13:00[Pacific/Auckland] in Auto Lights

You’ll need an integer value there (your variable Office_Timeout_Minutes_Use I think)

Here’s the complete rule. each room in my house has a similar rule.
depending on the time of day, the time the lights stay on, the brightness and colour temp of the lights are different.
side note these rules were working 100% fine before moving to oh3

var Number Office_Desk_Lights_Temp 
var Number Office_Desk_Lights 
var Number Office_Main_Lights	
var Number Office_Timeout_Minutes_Use
var Timer OfficeLightsTimer = null

val int Office_Timeout_Minutes_Morning = 5
val int Office_Timeout_Minutes_Day = 5
val int Office_Timeout_Minutes_Afternoon = 5
val int Office_Timeout_Minutes_Evening = 5
val int Office_Timeout_Minutes_Night = 10
val int Office_Timeout_Minutes_Bed = 5



rule "Auto Office Lights"

when
	Item Office_Motion changed from OFF to ON or
	Item Auto_Office_Lights changed to ON
then
	logInfo("Auto Office Lights", "Rule triggered")
	Rule_Office_Lights.sendCommand(ON)

if	(TimeOfDay.state == "MORNING") {
		Office_Desk_Lights_Temp = 60
		Office_Desk_Lights = 100
		Office_Main_Lights = 100
        	Office_Timeout_Minutes_Use = Office_Timeout_Minutes_Morning 
    		}

if	(TimeOfDay.state == "DAY") {
		Office_Desk_Lights_Temp = 60
		Office_Desk_Lights = 100
		Office_Main_Lights = 100
        	Office_Timeout_Minutes_Use = Office_Timeout_Minutes_Day
    		}

if	(TimeOfDay.state == "AFTERNOON") {
		Office_Desk_Lights_Temp = 60
		Office_Desk_Lights = 100
		Office_Main_Lights = 100
        	Office_Timeout_Minutes_Use = Office_Timeout_Minutes_Afternoon 
    		}

if	(TimeOfDay.state == "EVENING") {
		Office_Desk_Lights_Temp = 60
		Office_Desk_Lights = 100
		Office_Main_Lights = 100
        	Office_Timeout_Minutes_Use = Office_Timeout_Minutes_Evening  
    		}

if	(TimeOfDay.state == "NIGHT") {
		Office_Desk_Lights_Temp = 60
		Office_Desk_Lights = 100
		Office_Main_Lights = 100
        	Office_Timeout_Minutes_Use = Office_Timeout_Minutes_Night
    		}

if	(TimeOfDay.state == "BED") {
		Office_Desk_Lights_Temp = 60
		Office_Desk_Lights = 60
		Office_Main_Lights = 60
        	Office_Timeout_Minutes_Use = Office_Timeout_Minutes_Bed 
    		}
if	((OfficeLightsTimer !==null) && (BYPASS_Office_LightsTimer.state !== ON) && (Someones_Home.state == ON)) {
		logInfo("Auto Office Lights", "Turning on lights and rescheduling timer")
        	OfficeLightsTimer.reschedule(now.plusMinutes(Office_Timeout_Minutes_Use ))
        	Main_Office_Lights.sendCommand(Office_Main_Lights)
        	Office_Lamp_Left.sendCommand(Office_Desk_Lights)
       	 	Office_Lamp_Back.sendCommand(Office_Desk_Lights)
        	Office_Lamp_Right.sendCommand(Office_Desk_Lights)
		Thread::sleep(300)
        	Office_Lamp_Left_Temp.sendCommand(Office_Desk_Lights_Temp)
       	 	Office_Lamp_Back_Temp.sendCommand(Office_Desk_Lights_Temp)
        	Office_Lamp_Right_Temp.sendCommand(Office_Desk_Lights_Temp)
		postUpdate(All_Lights, ON)
			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])
   	 	}
if	((OfficeLightsTimer === null) && (BYPASS_Office_LightsTimer.state !== ON) && (Someones_Home.state == ON)) {
		logInfo("Auto Office Lights New", "Turning on lights and setting timer")
        	Main_Office_Lights.sendCommand(Office_Main_Lights)
        	Office_Lamp_Left.sendCommand(Office_Desk_Lights)
       	 	Office_Lamp_Back.sendCommand(Office_Desk_Lights)
        	Office_Lamp_Right.sendCommand(Office_Desk_Lights)
		Thread::sleep(300)
        	Office_Lamp_Left_Temp.sendCommand(Office_Desk_Lights_Temp)
       	 	Office_Lamp_Back_Temp.sendCommand(Office_Desk_Lights_Temp)
        	Office_Lamp_Right_Temp.sendCommand(Office_Desk_Lights_Temp)
		postUpdate(All_Lights, ON)
			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])
        	OfficeLightsTimer = createTimer(now.plusMinutes(Office_Timeout_Minutes_Use ), [|
			Rule_Office_Lights.sendCommand(ON)
		logInfo("Auto Office Lights", "Timer finished Turning Lights Off")
	        	Office_Lamp_Left.sendCommand(OFF)
 	      	 	Office_Lamp_Back.sendCommand(OFF)
        		Office_Lamp_Right.sendCommand(OFF)
        		Main_Office_Lights.sendCommand(OFF)
			OfficeLightsTimer = null
			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])
        		])
    		}
end

I think the problem is here:

			createTimer(now.plusSeconds(3), [|	        
				Rule_Office_Lights.sendCommand(OFF)
        		])

you create a timer without the timer variable. Normal way:

    corridorLightsOffTimer = createTimer(now.plusSeconds(3), [|
        Corridor_LightsState.sendCommand(OFF)
        ])

what type is your item Office_Timeout_Minutes_Use ?
just a guess into the blue. Let’s say it’s a DateTime then I’d try:

OfficeLightsTimer = createTimer(now.plusMinutes(Office_Timeout_Minutes_Use.state as Number), [|

If it’s a number item and not working then I’d go with:

OfficeLightsTimer = createTimer(now.plusMinutes((Office_Timeout_Minutes_Use as Number).intValue), [|

But all of this is just a wild guess and might be bullshit :wink:

No, that’s fine. It just makes an “anonymous” timer with no handle, so you can’t cancel or reschedule it but it works as usual.

It isn’t an Item, they’ve defined a global variable.

This needs to be used as an integer in plusMinutes().

OfficeLightsTimer = createTimer(now.plusMinutes(Office_Timeout_Minutes_Use.intValue ) ...

Really, this should have been done in OH2 as well.
You could sometimes get away with the raw Number type in OH2, but things have changed in OH3.

Hello,

I am facing currently an issue with one of my rules after upgrade to OH3 as well.

I assume it is sth. with the create timer, but I don’t have any idea. Hope someone can help me. Before the change now.plusMinutes(sollMinuten) worked like a charm. I tried it now several times.

This is the expression I am not getting ready:

Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten) [|

This is the Loginfo I get currently:

2021-05-16 18:26:15.964 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'zigbee-2' failed: An error occurred during the script execution: Could not invoke method: java.time.ZonedDateTime.plusMinutes(long) on instance: 2021-05-16T18:26:15.962178+02:00[Europe/Berlin] in zigbee

Complete rule:

///////////////////////////////////////////////
//////////////////////// 2. Wake up morning Bedroom Osram Lightstrip
///////////////////////////////////////////////
var Timer Lichtweckertimer      = null

rule "Schlafzimmer morning alarm Radio"
    when
        Item Lichtwecker_Osram changed
    then
        if(Lichtwecker_Osram.state == ON) {
            var Number sollMinuten                                                                        // define var
            if(Lichtschlauch_Wecker_H.state instanceof Number)                                            // check if value valid
                sollMinuten = (Lichtschlauch_Wecker_H.state as Number).intValue * 60                      // set var
            else 
                sollMinuten = -61                                                                         // mark as invalid
            if(Lichtschlauch_Wecker_M.state instanceof Number)                                            // check if value valid
                sollMinuten = sollMinuten + (Lichtschlauch_Wecker_M.state as Number).intValue             // set var
            else 
                sollMinuten = -1                                                                          // mark as invalid
            if (sollMinuten >= 0 ) {                                                                      // check if time valid
                Lichtweckertimer?.cancel                                                                  // cancel existing timer
                if (sollMinuten <= (now.getHour * 60 + now.getMinute)){    
                    sollMinuten = 1440 - (now.getHour * 60 + now.getMinute ) + sollMinuten }
                else {
                    sollMinuten = sollMinuten - now.getMinute
                Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten) [|
                    if((ZigLightstrip_2.state as Number) < 91 && (ZigLight1_Dimmer.state as Number) < 91) {                                      // check Level
                        ZigLightstrip_2.sendCommand((ZigLightstrip_2.state as Number) + 10) 
                        ZigLight1_Dimmer.sendCommand((ZigLight1_Dimmer.state as Number) + 10)       // Increase Level by 10 für deckenfluter und bettlicht
                        Lichtweckertimer.reschedule(now.plusMinutes(1))                                // Reschedule Timer
                    } else {                                                                              // or
                        Lichtwecker_Osram.sendCommand(OFF)                                                // switch light off
                        logInfo("morningAlarm", "Wakeup finished")
                        if (Sonos_Radio_Wecken.state == ON) {
                                timer_Sonos_WakeUp?.cancel
                                timer_Sonos_WakeUp = createTimer(now.plusSeconds(5),[|
                                    Sonos_ONE1_Volume.sendCommand(10)
                                    Sonos_ONE1_TuneInID.sendCommand("24878")
                                ]) 
                        }
                    }
                ])
                logInfo("morningAlarm", "Wecker erstellt für {}:{} Uhr",Lichtschlauch_Wecker_H.state,Lichtschlauch_Wecker_M.state)              
            } else {
                logWarn("morningAlarm", "Stunde oder Minute haben keinen gültigen Wert!")
            }
        } else {
            Lichtweckertimer?.cancel
            logInfo("morningAlarm", "Wecker ausgeschaltet")
        }
end

Someone having an idea?

Exactly the same as the preceding post, .intValue is your friend - at the point of use, in the plusMinutes()

Not all of the ways your rule might calculate sollMinuten result in an integer.

@rossko57 Thank you.

I changed the line according your hint:

Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten.intValue) [|

still getting the following error:

2021-05-16 20:35:41.674 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'zigbee-2' failed: An error occurred during the script execution: Could not invoke method: java.time.ZonedDateTime.plusMinutes(long) on instance: 2021-05-16T20:35:41.672840+02:00[Europe/Berlin] in zigbee

Do you have further suggestions?

Got any old datetime related imports at the head of that file?
Log out sollminuten to see what you are doing.
Check you are looking at the correct rule - the second one in that file.

@rossko57 thank you for the reply.

I only define var’s at the head of the file.
sollMinuten is providing e.g. 1252 before creating the timer. I log it at three points, this is a correct value. Is it in a wrong format? Second rule is correct. puh :slight_smile:

No sign of that or the results in what you’ve shown us.
But don’t care really; what is its .intValue version just before you feed that to plusMinutes()?

@rossko57 right, I did hide those lines, sorry. Thought that wouldn’t be interesting. I log at three positions.

if (sollMinuten <= (now.getHour * 60 + now.getMinute)){
                    logInfo("Test1", "T1 {}:{}",sollMinuten, (now.getHour * 60 + now.getMinute))        
                    sollMinuten = 1440 - (now.getHour * 60 + now.getMinute ) + sollMinuten }
                else {
                    sollMinuten = sollMinuten - now.getMinute
                    logInfo("Test2", "T2")}
                logInfo("Test3", "T3 {}",sollMinuten)
                Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten.intValue) [|

What do you mean with .intValue version? the first time I feed sollMinuten is

if(Lichtschlauch_Wecker_H.state instanceof Number)                                            // check if value valid
                sollMinuten = (Lichtschlauch_Wecker_H.state as Number).intValue * 60   

at the beginning of the rule. I take it from number and convert it to .intValue. Did you mean that? Log info output for SollMinuten just before the timer creation failed was based on input parameter 1252 in my last case.

That’s what I meant.

There are subtle differences in Java version, I think you’ve run into one of them.
Try
createTimer(now.plusMinutes(sollMinuten.longValue)

Hey @rossko57,

after changing the line to Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten.longValue) [| I receive a different issue notification:

2021-05-17 21:42:39.144 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'zigbee-2' failed: An error occurred during the script execution: index=1, size=1 in zigbee

Do you have a further idea?

Nope. Change it back if you think that’s the problem.

@Udo_Hartmann do you have an idea? You helped me two years ago with the rule the first time to get it running.

Searching this forum for “script execution: index=1, size=1” leads to

2 Likes

Jepp, that’s the point.

Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten) [| 
                                                          /\----- missing comma
1 Like

@rossko57 @Udo_Hartmann thank you both, that helped. Recently I adjusted the code and the issue message is gone.

I am facing now the problem, that the creation of the timer is not working:

e.g. I have created a message T3 that tells me the value of SollMinuten calculated for 2 Minutes. So the system should create the timer for 2 Minutes. SollMinuten was created as .intValue.

2021-06-20 14:41:57.438 [INFO ] [org.openhab.core.model.script.Test3 ] - T3 2
2021-06-20 14:41:57.457 [INFO ] [enhab.core.model.script.morningAlarm] - Wecker erstellt für 14:43 Uhr

But I receive the following break up:

2021-06-20 14:43:57.443 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job failed and stopped
java.lang.NumberFormatException: Character , is neither a decimal digit number, decimal point, nor "e" notation exponential mark.

This is the code at this position of code:

                Lichtweckertimer = createTimer(now.plusMinutes(sollMinuten.longValue) , [|
                    if((ZigLightstrip_2.state as Number) < 91 && (ZigLight1_Dimmer.state as Number) < 91) {                                      // check Level
                        ZigLightstrip_2.sendCommand((ZigLightstrip_2.state as Number) + 10) 
                        ZigLight1_Dimmer.sendCommand((ZigLight1_Dimmer.state as Number) + 10)       // Increase Level by 10 für deckenfluter und bettlicht
                        Lichtweckertimer.reschedule(now.plusMinutes(1))                                // Reschedule Timer

Where is my mistake? Do I have to transform the “2” again?

thank you in advance :slight_smile: