runIn does not run at specific intervals

@AaronZON is correct, runIn expects (at least) two arguments - delayInSeconds and hanlderMethod:

runIn(delayTimeInSeconds, handlerMethod)

We’re working on some documentation updates that should help clarify this.

Thanks!!!

what would the handlerMethod be if I just want it to continue with the next else if statement?

I think you have to organize your code so that the stuff you want to do after the delay is in another handlerMethod. The way to think about this is that when runIn is executed, the result is the creation of a scheduled event (or cron job). Once the job is scheduled, code execution continues immediately, through to the end of the handlerMethod.

1 Like

We just added some new documentation around Scheduling that you may find useful:

Jim, quick question: in http://smartthings.readthedocs.org/en/latest/smartapp-developers-guide/scheduling.html#limitations-best-practices you say:
“For example, if you schedule a job at 5:30:20 (20 seconds past 5:30) to execute in five minutes, we expect it to be executed at some point in the 5:35 minute.”

Do you really mean 5:35 there? I would have thought it would be “we expect it to be executed at some point in the 5:30 minute”.

Also, one thing which is not clear from the updated documentation: are scheduled events ever “dropped”? Suppose I schedule an event to be triggered every 60 seconds; and suppose at some point one event is X seconds late; is that event going to be dropped (never fired) if X > 60 seconds (or some other amount of delay in seconds)? Or is ST eventually going to fire all of them anyway? My experience seems to suggest that delayed events are indeed dropped at some point.

Thanks.

Super, @Jim! A few questions/comments:

You seem to be describing 2 behaviors of schedule(). The second one is clearly ‘every day at the same time’ and matches what’s already in the SmartApp Class Summary. I’m not sure what you are saying in the first one, however, and how schedule() knows which behavior to execute.

Does schedule() expect the first argument to be a java date object (I may have some terminology wrong) or does it matter? Will it take a long value and understand it as epoch? If so, why not recommend the use of now() instead of new Date(). I have to admit, in my newbishness, I still haven’t quite got my head around new Date().

I appreciate the inclusion of . . .

When using runIn with less than one minute from now, your mileage will vary

. . . in the docs, however, there doesn’t appear to be any guidance for a best practice to make something happen in less than one minute. I think we need that.

When using runIn with less than one minute from now, your mileage will vary

@Jim, I understand this limitation but as @AaronZON said above, is there a way to make something happen less then a minute. My issue is that i’m creating a SmartLock app where the door will automatically lock after X minutes. But I have included that if you unlock, lock, then unlock again within 10 seconds, the automatic lock will be disabled.

I’ve run into tons of problems with the 10 second part. Sometimes it fires after 2 seconds, sometimes never. Is there any way to reliably achieve this?

Also will the local app engine in the 2nd gen hub fix this?

Thanks

I mean 5:35, since it was scheduled to execute in five minutes from 5:30:20.

Are you using runIn? If you are using runIn, there is the optional overwrite parameter that you can pass to indicate that the most recently scheduled event does not replace the previously scheduled event.

OK, sorry, I missed that

No; I was referring to events scheduled through schedule() to happen every X minutes.

Right or wrong, the way I think of this is that scheduled jobs go into a queue and wait. If, it remains in the queue past the scheduled time (for whatever reason) and, in the meantime, you schedule another occurrence of the same handler, unless you have specified otherwise (via the [overwrite: false] option), the old shceduled event would be replaced by the new and the old would never fire. Someone correct me if I am wrong.

If that’s the way it’s intended to work, and if that’s the way it works, I can live with that.
What I’m looking for is clarity (specs) about how things are meant to work. Whether that’s right or wrong, as you suggest, that’s a different discussion.

@AaronZON schedule can take several different types/formats of arguments, which is why you see them called out separately. It can take a Date object, which will then create a schedule to execute the handler method every day at the time represented by that date object. It can also take a string, which may be a cronExpression, or a string in ISO-8601 format (this is the format of any time variables populated by preferences). So there are actually two documented schedule methods here - one that takes a Date, and one that takes a String (which can be in different formats). Perhaps I can clarify this better in the docs…

Regarding scheduled jobs being dropped, @minollo I think you’ve uncovered some gaps in these docs around this - I’ll find out and update appropriately. Like you said, we need to have clarity for how it actually works.

@AaronZON @ericcirone I will follow up about the less than 60 seconds schedule granularity, and see if there are plans to handle this more reliably in the future.

Thank you all for your detailed feedback and questions!!!

Thanks @Jim. Actually, you list 3 schedule() methods.

The first references the cron expression. The cron syntax is pretty well documented and can handle quite a broad range of options.

The second is this:

I don’t know what ‘according to the specified dateString’ means. In the example below it, the value comes from preferences() so it should be a string conforming to ISO-8601. ISO-8601 defines the representation of calendar dates and time. Do you mean here that event is scheduled once per day at the time represented by the dateString? If so, it could be clearer.

The 3rd shows ‘schedule(dateTime, method)’ and I think I know that new Date() returns a Date object, so, this must be the case of the schedule() taking a Date object.

Finally, just so I’m clear, schedule() will not take a long epoch time. . . correct?

You are correct, and I’ll update the docs to be clearer.

Well, it will take a Long. It just has not been officially documented/supported yet. I’ll work with the engineering team to see if we can lift that restriction.

1 Like

So, maybe the way to define schedule() is to define it as one method that schedules an event every day at a time specified by the first argument. Then, define the forms the argument may take (java Date object, ISO-8601, cron, long/epoch). Also, to define what happens if the argument includes date information - I think all of the possible forms do include or may include date information which is probably ignored (as opposed to throw an error).

Thanks for your attention to this, @Jim!

That’s a good idea. It may not be quite that neat simply because a cron expression is different and more powerful than just a once-per-day-at-this-time schedule. I’ll get working on something. Expect an update early next week.

p.s., you guys are awesome - I feel bad for other docs writers who don’t get this kind of thorough feedback so quicky! :smile:

2 Likes

good point. Maybe that has to be separate. Looking forward to seeing what you come up with.

@Jim does , [overwrite: false] also apply to runOnce?

It does.

I’ll update the docs. (I’m saying that a lot here… I need a cool acronym for it. How about “I’ll UTD”? :smiley:)

2 Likes

@Jim - if you see my reference code above, basically in my function was executing some commands then scheduling itself to be called again using runIn() after 13 seconds. This is what I see in the live logger:

858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:07 PM: debug code 17
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:06 PM: debug code 16
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:06 PM: debug code 15
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:05 PM: debug code 14
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:04 PM: debug code 13
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:04 PM: debug code 12
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:03 PM: debug code 11
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:02 PM: debug code 10
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:02 PM: debug code 9
858fa556-f2a8-40ad-b68f-6223f9beee97 4:57:01 PM: debug code 8

notice the timestamps, each time the function runs it increments a counter and call runIn with a 13 second delay. It’s not waiting 13 seconds to run. That’s also a bug I see