Using TimeDate to filter actions (groovy newbie)

(Brian) #1

I want to set up an audio warning for motion outside the house, but want it to not go off for a few minutes after some “suppression” events. (That is, don’t sound within say 10 minutes of one of us getting home, 5 minutes after a door opens, or 15 minutes of changing mode etc.

I’ve seen some delay functions that say “unsubscribe” and then use RunIn, but I’ve also seen mention that you can’t have very many (4?) scheduled events. Given that we could have a lot of events all preventing the audio warning, it seems to me that a good way to handle this is:
a) everytime a “suppressing event” happens, set some state variable “AlarmTimeCheck” to now+ the delay for that event.
b) when I get motion on the outdoor sensor, only sound the alarm if Now > AlarmTimeCheck.

However, I can’t seem to set that state variable with a timedate properly.

So am wondering a) am I thinking about this correctly and b) syntax to set and then compare that state variable.

Thank you!

( co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #2

The state object stores everything in JSON format, so date values can get easily messed up.

The general recommendation is to convert all Java Dates to Long (seconds since Unix Epoch, I believe). I don’t have the syntax handy … but if you’re a coder, just look it up in Java help pages.

Else… someone is bound to reply with a good code example maybe for either of us find it.

( co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #3

I can’t say for sure if this is the best way to solve your use case, but it’s not bad.

Regardless, I think your date comparisons will work best if you use the getTime() method to convert to milliseconds. There are various Template / Example SmartApps which do this, though I like to go right to the Java documentation as mentioned.


As in (roughly):

def nowInMillis = new Date().getTime()
state.AlarmTimeCheck = newInMillis + ( settings.delay * 1000 )

(Aaron) #4

now() returns the current time in milliseconds and should give the same result as new Date().time. I agree with @tgauchat, the best thing to do is to make sure all your time information is in milliseconds. When you do your runIn() calls, just do the time math in milliseconds and divide by 1000 to get to seconds which is what the runIn() method is looking for. BTW, you can have multiple runIn() calls and if they are to the same method, the newest one will overwrite the last one unless you explicitly suppress this (addresses the concern about the limit of 4 pending scheduled methods).

(Brian) #5

You guys rock! Will give that a try and let you know.

(Brian) #6

@Aaronzon thanks for pointing that out. In that case, it sounds like RunIn to the same method would actually work fine? Will try that too…