Close garage door if there's no motion


I’m trying to close a garage door when there is no motion in the garage.

2) What is the expected behavior?
When there hasn’t been any motion in the garage for five minutes, the garage door will close.

3) What is happening/not happening?
It looks like the piston is controlling the garage door contact instead of subscribing to it.


5) Attach logs after turning logging level to Full
|+13ms|╔Subscribing to devices…|
|+16ms|║Using Attribute subscription|
|+46ms|║Device missing from piston. Loading all from parent (29ms)|
|+54ms|║Subscribing to Garage Motion.motion…|
|+62ms|║Piston controls Marshall’s Garage Door Status…|
|+64ms|║Piston controls Marshall’s Door…|
|+83ms|╚Finished subscribing (74ms)|
|+100ms|║Comparison (enum) inactive stays (string) inactive = true (2ms)|
|+102ms|║Cancelling condition #2’s schedules…|
|+109ms|║Comparison (enum) open is (string) open = true (1ms)|
|+111ms|║Cancelling condition #6’s schedules…|
|+112ms|║Cancelling condition #1’s schedules…|
|+120ms|╔Starting piston… (v0.3.110.20201015_HE)|
|+122ms|╚Piston successfully started (114ms)|
indent preformatted text by 4 spaces


This is the Hubitat version of webCoRE. I am assuming that it is basically doing the same sort of thing as the SmartThings version but with changed wording.

The piston begins with a ‘stays’ condition which is classed as a trigger. This causes the piston to subscribe to the device attribute it is using, the Garage Motion motion. There are no other triggers so that is the only subscription.

The piston also uses Marshall's Garage Door Status and Marshall's Door in a condition and an action. These aren’t being subscribed to but it is useful to know they are used in the piston, and that is what ‘Piston controls’ is acknowledging.

In SmartThings, a list of legacy apps a device is used in appears on a device’s page in the IDE and used to also appear in the Classic app. This is actually a list of legacy apps subscribing to the device so what SmartThings does is to make it look as if is subscribed to the devices without actually subscribing. So it says ‘Subscribing’ for both categories but only includes the attribute for the real subscriptions and uses different colours in the log.


I thought the other trigger was the contact sensor being open. I’m sorry, I’m new to this.

It should be, if the door is open and there’s no motion for 5 minutes, close the door.


When you are using one of the conditions classed as a ‘trigger’ you are explicitly defining an event that is of particular interest to you. In your case by using the stays trigger you have explicitly stated that you want your piston to subscribe to changes to the Garage Motion device’s motion attribute and to run when one occurs. As there are no other conditions classed as triggers that is the only thing that makes your piston run automatically.

As things stand, the piston will close the door after any five minutes of inactivity in the garage. So if you have been in the garage five minutes before the door is opened it could get closed instantly.

If you change the order of the contact and motion around as you suggested the change to motion inactive has to happen when the door is open for the timer to start, which I think is probably what you want.

The edge case is when you open the door and don’t go in the garage as the piston won’t fire.


I tried changing it around. If there’s no motion and if the door is open, close the door. That didn’t work.

I don’t understand why the log says it’s controlling something I list as a condition. No where below the with line does it say “Marshall’s Garage Door Status” so why would it be controlling it?

It should be looking at the status of the door and if it’s open then execute lines below “with”.

Instead of using “is” I changed it to “stays” now it reads if the door stays open and the motion stays inactive, it works as intended.

Can you not mix conditions and triggers?


You can use conditions and triggers in a piston.

It is important to understand triggers (the lightning bolt) as these cause the piston to wakeup to re-evaluate status).


  • something wakes up your piston (a device event, or a timer you set (directly or indirectly)
  • your code then runs
    • conditions generally don’t wakeup
      • (there is a special case if you ONLY have conditions in the piston that webCoRE treats them like triggers for you)
    • triggers these wakeup the piston to run

On using various ‘stays’ here is more of a writeup and simple examples.