Cannot get timer to work - how to properly convert int value to be used in timers

Tags: #<Tag:0x00007f617ec08b40> #<Tag:0x00007f617ec08708>

Hi,

I am trying to get a timer to work to disable a relay after some minutes.
I’m fighting since a couple of days, and the rule is correctly starting the relay, however it is never entering the timer.
Here is the error in the logs:

2020-09-15 22:55:50.005 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'timer test': An error occurred during the script execution: Could not invoke method: org.joda.time.DateTime.plusSeconds(int) on instance: 2020-09-15T22:55:50.005+02:00

I am building the timer using value from temperature sensor. Here is the code doing that:

rule "timer test"
when
   Time cron "0 0/2 * * * ?"   // every 2 minute
then
   var Timer pumpTimer = null

   var Number timerRelay = Shelly1Piscine_SondesTemp3.maximumSince(now.minusHours(15)).state
   logInfo("timer", "Température de la Veille = " + timerRelay )

// Durée de fonctionnement de la pompe environ la moitié de la température extérieure. Soustraction de 4h, convertir en minutes
   timerRelay = (timerRelay/2 - 4) * 60
   logInfo("timer", "Minutes - timerRelais = " + timerRelay.floatValue )

// Conversion en un multiple de 128 minutes
   timerRelay = Math::round(timerRelay.floatValue / 128) // * 128     
   logInfo("timer", "Round - timerRelais = " + timerRelay )
   timerRelaisPiscine.postUpdate(timerRelay)
   logInfo("timer", "timerRelaisPiscine = " + timerRelaisPiscine.state )

// Convert timer to int
 val Integer timerRelaisPiscineNum = timerRelaisPiscine.state as Number
//   val timerRelaisPiscineNum = Integer::parseInt(timerRelaisPiscine.state)
   logInfo("timer", "timerRelaisPiscineNum = " + timerRelaisPiscineNum )

   if(pumpTimer === null) {
		pumpTimer = createTimer(now.plusSeconds(timerRelaisPiscineNum),  [ |
//      logInfo("test", "pumpTimer exit = " + timerRelaisPiscineNum.state )
		logInfo("test", "pumpTimer exit = inside timer" )
		pumpTimer = null
	])
   }
end

I am getting correct values in the logs:

2020-09-15 22:55:50.003 [INFO ] [eclipse.smarthome.model.script.timer] - Température de la Veille = 25.9
2020-09-15 22:55:50.004 [INFO ] [eclipse.smarthome.model.script.timer] - Minutes - timerRelais = 537.0
2020-09-15 22:55:50.004 [INFO ] [eclipse.smarthome.model.script.timer] - Round - timerRelais = 4
2020-09-15 22:55:50.004 [INFO ] [eclipse.smarthome.model.script.timer] - timerRelaisPiscine = 4
2020-09-15 22:55:50.005 [INFO ] [eclipse.smarthome.model.script.timer] - timerRelaisPiscineNum = 4

It seems from the error that now.plusSeconds(timerRelaisPiscineNum) is being converted in timestamp which createTimer doesn’t like. If I put numerical value in the plusSeconds() command, it works fine.

What am I doing incorrectly?

Thanks

What type of Item is this?
If it is a simple Number type … change this

(which I suspect is not giving an Integer at all, Rules DSL is loosely typed)

The more usual method is -
val timerRelaisPiscineNum = (timerRelaisPiscine.state as Number).intValue

However …

This is heading for disaster. Items are not standard variables.
Updating Items is asynchronous, it fires the update off onto openHABs event bus but the rule carries on executing, it does not stop and wait.
Some time later, the Item actually gets updated.
If you read the Item state in the same rule you are quite likely to get the “old” state from before your postUpdate has taken effect.

That’s okay, you don’t need to read that state back. You already know what you just sent in your postUpdate, use that directly.

timerRelaisPiscine.postUpdate(timerRelay)
...
val timerRelaisPiscineNum = timerRelay.intValue

I have defined timerRelaisPiscine as a number in .items file:
Number timerRelaisPiscine "Timer pour la pompe de piscine"

Thanks, will try this.