Why is my piston being called while it's still running?


#21

Is there a better approach to this problem? “never cancel” works, but I find it difficult to follow the logic.

I was thinking of setting a global and then having another piston (or another part of this piston) watching the switch I turned on and turning it off if the global is set and it’s been on for my wait time.

Any better options?


#22

Normally, when the attribute is no longer true, we want the piston to abort. Setting the block to “Never Cancel”" assures us that once it starts, it will run to completion regardless of any changes.


#23

yeah, but I tried setting the do block that contained the with’s to “never cancel” and that didn’t work, so putting “never cancel” on random blocks of code is confusing to me. If setting it on the broader scope do wrapper had worked, it wouldn’t bug me so much.


#24

The TCP: Never Cancel should be on the WITH block… Not the do.

Basically you only want it on blocks that you want to continue once begun.


#25

That’s just it. I want everything in the do to not be cancelled, not just the stuff in the with. That’s why it makes no sense to me this way.


#26

It sounds like you may need more than one WITH set to “Never Cancel” then.

For what it’s worth, any WITH block before the WAIT does not need the “Never Cancel” flag. (since they happen nearly instantly) It is only the block with the WAIT (and after) that might need that setting to make sure it runs to completion.

In other words, if you did not have any WAITS, then you probably would not need that extra setting.


#27

I understand, and I have it working. I just don’t like the logic. I don’t want the wait or the logging to be cancelled either, but I don’t have to protect that, just the stuff in the with. That makes no sense to me. I’m not saying it should work differently, it just doesn’t feel right to me, so I’d like to approach it differently to avoid this.


#28

Here is the basic logic:

IF Device changes to X
is only true for a brief moment. If you put a WAIT somewhere below, then after the WAIT is expired, the Device is no longer “changing to X”, so the statement becomes false. (and normally cancels the remaining blocks)

This is a very powerful way to (normally) cancel blocks when things change.

In this case, you want it to run to completion once it begins, so it requires that extra step on the later WITH blocks.


#29

Like I said, I get how it works. It just doesn’t feel like I’m following the spirit of event based programming doing it. Just a personal preference thing.

I’m thinking my idea of setting an event to watch the on switch is probably a better way to go. Especially since I already have need to allow an over-ride of the second “with” based on other events. Doing it this way, I literally am over-riding the cancel only to over-ride the over-ride of the cancel and not perform the action.


#30

For the record, normally I program Motion sensors using this structure:

IF Motion changes to active
    Then do cool stuff
END IF

IF Motion stays inactive for 1 minute
    Then do other stuff
END IF

This method needs no WAIT, no fancy TCP setting, and no variable.


#31

Yes, that’s how I normally do it, but this scenario does not care about inactivity. The sensor is outside triggering a light on the inside when someone approaches the door, for a limited amount of time. The sensor cannot detect if the person is still inside or not.


#32

Oh. I did not see that logic anywhere in your first post. Maybe you have added more logic since then.


#33

No other logic. It’s a simple timer to turn the light off after x amount of time.

There are other pistons that can detect if I don’t want the light turned off and that’s what the over-ride variable is for.


#34

The if condition after the wait is my complaint about the “never cancel” I don’t want that if condition cancelled either, but there’s no “never cancel” around it and it still runs…

And I understand why, I just don’t like it. To me, it’s inconsistent.


#35

Then technically, you only need TCP set to “Never” on the last WITH block.
(although the log on line 39 will never happen unless you also change the TCP on that block as well)


#36

Stick with it. You are doing quite well for your fourth day!
(it takes a bit of time to understand the flow of webCoRE, but it is very consistent)


#37

I still think the following is a much cleaner way to accomplish this. It’s working with the system rather than circumventing it with “never cancel”. It fit’s perfectly with the pattern in your post as well, it’s just time based rather than inactivity based.

If Motion changes to active
    Turn on light
    set light-on-due-to-motion = true
END IF

If light stays on for 1 minute AND light-on-due-to-motion = true
    Turn off light
    set light-on-due-to-motion = false
END IF

#38

I like it, but be aware that if the light is already on when you walk past the motion sensor, the variable will still set. You can resolve that by using this tiny adjustment:

If Motion changes to active
Then
    IF Light is off
    Then
        Turn on light
        Set light-on-due-to-motion = true
    END IF
END IF

If light stays on for 1 minute 
AND 
Light-on-due-to-motion = true
Then
    Turn off light
    set light-on-due-to-motion = false
END IF

#39

Good point. And actually, I also have a safety in the code to only turn off the light if the sensor is still inactive. I didn’t post the full code for simplicity sake.


#40

Unless I forget, I always combine an “if off” to any “turn something on” trigger. So far that hasn’t gotten me into any trouble, and I think it’s protected me from a lot of issues.