Need help with runOnce

Attempting to add a process delay using a runOnce as follows where contactDelay is 5000 milliseconds, but it wont work. Works without the delay coded.

log shows (note 1175 is the runOnce statement)
java.lang.IllegalArgumentException: Name cannot be null. on line 1175 (onContact1Event)
delayed contact event by 5000

Any suggestion appreciated.

 if (contactDelay && contactDelay > 0)
	{
	log.debug "delayed contact event by ${contactDelay}"
    def tms = now() + (contactDelay)
	def date = new Date(tms)
	runOnce(date, processEvent(deviceType, deviceState1, deviceState2, deviceState3, deviceState4, index, evt))
	}
else
	processEvent(deviceType, deviceState1, deviceState2, deviceState3, deviceState4, index, evt)

There's a good chance I'm wrong but I don't believe you can pass parameters with runOnce that way.
It would have to be runOnce(date, processEvent [data:[deviceType, deviceState1, etc]]) or similar.

Or maybe
def myList = [deviceType,deviceState1,etc]
runOnce(date, processEvent [data:myList])

In your processEvent method you would need something to parse that "data" map.

The SmartThings documentation only mentions overwrite: as a valid option in the map and data: is not listed. lists [data: ...] as a valid option key. Presumably, Hubitat should allow it to be used as well.

If a data: map cannot be passed on, since runOnce is executed independently, the only way I can think of to pass arguments is to use state objects, or a single state object to store a map of all of those arguments you are trying to pass.

Hmmm..I just dug up one of my old posts and I have this, that I remember working at the time. See snippet below. I believe the same should work for all the run's

def runSequence(){
    	runIn(3,"runTest1",[data: [num: 1]])
    	runIn(6,"runTest1",[data: [num: 2]])
}

def runTest1(data) {
    log.info data.num
}
1 Like

According to:
https://docs.smartthings.com/en/latest/ref-docs/device-handler-ref.html

runOnce()

Executes the handlerMethod once at the specified date and time.

Signature:

void runOnce(dateTime, handlerMethod [, options])

Parameters:

dateTime - When to execute the handlerMethod . Can be either a Date object or an ISO-8601 date string. For example, new Date() + 1 would run at the current time tomorrow, and "2017-07-04T12:00:00.000Z" would run at noon GMT on July 4th, 2017.

handlerMethod - The method to execute at the specified dateTime . This can be a reference to the method, or the method name as a string.

options (optional) - A map of parameters, with the following keys supported:

Key Possible values Description
overwrite true or false Specify [overwrite: false] to not overwrite any existing pending schedule handler for the given method (the default behavior is to overwrite the pending schedule). Specifying [overwrite: false] can lead to multiple different schedules for the same handler method, so be sure your handler method can handle this.
data A map of data A map of data that will be passed to the handler method.

I'm attemtping to modify an exiting app, and did was attempting to avoid changing too much code. Oh well, guess that won't happen.

Thank you that worked! It was a list so no parse was needed.
This also worked.

runOnce(date, processEvent, [data:[deviceType, deviceState1, deviceState2, deviceState3, deviceState4, index, evt]])