Jump to content

Program Enable/Disable impact on Wait command


kclenden

Recommended Posts

I've always thought that a WAIT command will terminate and the conditions in the IF will be reevaluated if any of the conditions in the IF change.  Usually that is the case, but after a couple days of puzzling over why my programs didn't seem to be working as expected, I've learned that disabling a program does more than just prevent it from starting on its own.  It also prevents the IF statement from being reevaluated during a WAIT.

 

I turn my outside lights on around about sunset.  Instead of having them always come on at sunset, I use the RANDOM option of WAIT to have them come on within 30 minutes of sunset.  This means that from the time the ISY decides that the lights should be turned on, and they are actually turned on, as much as 30 minutes can elapse.  During all but about 6 weeks of the year, this 30 minute dead time is of no consequence.  But during Christmas time, I also have the ISY turn on Christmas lights after sunset and I don't want the outside lights to come on if the Christmas lights have been turned on during the dead time mentioned above.

 

The program I use to initiate turning the outside lights on is this:

 

Outside Lights-Random On - [iD 009F][Parent 0054][Not Enabled]
 
If
        $sXmasLightsOn is 0
 
Then
        Wait  30 minutes  (Random)
        Run Program 'Outside Lights-Manual' (Then Path)
 
Else
   - No Actions - (To add one, press 'Action')
 
I have the program DISABLED because I don't want it to run any time $sXmasLightsOn is 0, but only when another program specifically runs it at which point I want it to quit running if the outside lights are already on, or are turned on during the up to 30 minutes of waiting.  The ISY program that turns on the Christmas lights sets $sXmasLightsOn to -1.
 
If a program runs the IF portion of "Outside Lights-Random On" and $sXmasLightsOn is not 0, the ELSE runs and the program stops.  If a program runs the IF portion of Outside Lights-Random On" and $sXmasLightsOn is 0 then the THEN runs and begins to wait.  During the waiting, if $sXmasLightsOn changes from 0 to something else, the wait continues and ultimately executes the next line and the outside lights are turned on.  If I re-enable the program, the WAIT works as expected and reacts to changes in $sXmasLightsOn but the program runs any time $sXmasLightsOn changes back to 0 which is behavior I don't want.
 
If you're still with me, thanks.  Here are my questions.  Is disabling a program supposed to also disable the reevaluation aspect of the WAIT command?  And is there a best practice for using WAIT in a program you want to begin execution only when commanded by another program?  I could add another state variable, say sExecute, to keep the program from running unless I specifically command it to, but this seems like a lot of overhead, and I'd need a separate variable for each program that I both want to only run when commanded and uses a WAIT that needs to react to changes in the IF.
 
Appreciate any suggestions.
Link to comment
But during Christmas time, I also have the ISY turn on Christmas lights after sunset and I don't want the outside lights to come on if the Christmas lights have been turned on during the dead time mentioned above.​

 

  What problem are you trying to avoid?  Is there some harm in turning on some lights that are already on?

Is disabling a program supposed to also disable the reevaluation aspect of the WAIT command?​

 

my understanding is that disabling a program (including putting the program in a folder that is disabled) would prevent any condition from triggering at any time.  Since a WAIT statement would be interrupted when a condition triggers, if a condition is not triggered (disabled), the wait statement would not be interrupted.

 

And is there a best practice for using WAIT in a program you want to begin execution only when commanded by another program?

 

I am not sure I understand that question.  Use a WAIT statement when you want to pause the program for some reason.  This works whether the program is disabled or not.  If you desire some condition to interrupt a waiting program, either write the program(s) in such a way that disabling is not necessary, or call it from another program.  I cannot think of another option.

 

In your case, I think I would employ a program folder, with condition:

 

if

$sXmasLightsOn is 0

then

run the programs in this folder

 

In the folder, put a program like this:

 

If
        time is sunset
 
Then
        Wait  30 minutes  (Random)
        Run Program 'Outside Lights-Manual' (Then Path)
 
Else
   - No Actions - (To add one, press 'Action')

 

My understanding is that were the folder to become disabled during the wait statement, the program would halt.

Link to comment

With your current design, the execution is inevitable once the program is executed.  What you want is to have the evaluation occur at the time the random ends. If the folder option Oberkc suggested doesn't work, then another program (third in the case of your usage) should be executed at the expiration of the timer rather than executing the command directly.  You could also, put the wait in the calling program instead, but a 3rd program would make more sense.  Also disabled.

Link to comment

Disabling a program only stops it from SELF triggering.  

 

Ending/resetting a wait/repeat happens whenver a program clause is executed for any reason (if, then, or else).  Also, I believe the act of changing a program from enabled to disabled terminates a running wait/repeat.

 

It sounds like you want the wait to terminate if the variable changes to not-0, but don't want it to run true if it changes to 0.

 

You need mutliple conditions in the if clause to do this.  Or, alternatively, use other programs (which just means you have put the other conditions into other programs).

 

Alternatively, you could use version 5.x firmware which has a "repeat while" option.

 

EDIT:  My idea on using repeat while doesn't work.  I had never tested this before, so I did.  Repeat while does not "self trigger" on a disabled program, much like things in the if clause don't self-trigger.  In other words, repeat while is useless in disabled programs, it will keep repeating, I assume, forever unless some outside entity calls the if/then/else.

Link to comment

Disabling a program only stops it from SELF triggering.  

 

That's what I thought, but disabling a program also prevents the IF condition from ever being reevaluated once the program has been externally triggered.  There's nothing wrong with how UD has implemented the "enable/disable" option for programs.  It just works differently than I originally thought.

 

Thanks for all the suggestions.  For various reasons, that aren't obvious because I left out other details, I had consciously not implemented many of them from the beginning.  I'm going to try the folder idea oberkc suggested as it comes closest to matching the separation of duties structure that I have setup for my programs.

Link to comment

That's what I thought, but disabling a program also prevents the IF condition from ever being reevaluated once the program has been externally triggered.  There's nothing wrong with how UD has implemented the "enable/disable" option for programs.  It just works differently than I originally thought.

 

Thanks for all the suggestions.  For various reasons, that aren't obvious because I left out other details, I had consciously not implemented many of them from the beginning.  I'm going to try the folder idea oberkc suggested as it comes closest to matching the separation of duties structure that I have setup for my programs.

What you say is not true.  A "run if" can be executed manually, from another program, or from a REST command.  In other words, it can be run every possible way, except for a self-trigger.

Link to comment

What you say is not true.  A "run if" can be executed manually, from another program, or from a REST command.  In other words, it can be run every possible way, except for a self-trigger.

I stand corrected.  My confusion was with the concept of stopping a program by self-triggering it.  In reality the self-triggering doesn't really stop the program, it redirects its execution from the currently running WAIT command in the THEN section to the ELSE section which in my case has no lines to execute and thus allows the program to stop executing because it has run out of lines to execute.

Link to comment

I stand corrected.  My confusion was with the concept of stopping a program by self-triggering it.  In reality the self-triggering doesn't really stop the program, it redirects its execution from the currently running WAIT command in the THEN section to the ELSE section which in my case has no lines to execute and thus allows the program to stop executing because it has run out of lines to execute.

Just to re-iterate, the only thing that is different about a disabled program is that it does not SELF trigger.

 

To cause a program to stop a wait or repeat you can

1) Execute the other clause (run then/ run else) provided the other clause is blank (or does something that you want)

2) CHANGE a program from enabled to disabled (from another program/REST/manually)

3) Execute a "stop"command (from another program/REST/manually)

4) Execute a "run if" provided the if section is going to evaluate to the other clause, and provided the other clause is blank (or does something that you want)

 

Typically, if your interest is strictly to terminate the wait/repeat, you would use the "stop" command.

Link to comment

Thanks for being so concise.  Very helpful.

 

I didn't know about the STOP command.  When it stops a programs, does it stop execution immediately (i.e. no other lines in either the IF or ELSE clause are executed)?  What happens if you try to stop a program that isn't running?  Can you tell in the "Summary" screen that a program ceased execution because it was stopped and not because it completed?

 

I think rather than the folder option suggested by oberkc, which worked perfectly by the way, it would be clearer if I simply used the STOP command in my program that turns on the Christmas lights.

Link to comment

Thanks for being so concise.  Very helpful.

 

I didn't know about the STOP command.  When it stops a programs, does it stop execution immediately (i.e. no other lines in either the IF or ELSE clause are executed)?  What happens if you try to stop a program that isn't running?  Can you tell in the "Summary" screen that a program ceased execution because it was stopped and not because it completed?

 

I think rather than the folder option suggested by oberkc, which worked perfectly by the way, it would be clearer if I simply used the STOP command in my program that turns on the Christmas lights.

Stop just means stop.  It just stops.  Right where it is.

 

If you stop a program that isn't running, then you stopped something that was already stopped, so it is non-thing.

 

No, the program summary page does not tell you that a program was stopped.  It changes from "running then/else" to "idle" and the finish time updates to the current time.

Link to comment

I have a question. What runs the lights on program?

 

If you're referring the the program from the original post, then it appears to be a state variable being changed from something to 0 (zero). Yes, this is an assumption.

 

Are you actually asking what causes the state variable to change to 0 (zero) from some other value or are you asking something different? I don't mean to be simplistic (which I am), but simplicity often provides better solutions than assumptions.

Link to comment

The "Outside Lights-Random On" is run by a sunset triggered program.  There are other programs that turn on the outside lights as well.  One is linked to a keypad button and turns them on immediately.  Another is linked to a motion detector and, like the original program, turns them on a random amount of time (0-10 seconds) after motion is detected.  Another is linked to an Open/Close switch and turns them on immediately when a garage door is opened.

 

Actually, in all cases, the programs don't actually command the outside lights on.  Instead they set state variables and there are a couple programs triggered by those state variables to turn on specific scenes that include the outside lights.  Normally, when the lights are commanded on they come on at 35%.  If the motion detector or open/close sensor trips, they are command to full brightness for a random number of seconds and then return to 35% (unless they aren't on, like during the day, in which case nothing happens).

Link to comment

The "Outside Lights-Random On" is run by a sunset triggered program.  There are other programs that turn on the outside lights as well.  One is linked to a keypad button and turns them on immediately.  Another is linked to a motion detector and, like the original program, turns them on a random amount of time (0-10 seconds) after motion is detected.  Another is linked to an Open/Close switch and turns them on immediately when a garage door is opened.

 

Actually, in all cases, the programs don't actually command the outside lights on.  Instead they set state variables and there are a couple programs triggered by those state variables to turn on specific scenes that include the outside lights.  Normally, when the lights are commanded on they come on at 35%.  If the motion detector or open/close sensor trips, they are command to full brightness for a random number of seconds and then return to 35% (unless they aren't on, like during the day, in which case nothing happens).

 

If something like a kpl button always turns on the lights, then you have gone about making something of a rube goldberg machine by having it set a varialbe whtich then runs a program which then turns a scene on.

 

You would be much better off simply putting the kpl button in the scene as a controller.  The response would be essentially instant and editing it in the future would be much more obvious. Say 2 years from now you decide to change it . . . you might just spend a half hour trying to remember how you had set this thing up.

Link to comment

I use the variable set and detect method in many places. Once setup with the bank of programs as drivers the modularity allows easy changes without recreating and remembering how obscure programming paths work.

 

Use of variables to control lighting scenes, programs and devices also allows many different inputs to control that variable.

 

eg: To run a sequence of lights that independently dim and change colouring involving Insteon overhead floods, MiLight bulbs, Hue bulbs and LEDenet RGBW strips it is as easy as one line of code in a program.

 

  • then
  • ....set $sGathRm.mode = $cMODE.SUNSET

 

This would take a myriad of programming to trigger every program, and scene involved. This would be nasty to change three programs that use that sequence. The central variable control makes it very easy and modular for future mods.

Link to comment

 

Use of variables to control lighting scenes, programs and devices also allows many different inputs to control that variable.

 

 

True, but only of value when the "many different inputs" aren't Insteon devices that could just be set as a scene controller.  The only caveat being if the insteon controller isn't always doing the same thing.  Like maybe in the morning the Insteon device does one thing, and in the evening it does a different thing.

 

Setting the Insteon device as a direct scene controller will increase response time to nearly instant and cut Insteon traffic by half and reduce the potential points of failure by more than half.

Link to comment

Archived

This topic is now archived and is closed to further replies.


×
×
  • Create New...