runIn does not run at specific intervals

I’m writing a code that has to perform 60 actions with a 10 second delay in between so I use the runIn(10, function) to do that. The function schedules a call back to itself using the same runIn(10, function)

After about 7 times it stops getting called. However if I use runIn(7, function) it works fine and calls the function in 7 seconds 60 times without an issue.

But I need 10 seconds, any one know why in 10 seconds the runIn stop working after a few times but work with 7 seconds?

@bflorian , @duncan looping you guys in from a coding/platform perspective.

In my experience, runIn with intervals < 60 seconds is extremely unreliable.

I agree with @minollo. Using runIn with intervals < 60 seconds has been an issue for many. Try using runOnce instead. 60 actions that quickly back to back might cause some lag though, so good luck!

I’m looking for minimum guaranteed, say I ask 5 seconds and it runs in 10 seconds, I’m okay. But here with 7 seconds it isn’t running after a few executions.

@Sticks18 I’ll try it

also @Sticks18 doesn’t runOnce behave like Schedule()? In that case it won’t run if the time is less than 60 seconds

Well it’s working for now, will update if I see any issues. Thanks guys.
FYR, this is the reusable code to schedule a function in seconds:

def startTimer(seconds, function) {
    def now = new Date()
	def runTime = new Date(now.getTime() + (seconds * 1000))
	runOnce(runTime, function) // runIn isn't reliable, use runOnce instead
}

Honestly I have no idea why it works and runIn doesn’t. Just something that I’ve read from others around here. Glad it seems to be working for you!

yeah I take it back, after about 15 times it stops :frowning:

Open to ideas

I spent some time beating my head into a wall trying to figure out why a stupid-simple app I wrote wasn’t working. I had it narrowed to the runIn call I had. I found a post suggesting that runIn was the preferred method to get something to happen <1 minute in the future. I also found a post suggesting that runIn didn’t work for times less than 60 seconds. Hmmmm. . . Anyway, in the stupid-simple app I wrote, I was testing with 10 seconds to save time. I changed this to 60 seconds and it started working. The documentation for runIn doesn’t call out any limitations. If there are limitations, and/or there is a preferred method ST would like us to use, I would certainly like to see it in the docs or at least in some sort of notice here.

Hey guys, I’m looking into the questions around using runIn for intervals less than a minute. I’ll update the docs and reply here when I clarify this.

3 Likes

Much appreciated, @Jim. More broadly, I suggest that the documentation of all methods that result in a scheduled event clearly state that and include a link to the documentation of any rules associated with scheduled events - I think I read somewhere that a SmartApp may only have 4 outstanding scheduled events at any given time. Then, in the documentation of the rules for scheduled events, there should be clear differentiation between rules that apply when a V1 hub is used vs a V2 hub. I would assume that the concerns about server traffic are mitigated by the availability of a local rules engine in the hub itself. Thanks again!

@AaronZON is there a difference between the V1 and V2 hubs? I thought the hubs were just a gateway and did nothing more than that.

@RBoy, from the press release:

The new SmartThings Hub includes a more powerful processor and local app engine, built-in backup battery power, and expanded cellular connectivity. This will enable SmartThings to continue operating in the event of a power or Internet outage.

I’m interpreting this to mean some or all of the rules engine/apps would execute locally meaning any limitations based on server traffic would no longer be. I think this means you would be able to have an app do something every 10 seconds (like you had posted at the beginning of this thread) without being subject to any arbitrary (but for good reasons) rules designed to manage traffic. Obviously, we will have to wait for details to be revealed. Maybe we can get @Jim to inadvertently reveal some details in his clean-up of this documentation ;-).

WRT to calls to runIn calls being dropped, @RBoy do you have a simple code sample you can post so we can see the problem? It’s not expected that runIn works for 7 seconds, but not for 10. We can pass this on to the engineering team to investigate.

As others have pointed out, calls to runIn (or other scheduling APIs) are processed in the cloud, and thus subject to timing variances. We can’t guarantee to-the-second precision, but the calls shouldn’t just be dropped.

As far as that changing when using a v2 hub, it’s too early to make any statements or promises. If the timing variance expectations change in v2 hub, we will document that.

@Jim, In my testing, I was using 10 seconds for the runIn on line 61 and could not get this to work. After I investigated, I tried 60 seconds and it worked. The original requester was looking for 1 minute period so I just changed to code to allow a minimum of 1 minute for this runIn.

I run this app at my house. I have a 3 second delay implemented with a runIn that seems to work most of the time. Sometimes it does not. The suspect runIn is on line 217 in the gotDark() handler. This runs once per day and the issue corrects itself if motion is sensed, so, honestly, I have not paid close attention to this on a daily basis. I do clearly remember testing it on my house and observing it working.

Here’s a simple example @Jim :

def initialize()
{
  runIn(1, test)
}

def test()
{
  log.debug "test called"
  runIn(10, test)
}

This stops running after a few times

Does this example stop executing in the IDE or only when installed on a mobile device? I tried that example in the IDE (I changed the log statement to display the date so I knew when it was executing), and it ran for an hour.

Mobile device @Jim - I only test on mobile devices

> private scheduleAction(evt) {
>     	if (delayTime.toInteger()) {
>         runIn(delayTime.toInteger() * 1)
> 	}
> }


else if (opt == "4") {
sb << delim
sb << "Today's headline, "
if (isMetric) {
     sb << rss1.channel.item[0].title
          scheduleAction(evt)  
   }

Hi guys,

I’m trying to mod the Sonos Weather Report to do RSS feeds. I got everything working but I just cant get a 5 second pause in between each feed. Can anyone point me in the right direction, I am quite clueless when it comes to any programming.

I’m probably just as clueless as you but I think you are missing an argument in your runIn() statement. According to the docs, the call should look like: runIn(delayInSeconds, handlerMethod). Looks like you have delayTime.toInteger() * 1 which I suspect resolves to 5 seconds and is the delayInSeconds argument. You also need a coma, then a method where the method would be defined elsewhere and be the the code to start the next feed.

However, the point of this thread is that runIn doesn’t always seem to work for whatever reason, particularly for delays less than one minute. So, even if you resolved the syntax, I’m not sure if it would work. Based on my limited experience, you might find that it works sometimes and not other times.