How to set up delay between actions for multiple switch smart apps?

In my application, I am interfacing between the relatively fast world of Smartthings and the relatively slow world of X10. (It’s one of the challenges of investing in home automation long ago)

So I have set up a smart app to control multiple devices using:

    section {
         input "theSwitch", "capability.switch", title: "Which is the master switch"
         input "theSwitches", "capability.switch", title: "Which switches will you control?", multiple:   true, required:   false    

The first line sets up the master control, the second one lists the potentially many switches to be controlled in response to the master. So far so good.

If I just let it fly, Smartthings will iterate through all of the switches listed when the SmartApp is installed. But this goes too fast for X10 to keep up. Is there a way to add a delay between each firing of the Smartthings as it iterates over the list of controlled devices?"

I tried something like this in the event handler, but ummm… didn’t work.

def on() {
	sendEvent(name: "switch", value: "on", isStateChange: "true", delay: 250)

But of course, that is not guaranteed to work since SmartThings is asynchronous.

I think I have to somehow override the multiple device command and send the commands to each selected theSwitches individually with a long enough delay to ensure some separation in time.

So, I tried catching each instance of the to-be-controlled switches and set up a runIn() method to trigger each of them to run 1 second apart.

def switchOffHandler(evt) {
    def int delayIncrement = 1
    def int currentDelay = 1
    log.debug "MULTISWITCH: off"

    def individualSwitch
    theSwitches.each { eswitch ->
        individualSwitch = eswitch
        log.debug "switchname: ${individualSwitch.displayName}"
        runIn(currentDelay,makeItGoOffLater, [data: [theSwitch: individualSwitch]])
        currentDelay += delayIncrement

and the makeItGoOffLater method looks like this:

def makeItGoOnLater(theSwitch) {
    sendEvent(name: theSwitch, value: "on", isStateChange: "true")
        log.debug "Sent event with ${theSwitch}"

I get some sense that it is properly stepping through the various switches in the .each loop above… but the events never trigger.


Try using the delay ( milliseconds) command in between your events.

So for a half-second delay, use

delay( 500 )

That sounds logical, and I did try it. Thanks for the suggestion.

When I embed the delay() in a method like this:

   def sendOnSlowly() {
      delay (500)

the result is only that the whole batch of ON messages get sent all at once, but later.

I think that my challenge is figuring out to to send the on() event to each individual switch in the group of switches. In other words, if I have the name or ID of each of the switches to be turned on, how do I send a message to just one of them?

Thanks for engaging, I appreciate it.


Assuming that you (in your preferences) defined “switch” to be the switches that you want to control, then instead of

def sendOnSlowly() {
delay (500)


switch.each {

Well, I played with it all evening… the delay(500) as a statement and [delay: 500] as an addon to an .on() statement eventually worked without errors, but the actual physical delay never happened. The two events fired immediately and together.

I never got the runIn() command to produce a delayed response either.

I was able to fake it out by doing a useless for-loop that just took up time, but that seems like a waste.

Is there a chance the delay capability just doesn’t work in ST groovey yet? or now?

I gave up and used pause(). I know it is going to be phased out, but it is the only thing that works reliably.

When you say you tried using it as an addon, do you mean that you entered

switch.on([delay: 500])

Yeah… It kind of worked sometimes, but not with consistent results.

Since runIn() is not guaranteed to run in precisely the number of specified seconds… clearly stated in the documentation for runIn(), I thought that might be an option if I set the delay parameter to be at least a couple of minutes. But even that provided uneven real performance.

For now, pause() is working like a charm and I guess I’ll just use it until it gets shot in the head by the next release. It’s too bad, because it’s truly the simplest answer for this situation.

Thanks for your help.