Help on creating a timer to run a check every one minute to see if motion activates


#1

I have a GE Smart Motion switch and use it with the below piston to:
a. Stay on for two minutes after motion has stopped, then turn off
or
b. if the ‘on’ toggle is manually triggered to then have the light either:

  1. stay on for 15 minutes and then have it go back to the state where if motion is activated have it stay on for just more 2 minutes after motion has stopped
  2. Just turn off after 30 minutes if no motion is sensed.

Everything works fine but after 15 minutes of the light being on and the ‘On’ toggle being manually triggered, I only check for motion every 5 minutes with bunch of If/then/elseif’s (at the 15/20/25/30 min intervals).

I would rather be checking every one minute. I know there is a way to do it with some sort of timer loop, but just dont know how to implement. If someone could show me it would be greatly appreciated!


#2

I did not dig into your piston, but I do have an observation. You have at least 9 triggers (and maybe 12) in your piston (the orange lightning bolts in the left margin). Have you considered breaking this piston up into several smaller pistons, each with an individual task? I prefer to write small, task specific pistons with a single trigger. For me, the logic is much easier to follow and debug. YMMV.


#3

Thanks for the tip on this. Generally I have much fewer triggers as well, but in this case I feel pretty comfortable about it for the following reasons:

  • 5 of the triggers are for the if/then/elseif at the 15/20/25/30 min light on timeframes. They are consecutive so they make sense and that will go away if I have a timer loop instead which is the reason for this post.

  • none of the triggers are nested. There is not even a single if/then nested within an if/then.

  • the other 4 triggers are for very simple if/then’s: : a. for motion, b. for motion off, c. if the light is manually turned on, d. when the light is turned off

They are so simplistic, they dont get in the way of each other at all. I stay away from any ‘Waits’ or ‘only when’s’ which cause 95% of my troubles.

It all works great. I just dont know how to change those 5 nested triggers in the if/then/elseif at the 15/20/25/30 minute intervals into a timer type of setup


#4

*sticks his head into the room*

I would highly encourage you to rethink this logic:

IF Switch2's motion changes
Then
    Change Switch 2's switch
END IF

IF Switch2's switch changes
Then
    Change Switch 2's switch
END IF

Generally speaking, we do not want commands to retrigger the piston again from the top.


#5

Not sure what you have above will get me to my goal. What I want to have happen is for the motion switch to do the following:

  1. Act as occupancy sensors first and foremost. If nothing is touched, have the motion turn on the light and have the light go off after ~ 3 min of no motion.

  2. Give the occupant the ability to override the occupancy sensor by manually turning the light on, but only for a minimum of 15 minutes where it will once again become an occupancy sensor to a maximum of 30 minutes where if no motion is in the room at the 30 minute mark to automatically turn the lights off. This is in the bathroom so if you take a shower you need this function or the light will turn off due to no motion.

Here is the another interation of the piston to do this in a slightly more efficient manner than the original. It still has 7 triggers but the piston seems to fire in under 15ms.

I would be very intersted in hearing how it can be done more efficiently. It seems fairly clean to me but it seems like folks here can do it a bit better. I am all for learning!


#6

I am about to head out the door, but just to clarify:

Every piston on this page has exactly two triggers.

  • Switch 2’s motion
  • Switch 2’s switch

This means the piston runs top to bottom at these 4 events:

  • Switch 2’s motion changes to active
  • Switch 2’s motion changes to inactive star
  • Switch 2’s switch changes to on star
  • Switch 2’s switch changes to off

Note: The STAY blocks create hidden timers, but these are triggered by the 2 stars above. The tricky part is, if a trigger comes in while that timer is counting down, the STAY timers often cancel.
(which is why I usually suggest using the trigger “Switch 2’s motion” in one piston, and let another piston trigger when “Switch 2’s switch” changes)


#7

And here is where I am confused…again. When first learning webcore, I was under the impression that a lightning bolt in the margin was a single trigger. So, nine triggers in the first piston posted. Then, I learned that the switch/sensor associated with that lightning bolt can have two states, on and off. So, in my brain, that is two triggers, in that the switch changing to “on” triggers the piston and the switch changing to “off” triggers the piston. But now I see that a particular “trigger” (switch 2 for instance) is only counted as a single, unique trigger. But it can be used as a trigger multiple times in the same piston. But this is off topic and offers little assistance to our friend @Levahj.


#8

Interesting comment as I have always struggled with ‘WAITS’ for the reasons you give above. Or for maybe other quirky reasons why WAITS are such a pain :slight_smile:

I have been testing this Piston for the last few hours. The STAY blocks creating the ‘hidden’ timers you mention work very well, even when they overlap. Meaning they are always keeping track even when the shorter STAY starts (i.e. the 2 minute STAY when the motion becomes inactive), even after the 15 minute STAY for the switch being on had already started. Very happy with it!

Above my pay grade a bit but like I said, this Piston is working great. I dont think its taking a lot of resources to run. It is just checking if the motion is active or inactive, or if the physical switch has been turned on, or if the switch has been turned off. All of the conditions are very simple with no embedded if/then or complex stuff going on.
The entire thing always runs in under 15ms checking all the triggers and running the ‘hidden’ STAY timers. I’m not a software or hardware guy but that seems fast. I would hope even with 5 or 10 of these running in a large home that it will not overwhelm the Hubitat Hub.


#9

Me too, brother, me too :slight_smile:


#10

Perhaps I am to blame. Let me change my wording a bit.

Every piston on this page has exactly two device attributes acting as triggers.

  • Switch 2’s motion
  • Switch 2’s switch

Every piston on this page has exactly four device events acting as triggers.

  • Switch 2’s motion changes to active
  • Switch 2’s motion changes to inactive
  • Switch 2’s switch changes to on
  • Switch 2’s switch changes to off

Having multiple identical triggers (lightning bolts) such as:
IF DeviceA's switch changes to on
is something that I usually avoid, but it should only trigger the piston once.
(so I count all “IF DeviceA’s switch does anything” as one trigger)


To elaborate, when I count triggers, I am actually counting device attributes… Since any change to that will trigger the piston. (IE: With the current version of SmartThings, it is impossible to trigger a piston on active without also triggering on inactive)


#11

I try to avoid that as well, as I did in this Piston. But does it really matter? In your example, “IF DeviceA’s Swtich changes to on” , happened to be in two places instead of one, it should still fire in both places I would assume or not? Let me know your thoughts on that!


#12

It should, but depending on the logic, it is possible that the second one will return false.
(so I tend to nest IF conditions below a single top level trigger)


#13

Seems like that would be better from a resource perspective as well so good standard practice where it can be done.


#14

I am by no means a Webcore expert, but I feel that you might have misunderstood how triggers work to trigger pistons. When a trigger is triggered, it always starts the whole piston from the top, NOT from where the trigger is located in the piston. I for one made this mistake when I was very new to Webcore, as it is somehow counter-intuitive. That’s why the experts here always suggest to write the shortest and simplest pistons. It would be much easier to understand and debug if triggers were triggering a piston at where they are in the piston, rather than from the top, but that’s not how it works.

Edit WCmore has excellently described it here: Multiple if's in a single piston. What does "runs top to bottom" mean?


#15

Apologies for the stray thought, but to embellish a bit:

One reason I do not count events is because some have dozens of possibilities

IE:

  • “DeviceA’s switch” triggers on 2 events (on and off)
  • “DeviceB’s level” triggers on 100 events (1-100)
  • “DeviceC’s temperature” triggers on 1000+ events (15.0 - 115.0)

Basically, when I count triggers, I am counting what changed. Not what it changed to.


Side Note:

That list above is somewhat of a hint why certain attributes can trigger a piston so often.
(although it does not explain chatty power triggers or motion sensors, LOL)