mink Posted May 12, 2011 Posted May 12, 2011 Upon reflection, it seems to me that as long as the programstatements in the loop do not involve conditions requiring interaction from devices, but rather work with variables and programs which also are mainly internal to the ISY, the latencies and load from even a fair number of such programs should be low. After all the ISY is a 200mHz processor. In the above example the only device interaction will be when the loop count completes and a valve and perhaps a kpl light gets turned on or off, every 10-30 minutes. Am I understanding things right? thus if one codes to use minimal device status or queries, but use variables and program status for logic, and mainly use the powerline to generate actual control commands there should not be much traffic on the powerline. TIA
Illusion Posted August 11, 2011 Posted August 11, 2011 Thanks for the tough editing work. Through this post I finally understand State Machine programming. Now I will read the post that modifies it using variables with an actual understanding of the basic concept. One edit for the original post: ISY Programming Methodology(state-machine approach) edited from posts by ergodic in June 2010 I’ll start with a simple example: Press a keypad button ("KPL A") three times in succession to turn on a light.If more than 5 seconds elapses between presses,then the sequence resets and you have to start over. I think this should be KPL-D not KPL-A based on the text in the rest of the post.
dnl Posted August 15, 2011 Author Posted August 15, 2011 I think this should be KPL-D not KPL-A based on the text in the rest of the post. Thanks Illusion. Right you are. Actually, there was more than one instance of "KPL A" in the first example and I updated the post to correct them.
ergodic Posted August 15, 2011 Posted August 15, 2011 It is also possible to implement a variable wait using a pair of programs - one to start the process and one to 'step down' to zero. And a simple (non-state) variable to implement the wait interval. For instance, this turns on a light after $V seconds (30 seconds in this case): //___________________ //Program TestVarWait If Then $V = 30 Run Program 'Wait.V' (If) //______________ //Program Wait.V If $V > 0 Then Wait 2 seconds $V -= 2 Run Program 'Wait.V' (If) Else Set Scene 'Scene: U/S Office Desk' On The main advantage of this design is you can treat "Wait.V" as a subroutine of sorts, callable with different wait times from different programs. Note that this does lose the initial value set into $V. The main issue with this is that the "Run Program Wait.V" (at the end of TestVarWait) executes asynchronously and so execution continues immediately. That is not an issue here, but if you are waiting for the event to occur before you proceed on, you need to add logic to initialize and in effect wait for "Wait.V" to become false. This seems to require creation of yet a third program. I've tried a bit to concoct something simpler using state variables to handle this, but without any real success - maybe someone else has an idea. Even with a 1 second increment, the variability I've seen seems quite small, though I wouldn't use that for something involving hours. And since even trigger / state variables aren't used for this and the actual executions are trivial, I'd be astonished if this adds any real loading to the ISY.
dnl Posted August 15, 2011 Author Posted August 15, 2011 The main issue with this is that the "Run Program Wait.V" (at the end of TestVarWait) executes asynchronously and so execution continues immediately. That is not an issue here, but if you are waiting for the event to occur before you proceed on, you need to add logic to initialize and in effect wait for "Wait.V" to become false. This seems to require creation of yet a third program. I've tried a bit to concoct something simpler using state variables to handle this, but without any real success - maybe someone else has an idea. Hi ergodic, I think your example code could use the ELSE clause to achieve some synchronization. Execution of the following code would be initiated by setting $F = 0. What do you think? //___________________ //Program TestVarWait If $F = 0 Then $V = 30 Run Program 'Wait.V' (If) Else Run Program 'DoItNow' (If) //______________ //Program Wait.V If $V > 0 Then Wait 2 seconds $V -= 2 Run Program 'Wait.V' (If) Else $F = 1
Goose66 Posted August 16, 2011 Posted August 16, 2011 Pardon my ignorance, but what is the advantage of this over simply: Wait 60 seconds Run Program 'DoItNow' (If) ?
dnl Posted August 16, 2011 Author Posted August 16, 2011 Pardon my ignorance, but what is the advantage of this over simply: Wait 60 seconds Run Program 'DoItNow' (If) ? The advantage is that the delay time is programmable. Some day I am sure UDI will support the use of variables in a wait statement but until then something else is needed.
Goose66 Posted August 16, 2011 Posted August 16, 2011 I guess I don't see how coding the setting of a variable to a specific value and then calling a program to perform the wait is any more "programmable" or flexible than simply coding the Wait statement with the desired value. In fact, it seems to add complexity and an additional program that is not otherwise needed. I guess if you wanted to set the variable with a REST call and then execute the program, but I don't think that is possible as of now, right?
polexian Posted August 16, 2011 Posted August 16, 2011 I was confuse on the wait variables at first but mike explained it to me like this. When you invoke a wait statement the wait xx time later it will rerun to the if checks and if one of them is false the program stops. That is why you do your wait in a separate program of your Ifs to invoke the wait and then at the end of the wait run the end of the program or goto a new program to be ran. I hope this helped you also. --- - Sent from my iPhone using Tapatalk
dnl Posted August 16, 2011 Author Posted August 16, 2011 I guess I don't see how coding the setting of a variable to a specific value and then calling a program to perform the wait is any more "programmable" or flexible than simply coding the Wait statement with the desired value. In fact, it seems to add complexity and an additional program that is not otherwise needed. I guess if you wanted to set the variable with a REST call and then execute the program, but I don't think that is possible as of now, right? Agreed the complexity is greater but I can see some ways where this technique might be used to advantage. 1) The delay time can be the result of a calculation. The ability to do calculations right now is limited but not non-existant.2) The delay code can be packaged as a subroutine and called from multiple places, reducing program maintenance. Of course, it may be necessary to take care not to call the routine again before it completes.3) I don't know whether a variable can be set directly from a REST call but I believe it is possible to do it indirectly by controlling which programs execute and having those programs set a variable as desired. There may not be many instances where we need or want to do any of these things but if we do, some approach like what ergodic suggests is needed.
jsp Posted August 17, 2011 Posted August 17, 2011 This post allowed me to understand how this works, thanks. If I can make on suggestion, it seems that the way we have to use this programming, some types of programs, the ones with the IFs or WHENEVERs would be triggers and other ones would be the real PROGRAMS or procedures that are called from triggers and some could be considered VARIABLES, cause they are currently used as boolean variables after verifying/meeting a condition in some ways. My 2 cents.
Hurting2Ride Posted August 18, 2011 Posted August 18, 2011 The main advantage of this design is you can treat "Wait.V" as a subroutine of sorts, callable with different wait times from different programs. Just be cautious in your use of it that way since it would be shared between any programs that happen to trigger during the same time. Such as the one that runs a sprinkler valve to top off your pool for 5 minutes and the one that closes your garage after an hour.
plipof Posted July 28, 2012 Posted July 28, 2012 I have been trying to make sense of the "hit the button 3 times within 5 seconds example." I am totally confused. Is there any way you can tell me what the other SCond and SBody programs would be so i can stare at it and try and make sense of it. WIth just S1 and part of S3 I am very confused.
robr Posted December 19, 2012 Posted December 19, 2012 the 5 second wait is useful in that when you press the button, it transitions from off to on between each of the 4 states (0,1,2,3). the kepad will light from "off" to "on" on the first press. The program then clears the light back to "off" giving you feedback that the 5 second wait is counting down. press the button again, the light goes on, program turns the light off, letting you know to press again. third press, light goes on, at this point you're in the s3_body code, so you can leave the light on letting you know that it took. note in s3_body I set a state variable, I use this elsewhere to trigger code to "activate" whatever I intended the 3 presses to do. the programs are as follows: (note, i renamed them to shorten them up but you can easily follow the flow) ========================================= s0_body ========================================= If - No Conditions - (To add one, press 'Schedule' or 'Condition') Then Run Program 'S1_body' (Else Path) Run Program 'S2_body' (Else Path) Run Program 'S3_body' (Else Path) Else - No Actions - (To add one, press 'Action') ========================================= s1_cond ========================================= If Program 'S0_body' is True And Control 'Key_g' is switched On Then Run Program 'S1_body' (Then Path) Else - No Actions - (To add one, press 'Action') ========================================= s1_body ========================================= If - No Conditions - (To add one, press 'Schedule' or 'Condition') Then Run Program 'S0_body' (Else Path) Run Program 'S2_body' (Else Path) Run Program 'S3_body' (Else Path) Set Scene 'Key_g' Off $State_1 = 0 Wait 5 seconds Run Program 'S0_body' (Then Path) Else - No Actions - (To add one, press 'Action') ========================================= s2_cond ========================================= If Program 'S1_body' is True And Control 'Key_g' is switched On Then Run Program 'S2_body' (Then Path) Else - No Actions - (To add one, press 'Action') ========================================= s2_body ========================================= If - No Conditions - (To add one, press 'Schedule' or 'Condition') Then Run Program 'S0_body' (Else Path) Run Program 'S1_body' (Else Path) Run Program 'S3_body' (Else Path) Set Scene 'Key_g' Off Wait 5 seconds Run Program 'S0_body' (Then Path) Else - No Actions - (To add one, press 'Action') ========================================= s3_cond ========================================= If Program 'S2_body' is True And Control 'Key_g' is switched On Then Run Program 'S3_body' (Then Path) Else - No Actions - (To add one, press 'Action') ========================================= s3_body ========================================= If - No Conditions - (To add one, press 'Schedule' or 'Condition') Then Run Program 'S0_body' (Else Path) Run Program 'S1_body' (Else Path) Run Program 'S2_body' (Else Path) Set Scene 'Key_g' On $State_1 = 1 Run Program 'S0_body' (Then Path) Else - No Actions - (To add one, press 'Action')
skifiend Posted March 28, 2013 Posted March 28, 2013 I was wondering if someone could help me figure out what I'm doing wrong in my programs. The programs should trigger once the last person has left the house, then the goal is to send some notifications at some intervals and eventually turn off lights and devices if no one returns. My variable $X3 indicates the number of people in the house (works reliably) and $AwayNotified keeps track of whether a notification was sent (to avoid repeat notifications). When $X3 turns 0 (last person has left the house), I want to send a notification saying that lights will turn off in 15 minutes. If after 15 minutes X3 is still 0, I want to send another message saying lights will turn off in 5 minutes. If after 5 minutes X3 is still 0, the ISY will turn down thermostats, turn off lights and music systems. My programs are the following (all the Else conditions are empty): Program Away.S0.Cond (Run at Startup) If - No Conditions - Then Run Program 'Away.S0.Body' (Then Path) Program Away.S0.Body If - No Conditions - Then Run Program 'Away.S1.Body' (Else Path) Run Program 'Away.S2.Body' (Else Path) Run Program 'Away.S3.Body' (Else Path) Program Away.S1.Cond If Program 'Away.S0.Body' is True And $X3 is 0 And $AwayNotified is 0 Then Run Program 'Away.S1.Body' (Then Path) Program Away.S1.Body If - No Conditions - Then Run Program 'Away.S0.Body' (Else Path) Run Program 'Away.S2.Body' (Else Path) Run Program 'Away.S3.Body' (Else Path) Send Notification to 'Default' content 'Absence 1' Program Away.S2.Cond If Program 'Away.S1.Body' is True And $X3 is 0 And $AwayNotified is 0 Then Run Program 'Away.S2.Body' (Then Path) Program Away.S2.Body If - No Conditions - Then Run Program 'Away.S0.Body' (Else Path) Run Program 'Away.S1.Body' (Else Path) Run Program 'Away.S3.Body' (Else Path) Wait 15 minutes Send Notification to 'Default' content 'Absence 2' Program Away.S3.Cond If Program 'Away.S2.Body' is True And $X3 is 0 And $AwayNotified is 0 Then Run Program 'Away.S3.Body' (Then Path) Program Away.S3.Body If - No Conditions - Then Run Program 'Away.S0.Body' (Else Path) Run Program 'Away.S1.Body' (Else Path) Run Program 'Away.S2.Body' (Else Path) Wait 5 minutes Resource 'DenonPwrOff' Resource 'SonosMBRStop' Resource 'SonosMediaRoomStop' Resource 'SonosLivRoomStop' Resource 'TStatOffice Away' Resource 'TStatUpstairs Away' $AwayNotified = 1 Run Program 'Away.S0.Body' (Then Path) Program Away.Notified.Reset If $X3 > 0 And $AwayNotified is 1 Then $AwayNotified = 0 Currently, what happens when $X3 turns 0 is that S2Body runs and ends but S3Body does not run. I'd appreciate any tips. Thanks.
Xathros Posted March 28, 2013 Posted March 28, 2013 I got lost trying to follow that logic so I thought about the requirement and have the following to offer: I am assuming $X3 is a State variable. If $X3 = 0 Then wait 5 minutes Notify #1 - 15 mins till shutdown... $AwayNotified = 1 wait 10 minutes Notify #2 - 5 Minutes till Shutdown... wait 5 minutes Set scenes off Set thermostat back. If $X3 > 0 and $AwayNotified > 0 then Notify Away Mode cancelled Set Thermostat to normal settings. Set whatever else $AwayNotfied = 0 Why wouldn't that work? -Xathros
skifiend Posted March 28, 2013 Posted March 28, 2013 Thanks for your suggestion, Xanthros. Yes, $X3 is a state variable. If $X3 changes to >0 during the wait, I'd like to stop further processing, i.e., no more notifications and no turning off scenes. I am not clear on how exactly the wait command works. Would your code accomplish the interruption? I'll have a chance to try it this evening.
MikeD Posted March 28, 2013 Posted March 28, 2013 Not sure if I am reading it correctly or if my logic is correct but I believe "Program Away.S3.Body" is not running because it is dependant on the statement "Program 'Away.S2.Body' is True" however that program's 'If' is not called therefore it is never evaluated true or false. ~Mike
Xathros Posted March 28, 2013 Posted March 28, 2013 Thanks for your suggestion, Xanthros. Yes, $X3 is a state variable. If $X3 changes to >0 during the wait, I'd like to stop further processing, i.e., no more notifications and no turning off scenes. I am not clear on how exactly the wait command works. Would your code accomplish the interruption? I'll have a chance to try it this evening. $X3 being a state variable will cause the If to reevaluate any time it's value changes. The waits will be canceled when it changes to anything > 0. The timers will only expire if $X3 remains at 0 for the full duration. I'm quite sure that will meet your requirements. -Xathros
skifiend Posted March 28, 2013 Posted March 28, 2013 Not sure if I am reading it correctly or if my logic is correct but I believe "Program Away.S3.Body" is not running because it is dependant on the statement "Program 'Away.S2.Body' is True" however that program's 'If' is not called therefore it is never evaluated true or false. ~Mike Good to know. This helps my understanding going forward. I was actually thinking of using explicit state variables to keep track of state instead of relying on a program's returned value. I'll try Xanthros' code but your suggestion is helpful for multi-state programs. Thanks.
skifiend Posted April 1, 2013 Posted April 1, 2013 I got lost trying to follow that logic so I thought about the requirement and have the following to offer: I am assuming $X3 is a State variable. If $X3 = 0 Then wait 5 minutes Notify #1 - 15 mins till shutdown... $AwayNotified = 1 wait 10 minutes Notify #2 - 5 Minutes till Shutdown... wait 5 minutes Set scenes off Set thermostat back. If $X3 > 0 and $AwayNotified > 0 then Notify Away Mode cancelled Set Thermostat to normal settings. Set whatever else $AwayNotfied = 0 Why wouldn't that work? -Xathros It worked. The only change I had to make was to move the "$AwayNotified = 1" statement to the bottom (of the first if statement). As the variable is in the condition list, the subsequent waits were being interrupted. Thank you.
No Pressure Posted May 26, 2013 Posted May 26, 2013 This approach to programming the ISY is very useful once you "get it." I'm sure I could get similar results using if..then..elses with variables and etc, but troubleshooting my devices is so easy with this organization. That said I keep rewriting my programs to make them increasingly efficient, organized and uniform. Thus far I've identified 9 states per switch. That's 9 X 8 changes to the Run Else lines of the program. It's tedious. What's the best way to cut, "search and replace" and save method?
LeeG Posted May 26, 2013 Posted May 26, 2013 A right click on My Programs allows Find/Replace to be selected which will change the Programs. The Save has to be done separately.
johnstonf Posted December 19, 2015 Posted December 19, 2015 (edited) Hi All, This post is quite long-in-the-tooth (and good)... I am new to all of this. Can anyone point me to the latest and greatest to learn ISY programming, but using the new variables, event programming, etc, starting with event concepts etc, using variables. I'm scared of learning concepts here, that may no longer apply using variables, etc Thanks! Edited December 19, 2015 by johnstonf
larryllix Posted December 19, 2015 Posted December 19, 2015 (edited) Variable usage is exactly the same except you compare to a variable instead of time or wait for a device to send a command. State variables can cause triggers and Integer variables are only for filtering conditions. Edited December 19, 2015 by larryllix
Recommended Posts