Piston Not Running When It Should?


#1

1) Give a description of the problem
First time poster, though I have been lurking for a few months now. Apologies if the post is a little sloppy.
I have a status Update Piston to let me know when doors or lights are left open upon location mode changing. Also If I turn on a virtual switch, it notifies me. Sometimes it is quite intermittent.

2) What is the expected behaviour?
Upon location change it is supposed to notify me about what is left on. This is after an 8 second wait, because I have a light which is dependent on turning on and off based on location mode changing. Therefore I want to give it enough time to shutoff fully and update before pushing the notification. Also every day at 5am it runs and updates me if the house is in vacation mode, guest mode, or day off mode. This part of it I have never had an issue with. Also, there is an if in there which notifies me if a light switch is changed in vacation mode. This has always worked 100% too.

3) What is happening/not happening?
In The Log attached, I am changing location mode between vacation and away, and it is not updating and sending me a notification. Occasionally it will update and post the notification as expected. Though it is quite unreliable.

Also note, I have a piston run when changing into vacation mode that turns off my water. Sometimes this is unreliable as well. I am hoping how I have things setup cause an issue with reliability. I am still learning where to use asynchronous, never cancel tasks, and where to run tasks at the same time. If you think these settings are wrong within the if and with statements, please provide guidance.

**4) Post a Green Snapshot of the piston!

5) Attach logs after turning logging level to Full


#2

Hi there,
I’m sure a pro can help you much better than I can but here is my thought,
Your piston is doing a lot and for different devices. And while in WAIT some other situation can come in.

My amateur suggestion is turn this single piston into a 4-5 separate pistons… and see how that works.


#3

I seriously do not mean to be critical here…I have not had time to dig into this but I did notice a few things.

  1. At line 33 you turn Switch 8 off. That changes the state of your IF above it (with Switch 8) so the piston stops there and starts all over again. It may never get to your first PUSH.
  2. Line 44, I have had difficulty getting “switch physically changes” to work reliably. See HERE.
  3. Line 60, you change the state of Switch 8 again. That will cause your first IF to execute again. Is that your intention?
  4. Line 78, Any…switch is on… When do you expect that trigger to execute? A fan could be on all day. Should it be switch changes to on?
  5. Line 82, same as above…is open. Should that be changes to open?

I also agree with @ike2018. I am a fan of small, task specific pistons that are easy to read and debug. You might benefit from breaking this piston into several smaller, task specific pistons. Some here love long, complicated pistons. I have never been able to program that way.


#4

Just one small addition to reinforce what @ike2018 and @Pantheon said…

I cannot see what devices you have in your global variables, but your current piston has at least thirty triggers!?!

  • Switch 8 changing to on
  • Switch 8 changing to off
  • Location mode changing to Vacation
  • Location mode changing to Home
  • Location mode changing to Away
  • Location mode changing to Night
  • Location mode changing to Anything else
  • @AllFans #1’s switch changes to on
  • @AllFans #1’s switch changes to off
  • @AllFans #2’s switch changes to on
  • @AllFans #2’s switch changes to off
  • @AllFans #3’s switch changes to on
  • @AllFans #3’s switch changes to off
  • @AllFans #?'s switch changes to on
  • @AllFans #?'s switch changes to off
  • @AllLights #1’s switch changes to on
  • @AllLights #1’s switch changes to off
  • @AllLights #2’s switch changes to on
  • @AllLights #2’s switch changes to off
  • @AllLights #3’s switch changes to on
  • @AllLights #3’s switch changes to off
  • @AllLights #?'s switch changes to on
  • @AllLights #?'s switch changes to off
  • @Doors #1’s contact changes to open
  • @Doors #1’s contact changes to closed
  • @Doors #2’s contact changes to open
  • @Doors #2’s contact changes to closed
  • @Doors #3’s contact changes to open
  • @Doors #3’s contact changes to closed
  • @Doors #?'s contact changes to open
  • @Doors #?'s contact changes to closed

When ANY of these change… The entire piston runs thru the code… Top to bottom.

I would NOT expect reliability with that many triggers in one place


In all honesty, you could rename this topic to:
“Piston is Running more than it should”


#5

In the log, the piston has been fired because a location mode event has been received. The new mode is ‘Away’ but the piston doesn’t seem to think the mode has actually changed. On the face of it that sounds contradictory, but device handlers and SmartApps can, and do, request events be propagated regardless of whether anything has changed. Regardless of that, it clearly isn’t what you were expecting.

You can change the TCP to ‘Never cancel tasks’ on the ‘if’, the ‘with’ or the ‘do’ associated with a ‘wait’. I’ve yet to discover what on earth it does on the ‘if’, but I have seen it break things that ought to work so I’d definitely lose it on the ‘if location mode changes’ condition. You might want to move it onto the the ‘with’ associated with the eight second wait as if anything fires your piston in those eight seconds then you won’t get notifications, and you do have rather a lot of things triggering your piston.

I would also lose ‘enable parallelism’, and I doubt you really want any of the ‘always subscribe’ settings. webCoRE is pretty good at working out when to subscribe to things.

Is that an ‘allow multiple scheduled tasks’ I can see in the first ‘with’ of the ‘every day’ block? That isn’t going to do anything for you.


#6

You have plenty of help here so let’s put together a piston or pistons that will achieve your goals. Choose a simple task or two and build a piston and let us help your with it.


#7

I didn’t count them but I had a felling it would be around that LOL


#8

Thank you for the suggestions. Here are my takeaways.

  1. I was unaware when using a trigger if you changed its state it will disable the rest of the if. To me that makes sense for a condition, but not a trigger. Though I will switch the order of the turn off and PUSH.

  2. Yeah I have no need for physically to be in there. Even if it is there it still runs on not physical integration.

  3. Yes that is the intention. Causes the switch to trigger and reminds me in the morning how many days the house has been in vacation mode.

4&5) For these I want to accumulate a list of which devices are on. If I use a trigger, it just tells me the last device changed. This has been working quite well for me, though I’m not sure if it is the most efficient way to do it.

Personally, I prefer to have everything in 1 long piston, because then I am not involving global variables to rely on which devices I have on and off. This used to be much smaller, though as it has grown, I have upgraded it as well. Though, if I have to go smaller, I will.


#9

So what I have noticed is when you save items to a list you can only set it to local variables. Then if you want that as a global variable, you need to run a separate command setting it to global. AKA if ALL LIGHTS is on, save matching devices to local variable. And in the Then statement you have to set global variable to local variable. Is this the recommended way of doing things?

What I want is when I press a button on my phone (switch 8 changes on), or when location mode changes; I want to know what location mode it is, what doors are open, or what has been left on.

To separate these into different pistons means I have to use global variables to get the communication between pistons. Is this the best way to do this? Because I tried this before and was having issues updating the global variables reliably.


#10

If you see my reply to WCmore, you will see why I have had issues separating before. I believe I have it setup properly to run multiple tasks, if something were to change during the WAIT. I understand breaking it down into smaller pistons, and will if I must, but doing so makes it harder to do what I am trying to accomplish.


#11

Thank you for the helpful advice. So when you add a modifier like ‘allow multiple scheduled tasks’ does it allow the one which it is set on to run (if another with the default setting is already running)?

I removed the Never cancel on the IF, and there is one on the with (though not sure why in the code screenshot it was not showing up).

Wouldn’t the enable parallelism be beneficial here, because it allows the piston to run multiple instances?

Always subscribe here shouldn’t make a difference, but for the last two if statements it does as they are conditions. I need those on so they act as triggers so it updates the list upon a switch turning on, or a door opening.


#12

I always do the bulk of my processing using local variables, and then near the very bottom of the piston, I dump the important ones into globals. This gives me snappy local variables for instant use, and a lingering global for long term storage.

(Although I have not tested this using a “device” type variable… I assume it’s the same)


Personally, I would put lines 77-84 into three tiny pistons.

Piston #1:

IF any of {@AllFans}'s switch is on
    Save matching devices to {ActiveFans}
Then Set variable {@ActiveFans} = {ActiveFans}
END IF

Piston #2:

IF any of {@AllLights}'s switch is on
    Save matching devices to {ActiveLights}
Then Set variable {@ActiveLights} = {ActiveLights}
END IF

Piston #3:

IF any of {@Doors}'s door is open
    Save matching devices to {DoorsOpen}
Then Set variable {@DoorsOpen} = {DoorsOpen}
END IF

Next to motion sensors, these will likely be the three most active pistons in your entire house, so separating them can really streamline everything.


Pro Tip:

I am not quite sure what you should do with lines 43-50… Ideally, a switch trigger should go in the mini piston above that is also subscribed to those switches. (no need to have two pistons firing at each event)

Perhaps the “Vacation” portion can be in it’s own piston, but remove the trigger on the lights & fans, so 99% of the year, that piston will not be running like crazy.


#13

Curious about line 59.

image

Is that necessary? Does the “=” before the variable do something special?


#14

All “Set variable” commands have that equals sign…

It basically says:
Set the global to the previous global +1
(adding one to the current)


Pro Tip:

If you do this with globals, it only works once per piston run…
You cannot loop or repeat this code more than once per event.


Edit:

Oh, you mean the green equals… No, that is not needed.
(nor is the double curly brackets)


#15

That’s what I thought. Thanks for confirming. :slight_smile:

Damn…you changed it before I could correct you. :stuck_out_tongue:


#16

*blows smoke from his fingertips*


#17

It is tough… Nearly every statement has exceptions…
(usually found when proof reading my post, LOL)


#18

blows smoke from his fingertips


#19

Bonus points for the Mel Brooks reference!


#20

Thanks for the suggestion. This is how I initially had things, Though I found it to be sluggish and the global variables didnt keep up. I will try again and see if it improves.

Regarding Lines 43-50: This is used when I am gone to alert me if a light switch is changed ( low level security). As no one will ever be in my house during vacation mode, and if an intruder is dumb enough to turn on a light, I will know. Then I can check my cameras and confirm.