Teken Posted May 19, 2011 Posted May 19, 2011 I would like some help in creating a program which will turn on a power bar every two weeks (15 days) for 3 hours in duration. Once that time has passed, the program would end. This program would continue forever . . . I would like the program to start on Saturday at 11:00 AM, then turn off at 2:00 PM. Your help and assistance is greatly appreciated . . . Also, I would like to have a e-mail sent to me to confirm that this program has indeed started and ended. Much Thanks Teken . . .
apostolakisl Posted May 19, 2011 Posted May 19, 2011 If $State_1 is 0 Then Set 'battery charger' on wait 3 hours Set 'battery charger' off Send Notification to 'me' $State_1 = 15 If Time is 1:00:00 pm Then $State_1 -= 1 Set your initial value of $state_1 to a number which equals the number of days until you want it to trigger for the first time (taking into account whether you are writing the program before after 1pm, or whatever time you are having the program subtract 1).
C Martin Posted May 19, 2011 Posted May 19, 2011 The $State_1 is a variable that you need to create under the "Variables Tab", and that would be a state Variable. Clarence
apostolakisl Posted May 19, 2011 Posted May 19, 2011 If you haven't updated to the 3.1.x series of firmware you won't have variables. So . . . update if you haven't already. I didn't actually write the program and test it. I suggest you do that but instead of having it subtract 1 at 1pm, have it subtract 1 every second and set it to turn a light on for like 3 seconds instead of the charger for three hours. You should see the light turn on for 3 seconds every 15 seconds and get an email every 15 seconds. Once it does that cycle 3 or 4 times I think you can be confident it will work. I have lots of programs on my Elk M1G that are like this. The Elk deosn't have nearly as many time options as ISY, so this is how I do it.
C Martin Posted May 19, 2011 Posted May 19, 2011 Sorry, I assumed the Latest Version. My Bad. Using variables has enhanced the ISY platform immensely. Clarence
Teken Posted May 19, 2011 Author Posted May 19, 2011 I am stuck on the last portion of this program. How and where do I add in the time in the If portion you have below? I will definitely use your light bulb idea to confirm the operation of this program once I get this last portion done. Much thanks to both of you for the guidance. Lastly, with out the variables being a option, could this task not be done with a simple program? If Time is 1:00:00 pm Then $State_1 -= 1
apostolakisl Posted May 19, 2011 Posted May 19, 2011 I am not sure I understand your question. If you are asking what the last line is doing, it is subtracting 1 from the variable. Every day it drops by one. You need to set your variable's value to something more than 0 and after that it will drop by one every day till it hits 0, then it will jump back to 15 and start over. It is all under the variable tab. As I wrote the program, every day at 1pm it will subtract one from the variable, when the variable hits 0, your battery charger turns on for three hours, then the variable resets back to 15. As far as testing the program, I forgot that isy doesn't have a "every second" command like my Elk. It would be a pain to test. You would need to write your if statement to be If time is 1:00:00pm (or pick a time like 10 minutes from now so you don't have to wait till tomorrow!) or time is 1:00:01pm or time is 1:00:02pm or time is 1:00:03pm etc etc. Maybe you just write it like it is and trust me. I am confident it will work. You could check your variables every day and watch the number keep counting down to 0 then it will pop back up to 15. Also, you will get your email confirming it. Or write 45 lines of code as above and follow it through three cycles. And this is about as simple a program as you can get for something to happen every 15 days indefinitely. It really isn't much, just 2 programs and 1 variable. Because you want it every 15 days and ISY has no way to do every 15 days as a built in feature, this is the best I can think of. If you were OK with every 7 days then you could just set it to happen every Sunday at 1pm (or whatever).
apostolakisl Posted May 19, 2011 Posted May 19, 2011 And one more thing, set your "init value" to something more than 0. If your isy reboots for some reason the value would go to 0 otherwise and the program would never execute again. (it would go -1, -2, -3 and so on) This page might help explain variables to you a little better. http://forum.universal-devices.com/viewtopic.php?t=6063
apostolakisl Posted May 19, 2011 Posted May 19, 2011 I just played around with the "repeat" command. It lets you set it to 360 hours which is 15 days. So you could write a program with a then section of repeat every 360 hours and leave the "if" blank. Once you manually do a "run then" on it, it should keep going until you have an ISY reboot. How you would manage that automatically is a whole other story. I like my first solution. Just be aware that an ISY reboot will reset the schedule to whatever you set your "init" value to. I have my ISY plugged into a UPS so reboots only occur with firmware upgrades and I can manually reset stuff at that time.
apostolakisl Posted May 19, 2011 Posted May 19, 2011 If $State_1 is <= 0 Then Set 'battery charger' on wait 3 hours Set 'battery charger' off Send Notification to 'me' $State_1 = 15 $State_1 Init to $State_1 If Time is 1:00:00 pm Then $State_1 -= 1 $State_1 Init to $State_1 I added one line to this program to fix things up in the event of a reboot. After a reboot it will maintain the same value as when it shut down. This would only get messed up if the unit was off at 1pm. In that event it would lose one day. I also changed to <=0 on the first if. This avoids the risk of a power failure during the three hours it is waiting, which could restart the countdown from 0, getting into negative numbers where it would never fire again. With the addition of the last line, I now think this is about as robust a program as you are going to get to do what you want. If anyone knows how to fix things so it sets the variable correctly in the event of a power failure that crosses the 1pm mark, I would like to hear it.
andyf0 Posted May 19, 2011 Posted May 19, 2011 Here's a way to do it in one program .......... This changes the thermostat every other Monday from 8am to 10am to set the house temperature for my cleaning ladies. You can change the day and time and the actions to perform in the 'Then' section. I also have the possibility of a power failure at the wrong time upsetting the state but it's a small window. If On Mon From 8:00:00AM To 10:00:00AM (same day) And $Cleaning_Day is 3 Then Set Scene 'SCENES / THERMOSTAT / TStat (Sleep)' On $Cleaning_Day = 0 $Cleaning_Day Init To $Cleaning_Day Else Set Scene 'SCENES / THERMOSTAT / TStat (Away)' On $Cleaning_Day += 1 $Cleaning_Day Init To $Cleaning_Day $Cleaning_Day = 0 ; It's Mon 8am - 10am and cleaning is in progress $Cleaning_Day = 1 ; Next Monday is not a cleaning day $Cleaning_Day = 2 ; It's Mon 8am - 10am but wrong Monday $Cleaning_Day = 3 ; Next Monday is a cleaning day NOTE. $Cleaning_Day 'Init To' is updated to help preserve it through a reboot or power loss however, a reboot or power loss at the wrong time may leave $Cleaning_Day in a bad state.
TJF1960 Posted May 19, 2011 Posted May 19, 2011 Andy, Just for clarification is variable “$Cleaning_Day “ an Integer or State variable (guessing Integer)? Thanks, Tim
andyf0 Posted May 19, 2011 Posted May 19, 2011 Yes, it's an Integer. I don't see any need for the features of a state variable for this program.
Teken Posted May 19, 2011 Author Posted May 19, 2011 Andyf0, Could you write out the program I am looking for using your example above for me. Some of this stuff is just past my simple understanding right now. If <---- This line of text is what I am confused about. Time is 1:00:00 pm Then $State_1 -= 1 $State_1 Init to $State_1
apostolakisl Posted May 19, 2011 Posted May 19, 2011 Teken "If the time is 1pm" is what triggers the program to count down the variable once per day. You need the variable to go from 15 to 14 to 13 etc till it hits 0 which triggers the battery charger, then it resets back to 15. So, at 1pm, it subtracts 1. You could set it for any time you want. I just arbitrarily picked 1pm. The "init" variable is what the variable sets to at reboot. The line "$state_1 -=1" is what drops the value of the variable by 1 each day, and the line $state_1 Init to $state_1 simply sets the initialized value to the same thing as the current value, so after a reboot it will pick up where it left off (not go back to 0). Edit: Andyf0's program structure won't work for you. The difference is he is on a weekly program, you wanted every 15 days. That makes a big difference. ISY has no built in structure for that.
andyf0 Posted May 19, 2011 Posted May 19, 2011 I only saw every 2 weeks, not the 15 day part in parens. If two weeks is OK then try this: If On Mon From 8:00:00AM To 11:10:00AM (same day) And $Charging_Day is 3 Then Set 'battery charger' on wait 3 hours Set 'battery charger' off Send Notification to 'me' $Charging_Day = 0 $Charging_Day Init To $Charging_Day Else $Charging_Day += 1 $Charging_Day Init To $Charging_Day I set the end time to 11:10am to avoid the potential for the program being aborted at the end of the "Wait 3 hours". That's because of the way "Wait" and "Repeat" statements are executed.
apostolakisl Posted May 19, 2011 Posted May 19, 2011 If $Integer_1 is <= 0 And Time is 1:00:00pm Then Set 'battery charger' on wait 3 hours Set 'battery charger' off Send Notification to 'me' $Integer_1 = 15 $Integer_1 Init to $Integer_1 Else $Integer_1 -= 1 $Integer_1 Init to $Integer_1 Taking from Andy, this merges the two programs into one. You must switch to an integer variable now or the program will get caught in an endless loop.
TJF1960 Posted May 19, 2011 Posted May 19, 2011 Shouldn't the variable be set for 14 in order for the program to run "then" every 15 days?
apostolakisl Posted May 19, 2011 Posted May 19, 2011 My bad, or set the program to trigger on 1 instead of 0. I think setting the trigger to 1 is best, it makes it easier to think about every 15 days if you are setting that variable to 15. And Andy, I don't think you need the time interval 8 to 11:10 in your program. 8 am is the trigger and since you are using an integer variable nothing can interupt the wait except the time becomming 8 am again (which won't happen for 24 hours, well after the three hour wait). Edit: Actually I think the 11:10 part will kill the program. At 11:10 the program will trigger again but be false. The then clause (and the wait) will end and the charger won't get shut off, and the else clause will run. If there is a power failure that crosses that 1pm time frame, the program will shift back one day. If there is a power failure during 1 to 4 pm on the charging day, it will charge again the next day and also set the program back one day. I would love to hear any ideas about how to make that stop. Andy's program would get shifted back one week If $Integer_1 is = 1 And Time is 1:00:00pm Then Set 'battery charger' on wait 3 hours Set 'battery charger' off Send Notification to 'me' $Integer_1 = 15 $Integer_1 Init to $Integer_1 Else $Integer_1 -= 1 $Integer_1 Init to $Integer_1
andyf0 Posted May 19, 2011 Posted May 19, 2011 I'm not sure your program willl work. At the beginning or end (never figured out which it is) of the wait the 'if' will be re-evaluated. It will no longer be 1pm so will abort the 'then' and run the 'else'. By specifying a start and end time the 'if' will still evaluate to true and 'then' will continue to run. Originally I did the 8am to 10am because that's how long the cleaning ladies worked and I wanted the thermostat to back to "Away" mode. From the Wiki: Statement Execution Order Within the Then or Else clause of a program, statements are executed from top to bottom in the order in which they occur. When a statement calls another program, the called program begins executing, and the calling program immediately continues execution with the next statement in sequence--it does not wait for the called program to complete before continuing. 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 Else clause) to the Else clause (or the Then clause). Therefore, if a Then clause (or an Else clause) contains no Wait or Repeat statements, the entire clause is atomic, and will complete before the program's conditions are reevaluated. Edit: Come to think of it maybe schedule based 'if's don't apply because I have a Sprinkler program that does multiple 'Wait's starting at 4:30am and that never aborts.
apostolakisl Posted May 19, 2011 Posted May 19, 2011 No, that isn't how it works. A wait clause does not run an if clause, it only makes it available to run. Your program will run the if clause at 11:10 becuase 11:10 is a trigger. This will kill your then clause prematurely and execute your else clause. This came up in another thread earlier in the week. During a wait, the program's if section becomes available again for triggers, but the wait itself is not a trigger. The if section will sit idle unless some part of it is a trigger, just like it does at any other time, "waiting" or not. In my program there is only one thing that will run the if clause, and that is the time becomming 1pm. Try it, I swear.
andyf0 Posted May 19, 2011 Posted May 19, 2011 If that's truely how it works then the Wiki is wrong. "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."
apostolakisl Posted May 19, 2011 Posted May 19, 2011 Andy, That isn't written properly. An if statement is not actually run, it won't become false when it hits the wait. It will only become false if there is a statement in there that is a trigger (like a state variable that changes value, or a status of a light). I promise you. Try it. I swear.
andyf0 Posted May 19, 2011 Posted May 19, 2011 I was just thinking about how that couldn't possibly be right. You'd end up in an infinite loop all the time if it was. if Status LightA is On Then Set LightB On Wait 5 secs If it was the way it's written you'd end up in an infinite loop until you turned LightA Off. Sorry about that, I wish there was a more accurate explanation because this has set off a small grenade in my head. So that's how my Sprinkler program still works
Recommended Posts