Is it possible to introduce a sleep()/delay in a device type?


(Minollo) #1

I have created a new device type for integrating with my Total Connect alarm system, and a few operations which connect directly to the alarm console through wireless connection require that you initiate them, and them keep “polling” them until completed (arm and disarm fall in that category).

Of course I can’t do “while (arm() != finished) {}”, as that would flood the system with requests; what I would really want to do is “while(!done) {done = arm(); sleep(5000);}”, or something along those lines. I couldn’t find a way to do that, nor to schedule an event… Am I missing something obvious? For the time being I’m starting the operation and not polling it, hoping for the best (which is ok, even if it implies keeping a connection session alive longer than needed).


(Im Brian) #2

Check out the runIn() function, documented here:
https://graph.api.smartthings.com/ide/doc/smartApp

I use it in this app if you want reference:

Alternatively, you can use “schedule()”, which you can reference in this app:


(Minollo) #3

Yes, I’m familiar with those; but I’m talking about a device type, not an app.


(Im Brian) #4

Ahh - sorry, I didn’t thoroughly read your query. My apologize - I don’t have a good solution for you.


(Todd Wackford) #5

What are you trying to do?


(Minollo) #6

…I tried to explain; I guess I failed?
I need to poll a web service from inside the device type every few seconds until some condition is satisfied.


(Todd Wackford) #7

I suggest you handle the communications with the outside world in an app. Have the device sensor and state handled in the device file.

Does this make sense?


(Minollo) #8

Surely possible; but it seems to me it’s not elegant at all, and it creates future maintenance nightmares…


(Todd Wackford) #9

OK, then create a device attribute like “ConditionReady”. Then subscribe to the attribute condition you want and have an event handler method for when it is true. Have your checking function run on a cron job to fire on a scheduled job every so many seconds/minutes. In the handler you can unschedule the cron job.

Make sense?
Twack


(Todd Wackford) #10

You can also do something like this:

.....
... some code

    def waitSeconds = 30
    startTimer(waitSeconds)
}

def startTimer(seconds) {
	log.debug "in start timer"
   
    def now = new Date()
	def runTime = new Date(now.getTime() + (seconds * 1000))
	runOnce(runTime, myTimerEventHandler)
}

def myTimerEventHandler() {
     //do the things that I want delayed in this function
     
     log.debug "doing the delayed things"
}

(Minollo) #11

Yes, it makes sense; in fact, it’s quite similar to how I’m doing things right now.
Still, I wonder why such a mechanism can’t be all part of the device type, without the need of an external ad-hoc app.


(Todd Wackford) #12

You can do the above in a device type file.


(Minollo) #13

Wait, you mean runOnce is available in a device type? Did I miss it in the documentation? Does runIn work as well?


(Minollo) #14

Well, I tried, both runOnce() and runIn(); and they are not available on a deviceType:
‎9‎:‎06‎:‎07‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script1396832766704231713829.runOnce() is applicable for argument types: (java.util.Date, java.lang.String) values: [Mon Apr 07 01:06:17 UTC 2014, myHandler]

…which brings me back to my original question.


(Tony Gutierrez) #15

Same question! I need a way in a device type to delay execution of a button press, in case the button is pressed more than once in a certain time range. Also, can confirm that currently the scheduling functions DO NOT work in device types.


(Convinced ST will never be unbroken…) #16

Have a look at the MyQ device type. But careful as too much delay can cause a timeout issue.


(Tony Gutierrez) #17

Checked that out. Very hacky, and also pauses execution, so not suitable for my purposes.


(Barry) #18

You can use “delay 1000” in a device driver to wait a second before proceeding. I had trouble with using the command directly, but found that this works reliably:

def cmds = []
cmds << "delay 1000"

(code)
cmds  // wait 1 second
(more code)

My version of the MyQ device driver uses this both in-line and in the sleepForDuration() module.


(Tony Gutierrez) #19

So it doesn’t block other execution? If not it could be used for queueing button presses.


(Barry) #20

I don’t think it blocks another event being handled by the device driver, but I haven’t tested it to prove it.