"Stays On/Off for at least" trigger and "Was On/Off for at least" condition only firing after the "at least" time period passes twice - See below


I am using a simple process that turns off 4 devices when a trigger light turns off. This is only to occur however, when the trigger light has been ON for at least x amount of time. My condition is - If Trigger light stays on for at least x amount of time, then do some other things and then turn off the devices (I have also used - If trigger light was on for at least x amount of time, then do some other things and then turn off the devices.

While using this, I have noted that the condition using the “was” word and the trigger using the “stay” word only cause my if statement to evaluate as true after X amount of time passes twice. In other words if I said, for instance, If trigger light stays on for at least 10 minutes, then turn off heater, then when the trigger light comes on and 10 minutes passes, it still evaluates as false. At this point the piston starts counting to 10 minutes again, and when the 10 minute mark is reached the second time, then the condition evaluates as true and the heater is turned off. This works the same way if I use the condition - If trigger light was on for at least 10 minutes. I have changed the time period to 30 seconds, 1 hour etc and the same thing happens. I would not think this is the way it was designed to work. For now if I want to check to see if the trigger light has been on for at least 1 hour, I instead have to use 30 minutes to get the desired result. Any advice appreciated but I am pretty sure this is a bug. Thanks


you might be right but can you share the complete piston that does this?


@ThePuebloPete, here is a quick example of how STAYS works:



I think it would help to see your piston. @WCmore has already illustrated how the ‘stays’ behaves, to which I’ll add that it evaluates like a condition (’ is on’) rather than a trigger (‘changes to on’). It sounds like you may be treating it as if it is a simple true/false comparison, rather than the ‘timed trigger’ it is.

The ‘was’ condition doesn’t use a timer. It just looks back at the device’s event history. Suppose you are testing if a ‘trigger light was on for ten minutes’. If the piston is running because of a reported change to the trigger light, it ignores the last event and so tests whether the light had been on for ten minutes before the last event happened. If the piston is running for some other reason it tests whether the light has been on for ten minutes and still is. The logic can be fooled if events are processed out of sequence (possible if the piston gets multiple events near simultaneously), and it is also possible for a switch to ‘change’ from on to on (depending on the device handler), which is why logs are handy.


Here is an example, I have shortened the routine but basically when the Garage is already closed another piston turns on the two lights simultaneously, then I would expect that after 25 minutes, the GoControl would be set to 72 and the gas logs would be turned on, however, instead I can watch the 25 minutes countdown in webCore then it says pending, starts a new 25 min countdown and then the gocontrol is set and the gas logs come on. Why is it taking 50 min and not 25 min? Am I doing something wrong or misunderstanding this? If I shorten everything to 25 seconds, it takes 50 seconds. Everything turns on or does not turn on as it should but only after 50 min or sec


you are in good hands with @WCmore and @orangebucket
i’m just going to say, two triggers with AND, won’t work too well…


It might actually be more complicated than this because of the piston firing twice, but …

Let’s assume the piston has fired and both switches are on:

  • Line 13 will look to see if the Family Room switch is on at the moment. It is, so a timer will be set for 25 minutes time. If the switch doesn’t get turned off in that time, a new instance of the piston will continue as if the comparison has returned true.
  • As well as setting up the timer, the comparison will immediately return false and the piston won’t bother to consider the other two conditions as they won’t affect the result. So the piston won’t have anything more to do and will exit.
  • Assuming the switch has stayed on, after 25 minutes a new instance of the piston will fire up, fast forward to line 13, and return true.
  • Now the piston has reached line 15. The End Tables switch is true so another 25 minute timer starts up.
  • The comparison also immediately returns true and the piston exits again.
  • Assuming the switch has stayed on, the piston wakes up after 25 minutes, fast forwards and returns true.
  • Now the line 17 comparison is tested. It basically says ‘Has the Garage Door been continuously closed for the last 25 minutes or more?’. If it has, the ‘then’ block gets executed.

So that is where your double wait comes from. As for how to code the piston to get the results you want, well @wcmore has written hundreds upon hundreds more pistons than I have and can bring practical experience to the fore. But:

I think that you might be able to simply combine lines 13 and 15 into ‘All of Family Room and End Table’s switch stays on for 25 minutes’, as although the ‘stays’ comparison is classed as a trigger, it actually compares like a condition.


In this case it seems to work OK, just a little unexpectedly, but then ‘stays’ is not as other triggers …

The ‘stays on’ comparison is classed as a trigger and so the piston will, by default, subscribe to the device attribute changes just like it would if it were ‘changes on’. However, when it comes to evaluating the comparison, the ‘stays on’ behaves like the condition ‘is on’, albeit with the timer adding weirdness. So it doesn’t care what event caused the piston to fire.


So if you are saying that the “IF” statements, like the “DO” statements also fire synchronously, then if I have 3 conditions that are all AND conditions using the Stay ON word, that the first one is checked and nothing else happens with the other two until the first 25 min has passed? If that is the case, then I need to change the “IF” conditions to fire asynchronously so that they all are evaluating at the same time, correct?


I’m not sure if the idea of asynchronous conditions really exists in webCoRE, less still how it would work with ‘stays’. I think the pistons might have a setting to make them evaluate all the conditions in an ‘if’, regardless of whether they affect the result, but that isn’t going to help you either.

What I am suggesting is that your example piston would do what you want if you replaced the two ‘stays’ conditions with the single condition ‘All of Family Room and End Table’s switches stays on for 25 minutes’.


Ok thanks that seemed to have worked, but what if the two things you want to stay on are not both switches? I can combine the two lights, but I can’t combine that with the garage door opener. Oh well for now your suggestion worked, but I still think the thing is buggy! lol!