Execute piston if virtual button pressed OR called from another piston


#1

1) Give a description of the problem
I have a goodnight piston which gets executed from another piston. It doesn’t subscribe to any events, it simply executes some statements which dim certain lights.
I’d like to create a virtual button so I can manually execute this but I think this would prevent it from running when the other piston calls it.

So the logic is:
IF button is pressed OR piston gets called from PistonX…

I’m not sure how to implement this. Maybe I’m a bit hungover from Taco Tuesday…


#2

I do something like this with my Morning Wake up routine. It normally goes of on its own at a specified time, but if I wake up early I can start it by using the Alexa, or by double-tapping a switch. So it’s certainly possible to have multiple ways to start another piston.

What I did was to add another “virtual switch” which let’s the scheduled piston know that it is already running. So if I got up a half hour early, the scheduled piston will see that the virtual switch is already on and then it will skip execution. In my case I don’t want it to run again on the schedule if it already ran earlier in the day.

But if you do want it to keep to a schedule AND run it manually then I don’t see any problem with that at all. You could just make another piston with just one Trigger (your button) and have it call your other piston which does not have any events in it.

I even setup mine so that an entirely different piston for the light switch makes the same call. No reason you can’t do the same. They don’t all have to be in the same piston.


#3

Thanks, I went ahead and just created a new piston:
IF ‘switch’ changes to ON
Execute piston “Goodnight”

Works just fine…

Just curious though, there’s no built-in logic that could evaluate whether or not PistonB is getting called from PistonA?


#4

While it’s getting called? Or who called it?

There’s nothing which will tell you the while part. Which is why I use the simulated switch to know that mine is already active (had been called by a different means). But you can pass args to the piston you call and that could tell you “who” called the piston…providing each calling piston passes some different args.


#5

I use this technique - i.e., either the piston being invoked directly (in my case via IFTTT) or via a “normal” event. Here’s a simple example:

And here’s a log from it being invoked by another piston and by a button push:

3/8/2018, 10:07:26 AM +411ms
+2ms	╔Received event [Button 1].button = pushed with a delay of 78ms
+115ms	║Run via button push.
+119ms	╚Event processed successfully (118ms)
3/8/2018, 10:07:21 AM +688ms
+0ms	╔Received event [Doral Ct].execute = :b0c910121803b70c2a67109fe9263f0c: with a delay of 39ms
+102ms	║Run via execute - command is Cmd2.
+114ms	╚Event processed successfully (114ms)

This works because when invoked directly a parameter is passed (in this case $args.command), and when run via a trigger $args will be null. No need for another intermediate piston (although in some cases that might be useful.)


#6

Well, unfortunately, I have to take this back. I’ve encountered several scenarios where a piston is executed with arguments followed by being triggered by other events and $args still contains the parameters from the previous call. E.g., I wrote a piston that, after being executed with arguments, causes the piston to run again after a period of time. When that time event happens, even though the log clearly shows the event was time, $args still has the parameters from the previous run. Worse, $currentEvent… still has all the values from the previous run and there appears to be absolutely no way to tell the difference from within the piston.

So, bottom line, you may get lucky, but you’ll probably be better off not mixing the two. I.e., a piston that is called (either via another piston with the execute action, or via some external method using the piston’s URL) should not also subscribe to and react to other events.

To me, this is unfortunate, because it would really be nice sometimes to keep the processing of these related events in the same piston.