TCP and fast-changing conditions

canceling

#1

Say I have a simple piston like:

execute
  if 
    someSwitch's switch changes to on
  then
    with
      Location
    do
      do Execute piston "some piston"
    end with
  end if
end execute

The switch is momentary, so it’s going to turn on and off again pretty quickly, < 100ms. If the switch changes to ‘on’, the piston should definitely execute. However, my understanding is that if the switch’s state changes to something else before the piston execution command has been issued, it might not happen, so it seems like disabling TCP somewhere would be prudent.

My question is, in a station like this, where should the TCP be set to “never”: on the “if” or on the “with”? (Really, what does it even mean to set the TCP on the “if” in this case?)


#2

Still wouldn’t work based on the way you wrote it above. You need the switch to report that it’s ON. So if it goes ON then OFF again too fast it won’t report that it’s ON, or maybe it reports that it’s on half the time (every other time).

The way I see it, you could change your piston so that you just say “Changes” instead of “Changes to on”. You know the momentary is going to immediately go back to being off, and you know it’s going to happen so fast that you’re only likely going to get 1 event notification in the logs (test for yourself with FULL logging enabled), so that could work. It will just act as a Toggle, effectively…but you wouldn’t care. It’s a bit of a hack…but it would get the job done.

OR…and I just went through this in another thread, you could just use a regular switch and turn it back off at the end.


#3

You know the momentary is going to immediately go back to being off, and you know it’s going to happen so fast that you’re only likely going to get 1 event notification in the logs (test for yourself with FULL logging enabled), so that could work.

I have tested it. Both events are always received (at least I’ve never seen one be missed), although without parallelism turned on the second event is sometimes delayed by 10s.

The switch works almost every time, but sometimes it doesn’t, and it seems like event cancellation may be the issue. I still need to diagnose it a bit more to determine exactly what the problem is, but in general I was just curious about how the TCP works. Like, what’s the difference between preventing cancellation on the IF vs on the WITH?


#4

If you want to get that deep into the weeds then perhaps one of the Minions will respond.

But if you are indeed always getting both the ON and the OFF events sent to the piston then it is possible that the piston could start, and then before it gets to the DO section it receives the notice that the switch is now OFF. Which would then mean that TCP will indeed cancel all the remaining tasks because the condition which started the piston “switch changes to on” is no longer true.

So…this could be a candidate for setting TCP to never.

I was initially thinking that you were only getting one of the Events, either the On or the Off. But if you’re always getting both, then yes, the Off could cause problems depending on when it is received.


#5

Task cancellation policy is normally used for things that take a long time to execute that you don’t want interrupted. A good example would be:

IF
Switch X or Switch Y changes to ON
THEN
Turn light Y ON
Wait 10 seconds
Turn light Y OFF

The above example would subscribe to changes to Switches X and Y, meaning the piston would execute in full every time Switch X or Y reports a change in their switch position. If either changed to OFF, even though the condition states ON, the piston would still run in its entirety. The only difference when compared to one of the switches turn on would be your IF condition would evaluate false… and that’s the key to your TCP question, because there was just a change in condition.

Be default, tasks are cancelled if there is a change in condition. In the example above, if the piston ran because Switch X turned on, it would turn on Light Y and then set itself to wake up in 10 seconds to turn the light off. If Switch Y turned off during that 10 second wait, it would cause the piston to run, the condition would evaluate false now, and the piston would therefore cancel your pending task wake up and to turn the light off 10 seconds after it was turned on.

In your example, since you’re dealing with very short on durations, unless you’re sensitive to the .1s delay I would set the piston to trigger on “changes to off”. Since ‘off’ is the steady state, when it changes to off you have confidence it still be off when the piston runs and your condition will evaluate true reliably.


#6

[smacks forehead] This is wisdom.

That should take care of my immediate issue, but I’m still curious about how to properly apply a TCP=never. Specifically, what does it mean to apply a TCP=never to an IF? (Does it do anything if the IF with the TCP=never is the one who’s condition changed?)


#7

Thank you, and glad to help!

I’ve only seen or used TCP = never on WITH statements and the results there are pretty predictable since WITH contains Actions you would prevent from being cancelled.

The only time I’ve seen an IF statement with TCP = never is in posts in this forum when people are asking why their piston isn’t working reliably, lol. I actually don’t fully understand what that does to a piston, but I’ve never needed to use it since applying to WITH has worked.

Does my example above make it clear how it works with a WITH statement? If not, I’ll take another crack at it… :beers:


#8

It does. I had assumed that’s how TCP=never it would work with a WITH, I just wondered what applying TCP=never to an IF actually does; like, can an IF be interrupted before it’s even started running things in the THEN clause?