Jump to content

dnl

Members
  • Posts

    75
  • Joined

  • Last visited

Everything posted by dnl

  1. Thanks oberkc, I added one of the KPL buttons as a controller and it worked as you knew it would. I then added the rest. As I watched the update process, it occurred to me that (among other things) the ISY provides a friendly user interface to build control tables in the Insteon devices. Apparently the ISY keeps track of the tables it builds so that it can interact properly with devices as both responders and controllers. So, the ISY and the Insteon devices are a distributed computing system. By increasing the complexity of the tables in the devices, more processing can be done in the devices, response is quicker and ISY programs are simpler. Why couldn't I see that sooner?
  2. I recently added a fourth Keypadlinc to my home. I programmed the ISY to handle its Scene-A button the same as I did for the first three KPL but it did not work the same way. I discovered a fix and learned a few things along the way. I called SmartHome technical support. We quickly decided the problem must be in the way I had setup things in the ISY. The tech said he was not an ISY expert but he thought I had setup things in an unusual way. I am writing to report what I learned and to ask if there is a better, more reliable way to do things. I have two scenes: Scene "All Lights" contains all of the controlled lights as responders. Scene "All Lights KPL" contains the A button of all KPL.Family Room KPL-(A) All Front Door KPL-(A) All Garage KPL-(A) All Master Bedroom KPL-(A) All When I first created this second scene, I added all KPL-A buttons as both controllers and responders. More about this later. I have three programs: Program: All Lights Status If Status 'Den Light' is On Or Status 'Family Room KPL' is On Or Status 'Front Door KPL' is On Or Status 'Kitchen Overhead Lights' is On Or Status 'Master Bedroom KPL' is On Or Status 'Hall Bedroom Light' is On Or Status 'Christmas ILR' is On Or Status 'Garage Inside Lights' is On Or Status 'Garage KPL' is On Then Wait 1 second Set Scene 'All Lights KPL' On Else Set Scene 'All Lights KPL' Off Set Scene 'Christmas Lights' Off Program: All Lights Turn Off If Control 'Front Door KPL-(A) All' is switched Off Or Control 'Master Bedroom KPL-(A) All' is switched Off Or Control 'Family Room KPL-(A) All' is switched Off Or Control 'Garage KPL-(A) All' is switched Off Then Set Scene 'All Lights' Off Else - No Actions - (To add one, press 'Action') Program: All Lights Turn On If Control 'Family Room KPL-(A) All' is switched On Or Control 'Front Door KPL-(A) All' is switched On Or Control 'Master Bedroom KPL-(A) All' is switched On Or Control 'Garage KPL-(A) All' is switched On Then Set Scene 'All Lights' On Else - No Actions - (To add one, press 'Action') If any light in the first scene is on, the KPL-A button is lighted on all KPL. If a KPL-A button is pressed when it is dark, all lights in the first scene are turned on. If a KPL-A button is pressed when it is lighted, commands are sent to turn off all lights in the first scene. Everything worked as desired until I added the fourth KPL. Everything was still OK for the first three KPL but the fourth KPL acted differently. Its KPL-A button would turn on/off all lights in the scene except for the load on that KPL. The KPL-A buttons on the other three KPL would control all lights correctly including the load on the fourth KPL. After my call to SmartHome technical support, I removed the KPL-A button from the second scene and added it again as only a responder. At that point, everything worked perfectly. Aha -- the KPL buttons do not need to be controllers! I then removed the KPL-A buttons for all other KPL and added them back as responders only. Now that things are working correctly, I am ready to learn more. Is there a better way to control "all lights"?
  3. I woke up thinking about this post and realized I could have written just a little bit more to explain why the state-approach can be a good way to design programs. If we start with the original example of how to handle two switch-OFFs, the state approach may seem much too complicated and not worth the extra effort. That may be true but it could be worth it if you need extra control. For example, the state approach would avoid restarting the 3-sec window if that is important and would allow you to do different things depending on whether the second OFF came within the 3-sec window or not. I think the real value comes when you want to extend the programs for third, forth, fifth ... presses. They could be any sequence of ONs and OFFs. I listed four states above. State S2 does one thing if a second OFF comes within the 3-sec window and state S3 does another thing if a second OFF does not come within the 3-sec window. If we do not want to do anything without the second OFF, then state S3 can be eliminated. When state S2 times out, it just goes back to state S0. Let's keep the example of not doing anything if there is no second OFF. With this example, we can extend the programming to handle a third OFF by adding a single state. Now a new state S3 handles the third OFF. A state S4 could handle a fourth, and so on. Each additional state would require a very minor change to one existing program and two new programs that have the same structure used for the earlier states. After you have programs working for two OFFs, it would be almost trivial to extend them to any number of OFFs and ONs. This has strayed from the original topic of faston and fastoff. Sorry johnmsch. I did not mean to hijack your thread.
  4. Hi northportphoneguy, You are right that additional flag programs would be needed. Additional logic is also needed to tighten up the control of the 3-second (or whatever length) windows. In your original programs, the window can be restarted. If someone turned off the switch every two seconds, the window would keep restarting and the flag program would remain true. This would prevent the remaining programs from running the right way. There are many ways this could be done. You could use additional flag programs or use enable/disable/stop commands to control program execution. One way to do the programming that I recommend is to look at this as a series of different states. If we look at your original programs, we can express this in four states. 1. State S0 initializes everything to starting condition. 2. State S1 occurs when the switch is toggled OFF. 3. State S2 occurs when the switch is toggled OFF again within 3 seconds. 4. State S3 occurs when the switch is not switched OFF within the 3-second window. One program is written to control the change between states and another program is written perform the actions for each state. This sounds a lot more complicated that it actually is. A very nice way to design the programs was written by ergodic. I have found his method very helpful when the programming gets complicated. See the thread "Triggers and conditions and IFs, oh my!" for details. I have found a few ways to optimize his approach but I am still working on the details. I may write it up after I gain more confidence with my changes.
  5. Hi northportphoneguy, The three programs you describe have a quirk you may or may not recognize. When 'Small Bedroom' is switched off the first time, the first program runs its Then clause that runs the flag program 'Virtual Flag'. The second program also runs when 'Small Bedroom' is switched off but, because Virtual Flag is false at that time, its Then clause is not executed. If 'Small Bedroom' is switched off again during the 3-second window, the second program runs and, because 'Virtual Flag' is now true, its Then clause executes. The unexpected quirk is that the first program also runs again and restarts the 3-second window. If 'Small Bedroom' is switched off a third time during the restarted window, the second program would run its Then clause again. The first program would also restart the 3-second window yet again. This may not cause any problems but it is something to consider. More specifically, the longer sequence you suggest would not work without some additional logic to disable or inhibit the first program(s).
  6. No. During tests I could successfully switch faston or fastoff several times in a row and I would begin to think I had finally learned the secret -- then it would fail several times in a row. I agree with northportphoneguy, it does not pass the wife test. I use keypad buttons to set vacation mode reliably but I keep this one switch programmed as described above because I can turn off the mode from my den where no keypad is close by. I endure the double-flip frustration because it saves me a few steps. I may replace my code with what Rand or northportphoneguy suggested.
  7. The togglelinc relay does have a beep function. The beep is not very loud. The device emits one or more beeps when you hold up the paddle to link it to the ISY or other devices. The program statement allows you to specify the beep duration but as far as I can tell that parameter does not have any effect. I do not hold onto the paddle. I rest my hand against the faceplate, put my index finger under or over the paddle and flip the finger twice as fast as possible. Obviously the switch does not care how I hold my hand but that is what I need to do to toggle it fast enough.
  8. Hi johnsmsch, Your experience is consistent with mine. As others have stated, the double-flip must be very quick. I learned I must stand to the side a bit, rest the heel of my hand on the switch faceplate and flip the toggle as quickly as possible. I tried using faston and fastoff with several togglelincs. I discovered that some units were more difficult to use than others but I could never be assured that a quick double-flip would result in a "fast" command. For my use, I can tolerate a failure because I use both faston and fastoff to toggle a "vacation" state. I keep double-flipping until it works. I use the beep function to notify me if it worked. One beep means the state is turned off. Three beeps means the state is turned on. Here are the two programs that perform the functions: TURN ON vacation mode: If Program 'Vacation Status' is False And ( Control 'Den Light' is switched Fast On Or Control 'Den Light' is switched Fast Off ) Then Run Program 'Vacation Scheduling Start' (Then Path) Set 'Den Light' 250 (Beep Duration) Set 'Den Light' 250 (Beep Duration) Set 'Den Light' 250 (Beep Duration) Else - No Actions - (To add one, press 'Action') TURN OFF vacation mode: If Program 'Vacation Status' is True And ( Control 'Den Light' is switched Fast On Or Control 'Den Light' is switched Fast Off ) Then Run Program 'Vacation Scheduling Stop' (Then Path) Set 'Den Light' 250 (Beep Duration) Else - No Actions - (To add one, press 'Action') The scheduling start and stop programs control the value of 'Vacation Status'.
  9. Hi LeeG, Sorry, I did not mention the thought that the switch might be responding to a command the PLM sends out. I mention the PLM because apparently the problem for Illusion started after he replaced his PLM. I thought maybe the new PLM might have a different firmware version -- maybe with a new bug or with an old bug now revealed because something else in the firmware changed. I also thought the PLM would be able to generate a valid device address because (I think) device addresses are stored in the PLM -- correct? Even so, I guess it is unlikely that the PLM would keep picking the address for the switch in this particular location. I offer the thoughts for whatever they are worth. Maybe they can stimulate better ideas.
  10. I have been following this thread with much interest. I am a new user of Insteon devices and the ISY so I probably can't add much to this issue but I do have two questions. Is it known for certain that the Insteon device itself is issuing the messages? Is it possible that a bug in the PLM could cause the PLM to issue a bogus event in response to what it receives from the motion sensor?
  11. mlennox, You are very welcome but the real credit is due to ergodic. He's the creator -- I only did some editing.
  12. Hi Walrus, I recently encountered a similar situation. A single AP solved the problem. First of all, RF propagation for the frequencies used by Insteon devices are affected by the thickness and density of the material between transmitter and receiver. With your ceramic tile and the wire mesh, you have a fairly effective RF barrier. I think you are fortunate to receive a signal from even as close as 12 feet. In my case, I had only conventional wood studs, joists, beams, subfloors, drywall, etc. I installed an Insteon motion sensor high on a second floor and the PLM low on a first floor. The two worked generally OK during testing until I placed the MS in a location where an additional beam and edge of a loft floor blocked the signal. With that change, the PLM (as recorded in the ISY log) did not receive anything from the MS. I added an AP that had line-of-sight to the MS, is close to the PLM (directly above the PLM on the second floor) but on the opposite phase. Everything is now rock solid.
  13. Hi JP, Interesting information but I don't think it applies to the issue here. My email server uses port 465 and requires SSL as you described. The ISY notification feature does not (yet) support SSL. Ben-smith suggested I try port 587 with TSL (as I understand it, all email server software should support port 587 but not all OS are configured to have that port open). In any case, I tried port 587 on one ISY and it did not help. I tried port 587 on another ISY at a different location (using the same server name and email account) and it did work.
  14. Hi Ben, An update -- I tried port 587 with TLS checked on another ISY at a different location and it worked (same server and email account). Because of the difference in location, I am fairly sure a different DNS was used. Perhaps the server name resolved to a different physical machine and that machine has port 587 open? Any thoughts?
  15. Using port 587 with TLS checked I get "Mail server failure: [AUTH LOGIN not accepted]." I guess I will open a freebie email account somewhere and use that. Thanks for your suggestions.
  16. You might try Sub-Routine's suggestion and add a Query to the repeat loop. That would allow you to get a better idea how often the problems occur and whether a repeated command by program works or fails.
  17. Hi Jim, If you used the cables that were supplied with the ISY, then they obviously should be the correct type. The cables I received are Cat5e. I will add my reassurance to what others have said. The support I have seen from Universal Devices and Insteon is extremely good and they will help you get things up and running.
  18. Hi Jim, You probably are already on the right track with a replacement coming. I noticed that you said you used Cat5 cables. I have been using Cat5e and Cat6 cables without problem. When I tried using a Cat5 cable, the ISY and PLM would not communicate. This is not what I would have expected. Perhaps my Cat5 cable was bad. I did not check it but I believe it is good - I had used it before and I had not used it since then. Maybe some others who know more than me can advise whether the ISY or PLM can adapt their speed to use a Cat5 cable.
  19. You probably have checked this but ... Is the PLM connected to the same phase as the devices that sometimes do not turn off? Do you have access points or filters that bridge the two phases in your house? If the answer to both questions is "no" you may want to get some Insteon access points or phase-bridge filters. Do the problems tend to occur at certain times of day? If so, you might look for devices that run on a schedule or run more often at those times -- they could be outside your house.
  20. Thank you for the suggestion. I entered the IP address you gave -- same result. EDIT: I tried a different account with a different SMTP server. That works OK. The only significant difference I can see between the two servers is that the ATT server requires a secure socket layer (SSL). If that difference is the cause of the problem, is there a solution?
  21. Hi Ben, I tried the change you suggested. The result was the same. I also tried "xyz" just to try a nonsense server name. The response changed to [Connection failed] so it appears that with "att" and "sbcglobal" in the serer name the ISY is at least finding a server.
  22. Hi Rand, I entered the complete email address with my id and the domain. It may be significant to note that the domain is sbcglobal.net.
  23. I cannot get notifications to work. I bet this problem has been posted a lot but I could not find anything on the forum that helped me. I entered my outgoing server information to match what I use in Outlook but when I click the "Test" button I see a dialog with "Mail server failure [server not responding]". I increased the timeout to 2000 ms and tried TLS checked and unchecked but still no go. Can anyone help? I upgraded to 2.8.10 RC6 Settings are: SMTP Server: smtp.att.yahoo.com User ID: my_email_address From: my_email_address SMT Port: 465 Password: my_password Timeout: 2000 I know my SMTP server requires authentication but I do not know what else to set in ISY to authenticate me.
  24. ISY Programming Methodology (state-machine approach) edited from posts by ergodic in June 2010 The ISY uses what technically would be termed "functional" (i.e.; stateless, variable-less), "event" programming and that is not the way people think at all. So you need some methodology that bridges that gap. Ad-hoc programming in the ISY just doesn't work for me. If you can identify what you want to do and diagram it, then have some rote mechanical method to develop the ISY programs from that, it is much, much easier to get something that works, that you are sure should work at least, and also can be expanded or changed later without introducing errors that are difficult to find and correct. The end programs may not be pretty to look at, but what ISY programs are? I'll describe a method that is easy to understand, quick, and once you've outlined your logic on paper, it is straightforward to produce a set of ISY programs that implement it reliably. I'll start with a simple example: Press a keypad button ("KPL D") 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 use something like this for my garage door open programming: it prevents the door from opening if you happen to hit the KPL button by accident. You can also have a little fun with this idea, for example, turning the aux buttons of a KPL into a combination lock. I'll also note that to actually do this, you may know that Insteon requires we create a scene ("Scene KPL-D") with the button in it, just to be able to toggle the keypad light on and off from the ISY. To start, draw big, labeled circles to represent all the different "states" of your process. These are generally the places where you are "doing" or "waiting" for something. For example, "the garage door is open and we're waiting for the close button." Each situation is different but generally the states will fall out pretty quickly once you've grasped the idea and you start to diagram the flow of your particular logic. States generally map to a particular point of logic: (e.g.; "My garage door was opened by a motion sensor and we're waiting for the off from the motion sensor.") And you'll always have a starting "quiet" state that does nothing. In this example the states are pretty easy to see, there are four: a start/reset state, a state for the button having been pressed once, pressed twice, and pressed three times. We'll use labels S0, S1, S2 and S3. Then you draw arrows between the states. Label the arrows with the triggers that cause that particular state change. Anyone with an information science background will immediately recognize this as a basic "state machine". No matter, just diagram how your logic flows from one state to the next. Don't worry about the ISY just yet. And don't worry if your logic isn't fully developed, you can always go back later and expand on it. For this little example, we draw an arrow out from the edge of the S0 circle to the edge of the S1 circle, indicating a press of KPL-D when you're in state S0 takes you to state S1 (first button press). Likewise S1 to S2, and S2 to S3. These are of course all basically the same transitions, but the only way a state-based system has to "remember" anything is by the state it is in. We don't need no stinkin' variables or, more precisely, the states themselves are our variables. This is partly why this model works so well for the variable-less ISY. The important thing to understand about state diagrams is that you have no idea how you got to the state you're in. If you need to "know" that for your logic, you create more states. Inside or near each state's circle you note what that state does when it is activated. For example, S1 turns off the KPL light to indicate it is ready for another press, waits 5 seconds and then, assuming nothing else has interrupted it, it returns to state S0. S1, S2 and S3 all will have arrows back to S0 representing this "timeout" transition (i.e.; you waited too long to press a key and the state reverts to S0). I like to draw these explicit transitions from inside the circle. I'll also point out that in a less trivial example than this, for example, one involving motion sensors, you often have arrows going from a state back to itself. For example, if a motion sensor sends a repeated "on" signal while you are waiting in a state, you want to restart the timeout countdown in that state by re-entering the state. Now, if you've suffered with this explanation this far, I recommend you try implementing this in your ISY to get a feel for the process. The basic idea is to separate figuring out what you want from the actual ISY programming. Now that we have our diagram, we can easily implement our logic by set of ISY program from a rote procedure. Each state will be represented by two ISY programs. One program will test the conditions, which correspond to all the incoming "arrows" to that state that represent the various trigger conditions into it. A second program performs whatever that state is supposed to do. Here were are at the eternal sticking point: Why two programs for one state? All we need is one set of conditions and one "Then" body to execute it. So ... one program, right? Wrong. The ISY executes either the Then or Else body of a program whenever any of its trigger conditions are TESTED. (This means the Then or Else body of a program will be interrupted and restarted if that program is currently executing a Wait or Repeat command.) This causes the program to be reset and could be (often is) really a Bad Thing; we want the code for our state to run only when one of the trigger conditions (incoming state changes) is True, not each and every time they are simply checked by the ISY. If you don't understand why, keep reading and thinking about it until it makes sense. It is critical to understanding the difference between the way you might think and the way the ISY thinks. In this example, we end up with eight programs for our four states. We'll call them here S0Cond, S0Body, S1Cond, S1Body, and so forth. The structures of the four S#Cond programs are basically the same; just tests for conditions of the incoming triggered transitions that activate into that state. If any of the conditions are True, the "Then" part calls the corresponding S#Body for that state. You must run a separate S#Body program. Do not put your state code in the "Then" part of the S#Cond program. It might work after a fashion but it will not consistently work the way you want. So here's the basic skeleton of our S1Cond program: If Program 'S0Body' is True And Control 'KPL D' is switched On Then Run Program 'S1Body' (Then Path) The condition program connects each transition coming into this state with a pair of "AND" ed tests. One test identifies the state you're coming from and the other test identifies the event causing the transition from that state to this one. This is simpler to do than to explain. In this example there is just one transition into S1 from state S0. If there are multiple transitions coming into the state, you merely "OR" a set of these parenthesized tests together to trigger any of the possible incoming transitions that can get you to this state. The ISY nicely takes care of checking these conditions automatically any time a transition might happen. What is put in an S#Body program? The first thing are statements that set all of the other state's body programs False. This cancels whatever those programs might be doing at the time a transition is made to this state, which effects the actual transition to this state. Remember, we can only be in one state at a time. That also declares the other state programs as being False to the ISY. This is crucial because we are using the True/False status of the S#Body programs to define what state we are in. After setting all other state body programs to False, an S#Body program does whatever you want to be done in the state (if anything). Finally, an S#Body program performs any "tail" transition that happens if the state times out or exits before any other condition triggers the ISY to cancel it. These "tail" transitions are performed by calling the body program for the target state. This is usually the last thing that an S#Body program does. They are not included in the trigger condition list for the target state's S#Cond tests. All other incoming (triggered) transitions are included in those tests but these are programmed transitions, not events. That's why I draw those arrows starting from inside the circle, as they are implemented differently, Here's our S1Body for example: If - No Conditions Then Run Program 'S0Body' (Else Path) Run Program 'S2Body' (Else Path) Run Program 'S3Body' (Else Path) Set Scene 'Scene: KPL-D' Off Wait 5 seconds Run Program 'S0Body' (Then Path) Again, generating this program is more or less a rote process. In fact I typically first just create one template "cond" and one template "body" and use the ISY to copy and edit since they're all so similar. You also want to use a careful (and terse) naming system to keep things clear. I recommend using a common prefix so that you can more easily watch them grouped together in the ISY Program Summary. The only things to think about for the S#Body programs are how long to wait before making an explicit timeout transition out of the state, and what to do around that waiting. For the most part, you have the freedom to do whatever you please without worrying about strange interactions because you know the program isn't going to be interrupted - its execution is 'protected' by its companion S#Cond program. You may have no timeout inside a state. For example, here's the S3Body: If - No Conditions Then Run Program 'S0Body' (Else Path) Run Program 'S1Body' (Else Path) Run Program 'S2Body' (Else Path) Set 'Our Test Light' On Set Scene 'Scene: KPL-D' Off Run Program 'S0Body' (Then Path) This state just notes that it is in state S3 then resets the KPL button off, turns on the target light ("success!") and transitions back to the resting state S0. (The S0Body does nothing except turn off the other three states and exit itself, staying True.) Finally, we need something to initialize the state of this logic to S0 when the ISY boots up. We require exactly one of the S#Body programs to be "True" at any time, which indicates the state we are in. We do this by simply marking the S0Body program as the only program in this group of programs to "run at startup". If you want extra insurance, you can create a separate program that is triggered by all four S#Body programs being False and, when True, runs "S0Body (Then)". This usually is not necessary but it does take care of unusual conditions such as someone manually setting S0Body False from the ISY console. Here's another example: you want to turn your Denon amplifier off at 11:45 and turn it back on at 7AM but only if it was on at 11:45 in the first place. This application has two states: the beginning/idle state that we'll call Denon.S0 and a state Denon.S1 that represents the amp being on at 11:45, waits for 7AM to turn it off, and returns to state Denon.S0. Two states require four programs ... Oops, not quite. We have no easy way in the ISY to wait INSIDE a program for a specific time of day. There are ways you could cook up to shim around this problem such as a little program to trigger True at 7AM and make this test in a repeat loop. But all that nonsense is precisely what we're trying to get away from. The solution, as always here, is simply to add another state. With this change, the state Denon.S1 merely serves to record that the amplifier was on at 11:45 and exits doing nothing except staying True. A new third state, Denon.S2, triggers from Denon.S1 at 7AM, turns off the amplifier and returns to state Denon.S0. Now we have three states, which requires six programs. Denon.S0.Cond: If - No Conditions Then Run Program 'Denon.S0.Body' (Then Path) Denon.S0.Body: (set to run-at-startup) If - No Conditions Then Run Program Denon.S1.Body (Else Path) Run Program Denon.S2.Body (Else Path) Denon S1.Cond: If Program Denon.S0.Body is True And Time is 11:45PM and Status 'AMP' is On Then Run Program 'Denon.S1.Body' Denon.S1.Body: If - No Conditions Then Run Program Denon.S0.Body (Else Path) Set 'AMP' Off Run Program Denon.S2.Body (Else Path) Denon S2.Cond: If Program Denon.S1.Body is True And Time is 7AM Then Run Program 'Denon.S2.Body' Denon.S2.Body: If - No Conditions Then Run Program Denon.S0.Body (Else Path) Run Program Denon.S1.Body (Else Path) Set 'AMP' On Run Program Denon.S0.Body (Then Path) OK, let's take the gloves off. I hear you: "But I can do this little thing in 3 programs (or 2 or 1 or one-half a condition test with my eyes closed, or whatever). Why 6? You've got programs doing basically nothing - we can get rid of them." Yeah, yeah, yeah. If you want to chase the infamous "Busy Beaver" problem, far be it from me to dissuade you. Enjoy yourself. But if you've followed me this far, I'd guess you already know from experience that with the ISY, madness lies down that road. Maybe here you can indeed toss out "Denon.S0.Cond" but maybe later you'll really wish it were there when you make some enhancement, Like the one I make below. So my advice: stick with the structure. The main point here is that, using this technique, everything is simple and more or less as understandable - at least as understandable as anything can be with ISY programs. If my logic diagram does what I want, I can more or less be assured that the programs I generate from it this method will implement it correctly. If I have to change the logic or add more states, I know exactly what to do and where to look to do it. I don't have a Denon amp to test this with but I am still reasonably confident that - absent any typos - the above set of 6 programs will do the job exactly as described without endless fiddling and forum posts. Here's an illustration of how this technique can save some heartburn. Suppose we want to enhance this application a little. If someone turns on the amp between 11:45 and 7AM, then we want to reset the logic and not turn the amp back on at 7AM. This is done easily. Just add a transition arrow from state Denon.S1 to Denon.S0, triggering on the condition "if AMP is switched on". Put that condition into the Denon.S0.Cond program and you're done. Let's apply the technique to an application described in a post on this forum: Between 10PM and sunrise ¦ if we get either of two off signals but with either of two "test" lights still on we turn off a few lights. If neither of those two lights are on then we turn off a lot of other lights. From resting state S0, we have a transition to a state S1 between 10PM and sunrise if either of the two test lights are also still on. We have a second state S2 activated from S0 between 10PM and sunrise if neither of the two test lights is on. There are a couple of other ways to structure this state diagram but, however you graph it, you should be able to produce the 6 programs to implement it easily. Again, if you're tempted to "optimize" them down to 4 or 2 programs, my unequivocal advice is to resist that temptation. Now this technique is hardly perfection. You can still have race conditions in your code, unexpected device interactions, Insteon signal collisions or missed signals. And the ISY has no variables or macro substitution so you can easily get copy/paste errors if you change something in one place and don't mirror it somewhere else where it needs to be. All the usual stuff. But it is much, much easier to debug and solve these problems inside this kind of structure. It's kind of cool to watch the True indicator jump from program to program (state to state) in the Program Summary screen as the programs run. I always know exactly what the programs should be doing and why. A poor man's debugger. If I see two True body programs, I know I probably added a state and forgot to clear it in one of the other states. Here is a program set I have for my kitchen. There are two motion sensors. At night, turn up the lights over the kitchen island to 50% if they're off or less than that when somebody walks in. Regardless whether it is day or night, after 15 minutes of no activity shutoff all the kitchen lights using a scene. There are four states: S0: Resting state Go to S1 when motion is detected and it is night Go to S2 when motion is detected and it is not night S1: Nighttime state Turn up the island light Go to S2 S2: Waiting-for-both-MS off state Go to S3 when status of both MS goes to 'off' (failsafe) after 4 hours, go to S3 (haven't really thought this through) S3: Waiting-for-either-MS-on state Go to S2 when on is received from either MS Otherwise after 15 minutes turn off the lights and go to S0 Here's a state diagram: (motion and night) S1 <--------- S0 <---+ | (motion / | | and not / | | night) / | v / | +-------} S2 <-----+ | | | | | | (both MS off) | | | | | v | | S3 | | / \ | | / \ | +------+ +----------------+ (either (after 15 min) MS on) The programs that implement this application are shown below. There are two oddball programs. The first is the "IsNight" program that has no code for either Then or Else. The program is True or False depending on whether it is "nighttime". I use this because the definition of "nighttime" is used in two conditions and I want to be sure if I change it later I don't need to remember to do it in more than one place. The second is the "Body.S1.Sub" program. I need something to test whether the island lights are currently below 50% and only raise them in that case. Otherwise, if the lights were already brighter, they'd get dimmed -- far more annoying than you might think if you've never actually had it happen to you. The ISY has no "if...then" testing inside program clauses, which would be most welcome. So I break out this little routine that is called from S1 to check the lights and raise them only in they are below 50%. You could do this with an added state or two but it really isn't necessary. Here are the programs Kit Motion.Cond.S0: If - No Conditions Then Run Program 'Kit Motion.Body.S0' (Then Path) Kit Motion.Body.S0: (set to run-at-startup) If - No Conditions Then Run Program 'Kit Motion.Body.S1' (Else Path) Run Program 'Kit Motion.Body.S2' (Else Path) Run Program 'Kit Motion.Body.S4' (Else Path) Kit Motion.Cond.S1: If Program 'Kit Motion.Body.S0' is True And Program 'Kit Motion.IsNight' is True And Program 'Kit Motion.IsMotion' is True Then Run Program 'Kit Motion.Body.S1' (Then Path) Kit Motion.Body.S1: If - No Conditions Then Run Program 'Kit Motion.Body.S0' (Else Path) Run Program 'Kit Motion.Body.S2' (Else Path) Run Program 'Kit Motion.Body.S4' (Else Path) Run Program 'Kit Motion.Body.S1.Sub' (If) Run Program 'Kit Motion.Body.S2' (Then Path) Kit Motion.Body.S1.Sub: If Program 'Kit Motion.Body.S1' is True And Status 'Kitchen Island' < 50% Then Set 'Kitchen Island' 50% Kit Motion.Cond.S2: If ( Program 'Kit Motion.Body.S4' is True And Program 'Kit Motion.IsMotion' is True ) Or ( Program 'Kit Motion.Body.S0' is True And Program 'Kit Motion.IsMotion' is True And Program 'Kit Motion.IsNight' is False ) Then Run Program 'Kit Motion.Body.S2' (Then Path) Kit Motion.Body.S2: If - No Conditions Then Run Program 'Kit Motion.Body.S0' (Else Path) Run Program 'Kit Motion.Body.S1' (Else Path) Run Program 'Kit Motion.Body.S4' (Else Path) Wait 4 hours Run Program 'Kit Motion.Body.S4' (Then Path) Kit Motion.Cond.S4: If Program 'Kit Motion.Body.S2' is True And Program 'Kit Motion.IsMotion' is False Then Run Program 'Kit Motion.Body.S4' (Then Path) Kit Motion.Body.S4: If - No Conditions Then Run Program 'Kit Motion.Body.S0' (Else Path) Run Program 'Kit Motion.Body.S1' (Else Path) Run Program 'Kit Motion.Body.S2' (Else Path) Wait 15 minutes Set Scene 'Scene: Kit On' Off Run Program 'Kit Motion.Body.S0' (Then Path) Kit Motion: IsMotion If Status 'Kitchen: Motion (Oven)-Sensor' is On Or Status 'Kitchen: Motion (Sink)-Sensor' is On Then - No Statements Else - No Statements Kit Motion: IsNight If From Sunset - 30 minutes To Sunrise + 30 minutes (next day) Then - No Statements Else - No Statements Kit Motion: Reset State (just for debugging, not needed) If Program 'Kit Motion.Body.S4' is False And Program 'Kit Motion.Body.S2' is False And Program 'Kit Motion.Body.S1' is False And Program 'Kit Motion.Body.S0' is False Then Run Program 'Kit Motion.Body.S0' (Then Path) ISY programming is not simple. This is illustrated by the Kit.Motion.Body.S1.Sub substate. One issue is whether the Kit.Motion.Body.S1.Sub substate has to be called explicitly. If it is not called explicitly, the ISY may never get a chance to invoke it because S1 runs through without any wait. (It isn't disabled.) It has been suggested that if Kit Motion.Body.S1.Sub is enabled, then it should run either Then or Else (as 'Kitchen Island' is, or is not, less than 50%, respectively) as soon as Kit Motion.Body.S1 becomes True. This happens as soon as its Then is called, which in this case is from Kit Motion.Cond.S1. But Kit Motion.Cond.S2 also becomes True as soon as Kit Motion.Body.S1 is True, and then calls Kit Motion.Body.S2, which will make Kit Motion.Body.S1 False. It is possible that this could create a race condition; this could be tested simply by removing the call. In summary, this method of boils down to the following steps: 1) Draw your diagram. Begin by drawing a circle for the resting state and begin thinking about what events trigger out of that. The rest will flow from that fairly quickly although it may take a few tries to get the logic right. 2) For every state in the diagram you will have two ISY programs: a body.state and a cond.state. Exactly one body.state program can be True at a time; that tells what state you are currently in. 3) The body.state program has no conditions, just a "Then" clause. It first sets all other body.state programs False. It then does whatever you want that state to do, if anything. Sometimes a state merely distinguishes where you are in the flow and may do nothing else. There is always a starting, rest state that usually does nothing and should be set to run-at-startup. If the state requires a wait or a wait is acceptable, then you can transit directly to the next state from the last statement ("Run Program Body.Target (Then Part)" instead of using a condition on the target state. The same is true if there is only one transition out of the state. Otherwise I believe you have to give the ISY a chance to check the other transit-out conditions. You must use conditions to handle every exit path. If there's another / better way to handle this, I'd be most eager to know it. 4) The cond.state lists the condition(s) for all incoming transitions into that state. It ANDs the source state = True with whatever condition takes you from that source state to this target state. This corresponds to a transition arrow on your diagram. If there is more than one incoming transition to a state, they are simply "OR"ed together to create one test. The "Then" clause for a cond.state has a single statement executing that state's body program. You should resist the temptation to put anything else in here. 5) If you find yourself using the same tests repeatedly, consider making a separate True/False program like the .IsNight and .IsMotion programs above. EDIT 8/15/11 to correct a few typos in the first example. Thanks to Illusion for pointing out the errors. EDIT 2/28/15 to clean up text by restoring some quotation marks and apostrophes that were converted into weird character strings. EDIT 8/10/15 to fix state diagram.
  25. I appreciate the patience others have shown in trying to help me (a newcomer) understand the challenges in ISY programming that arise because all conditions appearing in an IF clause are also trigger events that cause the program to run and the IF clause to be re-evaluated. It was not until I read a lengthy post by ergodic (linked from the Wiki) that the light began to come 'on' (no pun intended). The concept of the ISY acting like a state machine has helped me understand like nothing else has. Unfortunately, that post contains revisions and dialog over some fine points that make it more difficult to understand. One person (dbroere) wrote the following: I have tried to sort it out by editing that thread (I hope ergodic does not object), replacing some of the original programs with his subsequent revised programs and by redrawing a state diagram to fit the revised programs. I have taken a few editorial liberties and added some text but otherwise the text is essentially as ergodic wrote it. I may have introduced some errors. I hope others who are more experienced than I (perhaps ergodic himself) will review and correct whatever errors I have made so that we newbies can have an easier document to read. I can provide the document as a MS Word file or as an HTML file if anyone would like it. Otherwise, the edited text follows in the next post. EDIT: Version 3 of ISY firmware allows the use of integer-valued variables in our programs. The variables come in two flavors: state variables and non-state variables. Both state and non-state variables can be used to great advantage, simplifying the structure of the state-machine programs that are described below. Ergodic has described how the state variables can be used. You can see that post here: http://forum.universal-devices.com/topic/6055-state-machine-programming-using-variables-part-1/. Even if you are running version 3, I believe you will find the following post provides useful background that will help understand the new approach. EDIT 8/10/15 to fix broken link.
×
×
  • Create New...