Can't pass variable to createTimer in lambda... sometimes

I have a lambda that controls some dimmer lights when motion is detected. One of the variables that is passed to the lambda is the length of time in minutes that the lights should be turned on for after motion is detected. I would like to extend the code so that rather than turning the lights off after the timeout period, they should be dimmed to 50% for fifteen seconds before being turned off to give the occupants of the room a hint that they need to wave an arm or shake a leg to trigger the motion detector which will return the lights to 100% brightness and restart the timer.

The crucial piece of code (that currently works) is this:

		timeout = time
		logInfo("dev", "NG2: creating OFF timer. Timeout = (" + (timeout) + ") minutes.")
		logInfo("dev", "NG2: OFF Timer will expire at (" + (now.plusMinutes(timeout)) + ")." )
		timersmap.put(lightitem.name, createTimer(now.plusMinutes(timeout)) [|
                logInfo("dev", "NG2: motion stopped, turning (" + lightitem.name  + ") OFF." )
                sendCommand(lightitem, OFF)
                timersmap.remove(lightitem.name)
            ])

time is one of the variables passed in to the lambda. timeout is declared as ā€œvar Number timeoutā€. I want to add another section of the same code but with a different map and a 15 second shorter timeout to dim the lights. Something like:

	timeout = time * 60 - 15
	logInfo("dev", "NG2: creating OFF timer. Timeout = (" + (timeout) + ") seconds.")
	logInfo("dev", "NG2: OFF Timer will expire at (" + (now.plusSeconds(timeout)) + ")." )
	dimmedtimersmap.put(lightitem.name, createTimer(now.plusSeconds(timeout)) [|
                logInfo("dev", "NG2: motion stopped, turning (" + lightitem.name  + ") OFF." )
                sendCommand(lightitem, 50)
                dimmedtimersmap.remove(lightitem.name)
        ])

The strange issue I have is that it appears that if any code performs any sort of maths on the value of timeout then the call to createTimer fails with the error:

Rule 'Dev Motion Detected': Could not invoke method: org.joda.time.DateTime.plusMinutes(int) on instance: 2018-11-04T22:12:13.725Z

If i remove the maths from the assignment of timeout:

timeout = time

The error goes away. Iā€™ve tried casting timeout to Int and Number but it made no difference.

Any suggestions?

I believe the ā€¦plusMinutes et al require integer parameters. Try

timeout = (time * 60 - 15 ).intValue

or something like

1 Like

Interesting, adding .intValue has solved the problem. Thanks! Why would the error only manifest after the value of the timeout variable had had calculations performed on it?

Donā€™t know ; guess calculations are done in floating point by default. If you donā€™t explicitly assign a ā€˜numberā€™ format you get the best guess.

timeout is declared as ā€œvar Number timeoutā€. I also tried declaring it as an Int or Integer but it made no difference. Itā€™s very strange.

var Integer works for me - not quite the same class as little-i integer.