Phil Posted June 21, 2015 Posted June 21, 2015 I've written a few programs for my ISY-994i and they seem to work fine. I'm currently trying to make one that turns on some lights when I have a variable set to indicate when we're on vacation. It's not working as expected and I could use some help. Here's the program. If $Vacation is 1 And Time is 6:00:00AM Then Wait 5 minutes (Random) Set 'Upstairs / Master Bath main' On Wait 2 minutes (Random) Set 'Upstairs / Guest bathroom' On Wait 2 minutes (Random) Set 'Upstairs / Master Bath main' Off Wait 20 seconds (Random) Set Scene '3-way main stairs' On Wait 30 seconds (Random) Run Program 'Morning lights' (Then Path) Wait 1 minute (Random) Set 'Upstairs / Guest bathroom' Off Wait 2 minutes (Random) Set Scene '3-way main stairs' Off Wait 1 minute (Random) Set Scene 'Dim downstairs' On Else - No Actions - (To add one, press 'Action') What actually happens is that exactly at 6:00:00 AM, the 'Morning lights' (Then Path) is executed and nothing else happens. However, if I go into the console and right-click the above program, and select "Run (Then)", everything works fine. What am I doing wrong? Phil
Phil Posted June 21, 2015 Author Posted June 21, 2015 Is $Vacation an Integer or State variable? $Vacation is a State variable
LeeG Posted June 21, 2015 Posted June 21, 2015 (edited) Run Tools | Diagnostics | Event Viewer at LEVEL 3. Set the time to a value 5 minutes in the future. Post the event trace when Program is triggered. The conditions described should be impossible. The Then works when directly Run but skips statements when the Program is triggered. There is more to this than is being documented. EDIT: look for another program that is invoking 'Morning lights' or the If itself is running 'Morning lights' Edited June 21, 2015 by LeeG
hart2hart Posted June 21, 2015 Posted June 21, 2015 (edited) Just a guess. ... (Change program for a time few minutes in your future). ..... is program reevaluated and no longer true interrupting 5 minute wait before anything actually happens? Watch as time passes new time set above to see if it stays in running then state for one minute. Running then simply does so without condition and would not be subject to revaluation from guess above. If so, you could break into two program where one serves as if trigger than runs then other program that has all actions but no actual if statement Edited June 21, 2015 by hart2hart
zerop Posted June 21, 2015 Posted June 21, 2015 Run Tools | Diagnostics | Event Viewer at LEVEL 3. Set the time to a value 5 minutes in the future. Post the event trace when Program is triggered. The conditions described should be impossible. The Then works when directly Run but skips statements when the Program is triggered. There is more to this than is being documented. EDIT: look for another program that is invoking 'Morning lights' or the If itself is running 'Morning lights' Does all that matter? I thought after a wait command the "If" statement is re-evaluated. In this case the "Then" path starts at 6:00am as it should. After the 5 minute wait the "If" is re-evaluated and found to be false because it is no longer 6:00am and then "Else" path is then run (the "Then" path does not continue). To get around this you should put the "Then" path in it's own program with no "If" statement. In the original program's "then" path, call for a Run (Then Path) of the new program. If $Vacation is 1 And Time is 6:00:00AM Then Run New Program (Then Path) Else - No Actions - (To add one, press 'Action') If - No Conditions - (To add one, press 'Schedule' or 'Condition') Then Wait 5 minutes (Random) Set 'Upstairs / Master Bath main' On Wait 2 minutes (Random) Set 'Upstairs / Guest bathroom' On Wait 2 minutes (Random) Set 'Upstairs / Master Bath main' Off Wait 20 seconds (Random) Set Scene '3-way main stairs' On Wait 30 seconds (Random) Run Program 'Morning lights' (Then Path) Wait 1 minute (Random) Set 'Upstairs / Guest bathroom' Off Wait 2 minutes (Random) Set Scene '3-way main stairs' Off Wait 1 minute (Random) Set Scene 'Dim downstairs' On Else - No Actions - (To add one, press 'Action')
Phil Posted June 21, 2015 Author Posted June 21, 2015 Thanks for the suggestions. I just scheduled the program to run 5 minutes in the future, then watched things carefully. Everything worked fine. . The thoughts about the "if" being re-evaluated after the wait were interesting, but it appears that is not what's happening since the program worked just now. I thought I remembered reading that once the "if" condition is true, the "then" is immediately executed. I think you guys were right about something else triggering the 'Morning Lights' program to execute. That program turns on the downstairs lights when motion is detected there in the morning, starting at 6am. I think what happened was my motion detector may have been wonky (we've had a few problems with it recently), so it activated that program at the same time this vacation lights program was scheduled to start. I blamed it on this program not working correctly. Thanks for the hints to look for other ways that could be triggered. I'll reset back to having this program start in the morning and will capture the event logs if I catch it not working again. Thanks again for the help and suggestions! Phil
Phil Posted June 21, 2015 Author Posted June 21, 2015 I think I confirmed that the "if" does not get re-evaluated when there are "wait"s inside the "then" clause. I created a state variable called $Wait_testing and just ran this program: If Time is 9:43:00AM Then Wait 1 minute (Random) $Wait_testing = 1 Wait 10 seconds $Wait_testing = 2 Wait 1 minute $Wait_testing = 3 Else - No Actions - (To add one, press 'Action') It worked as expected. The program state was in "running then" for the duration, and I saw the variable get incremented after each wait period. Phil
zerop Posted June 21, 2015 Posted June 21, 2015 I think I confirmed that the "if" does not get re-evaluated when there are "wait"s inside the "then" clause. I created a state variable called $Wait_testing and just ran this program: If Time is 9:43:00AM Then Wait 1 minute (Random) $Wait_testing = 1 Wait 10 seconds $Wait_testing = 2 Wait 1 minute $Wait_testing = 3 Else - No Actions - (To add one, press 'Action') It worked as expected. The program state was in "running then" for the duration, and I saw the variable get incremented after each wait period. Phil From the ISY Wiki "A series of statements within a Then clause (or within an Else clause), up to the next Wait or Repeat statement, are atomic. In other words, all such statements are executed before the conditions of the program are retested. The program's conditions are reevaluated each time a Wait or Repeat statement is encountered, and at the end of each iteration of a Repeat loop. What this means is that if a program's Then clause changes a condition which causes the program's overall condition to become false (or if the program's Else clause changes a condition which causes the program's overall condition to become true), the current atomic statement group will complete, and at that point execution will transfer from the Then clause (or the Elseclause) to the Else clause (or the Then clause)." Maybe it's because your "Else" path wasn't what change the "If" condition. Maybe that's why it ran the entire thing? However be careful in the future because the "Then" path may stop after "wait" commands due to the following mentioned above.
LeeG Posted June 21, 2015 Posted June 21, 2015 The Wait (and Repeat) statement allows the Program to be triggered during the Wait (or Repeat). An 'If Time' has no False side trigger so the Waits will not cause the Else to run.
zerop Posted June 21, 2015 Posted June 21, 2015 An 'If Time' has no False side trigger so the Waits will not cause the Else to run. I did not know that. Thanks!
hart2hart Posted June 21, 2015 Posted June 21, 2015 The Wait (and Repeat) statement allows the Program to be triggered during the Wait (or Repeat). An 'If Time' has no False side trigger so the Waits will not cause the Else to run. If combined with variable condition as original program, will it be reevaluated ie no longer be true?
LeeG Posted June 21, 2015 Posted June 21, 2015 The State variable changing value ($Vacation is 1) would trigger the Program while in a Wait. The evaluation would be False driving the Else clause.
Phil Posted June 21, 2015 Author Posted June 21, 2015 Thanks so much for the help. Now that I understand how if/then is supposed to work with wait conditions, I have split up my program in the way zerop suggested in #6 above. Phil
apostolakisl Posted June 22, 2015 Posted June 22, 2015 (edited) From the ISY Wiki "A series of statements within a Then clause (or within an Else clause), up to the next Wait or Repeat statement, are atomic. In other words, all such statements are executed before the conditions of the program are retested. The program's conditions are reevaluated each time a Wait or Repeat statement is encountered, and at the end of each iteration of a Repeat loop. What this means is that if a program's Then clause changes a condition which causes the program's overall condition to become false (or if the program's Else clause changes a condition which causes the program's overall condition to become true), the current atomic statement group will complete, and at that point execution will transfer from the Then clause (or the Elseclause) to the Else clause (or the Then clause)." Maybe it's because your "Else" path wasn't what change the "If" condition. Maybe that's why it ran the entire thing? However be careful in the future because the "Then" path may stop after "wait" commands due to the following mentioned above. When you say "What this means is that if a program's Then clause changes a condition which causes the program's overall condition to become false (or if the program's Else clause changes a condition which causes the program's overall condition to become true), the current atomic statement group will complete, and at that point execution will transfer from the Then clause (or the Elseclause) to the Else clause (or the Then clause)."" The above statement needs some clarification. Just because the conditions in the "if" changed, that does not mean the program will re-eval at a wait/repeat. The change in the "if" must have also been a trigger. So "6am" is no longer true after a wait, but the program will keep going because there was no trigger (times are only triggers at the stated time). The variable on the other hand as I understand is a state variable, so if it changes, the "if" triggers and a wait/repeat will terminate the program and run the "else". Edited June 22, 2015 by apostolakisl
zerop Posted June 22, 2015 Posted June 22, 2015 When you say "What this means is that if a program's Then clause changes a condition which causes the program's overall condition to become false (or if the program's Else clause changes a condition which causes the program's overall condition to become true), the current atomic statement group will complete, and at that point execution will transfer from the Then clause (or the Elseclause) to the Else clause (or the Then clause)."" The above statement needs some clarification. Just because the conditions in the "if" changed, that does not mean the program will re-eval at a wait/repeat. The change in the "if" must have also been a trigger. So "6am" is no longer true after a wait, but the program will keep going because there was no trigger (times are only triggers at the stated time). The variable on the other hand as I understand is a state variable, so if it changes, the "if" triggers and a wait/repeat will terminate the program and run the "else". The portion of text after "What this means..." is not my words. It's directly from the Wiki. All of that is in one big set of quotes.
stusviews Posted June 22, 2015 Posted June 22, 2015 If you have a statement that causes the If condition to become false, then "the current atomic statement group will complete" means that everything in that statement will execute even if only one element caused the condition to become false. For example, if a statement runs a second program that changes the condition part way through, the rest of that second program will continue to run. The same is true if one member of a scene causes the condition to become false. All members of the scene will still respond to the statement command.
apostolakisl Posted June 22, 2015 Posted June 22, 2015 (edited) If you have a statement that causes the If condition to become false, then "the current atomic statement group will complete" means that everything in that statement will execute even if only one element caused the condition to become false. For example, if a statement runs a second program that changes the condition part way through, the rest of that second program will continue to run. The same is true if one member of a scene causes the condition to become false. All members of the scene will still respond to the statement command. Still, though, it has to be a trigger. If the variable were an integer variable, then it could change, the "if" would in fact be false, but the program would continue to run through the waits and repeats. Once engaged in an "atomic" section, that section will finish no matter what, but breaks points such as wait and repeat will allow trigger events to start the program over and from there it could be true again, or false. If it stays true, the program will start over from scratch after a trigger event. For example, if your if statement said If time is 6am or time is 6:00:10 am Then wait 5 seconds do stuff wait 10 seconds do more stuff The program will start over at 6:00:10 and the "do stuff" part will run twice, but the "do more stuff" part will only happen on the second round. EDIT: To further illustrate If time is 6am or (time is 6:00:10 am and something else that is false) Then wait 5 seconds do stuff wait 10 seconds do more stuff This program will trigger at 6 and at 6:00:10. The second trigger will be false. So, the result will be "do stuff" happens once, "do more stuff" never happens. In short, "if" clauses only evaluate on triggers. Whether the contents are true or false is basically irrelevant without a trigger. A program is true if the last run was a "then" and false if the last run was an "else". The only way a "then" or "else" happens is if there is a trigger. This is true whether it is a "wait", a "repeat", or if it is a program without those items. An "if" sections current state of being "true" or "false" outside of a trigger really isn't relevant to any ISY program. The only relevant state of a program is what it was at the time of the last trigger. A wait or repeat simply open up the possibility that a trigger can occur, it is not a trigger itself and if no trigger exists, then the "if" clause status state is irrelevant as far as the continued execution of the "then/else" containing a "wait/repeat". Edited June 22, 2015 by apostolakisl
Recommended Posts