The runIn method is scheduling things behind the scenes, our scheduling of smart apps all just take a method name to be called at the scheduled time. That means when this executes it is a new “run” of the smart app.
For a closure to be executed like you are showing we would need to keep a reference to that closure which depending on how long that runIn is for means holding way too many references in memory and that the execution would need to happen inside the same JVM which isn’t as resilient as being able to make a new call to a smart app method.
I’d wager I’m going down a similar mental path that @obycode was on. Looking at how to best apply a variable delay to an action in the rules engine I’m working on. I was hoping that SmartThings would allow me to use runIn() on a device command, but it doesn’t look like there is an easy way to do that. Just curious, @obycode, did you come up with an approach that will work for you? I’d be interested to see how you approached it if you’re comfortable sharing.
I’m probably going to avoid runIn() and just implement the delay on my end. Right now, for time based triggers (i.e. run something at 6:30 PM) I am saving the time value in the database. I have a very simple program that is scheduled to run once per minute, it queries the database for any time triggered rules and evaluates them. Any of the rules evaluate as passing are executed by sending a command to SmartThings via the API. For time based delays I’m probably going to do something similar. If a time delayed action is called, I will insert a row into the database with the time that it should execute. The program that runs each minute will be adapted to also look for any actions that need to be executed during that minute and send the execute commands.
Yup, definitely running into the same problem. I’m still working on my solution… I was actually just testing it. If I get something that is not just a hack, I’ll share it for you and others. There are actually two problems, one is the inability to pass a closure to the schedule functions, and the other is the 4 scheduled events per SmartApp limit. The solution I’m working on handles both.
I think your case will be easier to handle, as you have the added benefit of the separate server there that can do polling, while my solution needs to do everything within the SmartApp (I can’t constantly poll from your iPhone).
I ended up basically managing a queue of scheduled tasks myself, and using runOnce to schedule the task at the front of the queue. When I have some time, I’ll try to separate it out enough from the rest of my code so that it could be generally useful.