Jump to content

detailed write-up of a programming example


johnradams

Recommended Posts

I am using a KeyPadLink button to see if any of my basement lights are on (e.g., someone left some of them on ). If any of the lights are on, the KP button is lit; I can then press the button to turn all of the basement lights off. I can also use the same button to turn all of the lights on.

 

While this is a simple scheme, the programming needs to handle some race conditions.

 

I initially struggled with ISY programming, as I was really thrown by a few quirks of the model (not to mention spotty and sometimes contradicting doc!). When I finally got it sorted out, I documented what I had learned, in hopes that others would be spared some pain.

 

Here's the link; enjoy: http://www.adamsj.com/isy/

Link to comment

Nice work.

 

I agree that ISY has a lot of things you don't quite expect and you touched on a number of them.

 

One thing I think they should do is drop the word "on" and replace it with 100%, since that is what they mean.

 

A silly thing that bugs me is the lack of the word "delete". The rest of the world uses "delete" to delete something, not "remove". I always have to stare at if for a while before I remember to look for remove, not delete.

 

The ISY totally needs a logically put together programmers manual. Even for people like me who have spent a fair amount of time writing programs and whatnot, a few weeks after you figure something out, you forget when you don't use it. I have taken to writing a list of my anecdotes for future reference, but still. And trying to piece things together from the threads is, well, at best very time consuming.

 

I like what you have started. Thanks.

Link to comment

Hello apostolakisl,

 

One comment on the Delete vs. Remove:

As you may have already gathered, user input is very important for us and is usually implemented especially if it's something trivial and non-intrusive (just look at the enhancement section of each release: all those with numbers are user requested features).

 

All you have to do is submit a request.

 

With kind regards,

Michel

Link to comment
Even for people like me who have spent a fair amount of time writing programs and whatnot, a few weeks after you figure something out, you forget when you don't use it.

 

Perhaps it would be better stated "ESPECIALLY for people like me..." I often wonder if it is easier for those of us without expectations or experience regarding how it should work and the ability to recognize that it is somehow different than other programming languages that I may know.

Link to comment
Perhaps it would be better stated "ESPECIALLY for people like me..." I often wonder if it is easier for those of us without expectations or experience regarding how it should work and the ability to recognize that it is somehow different than other programming languages that I may know.

 

oberkc, Your point is consistent with my experience! I freely admit that I have pre-conceived notions/expectations about the programming model. And that got me into trouble -- the interesting behavior of the 'Wait' statement was probably the biggest mystery for me. The way that 'Wait' causes re-evaluation has now been added (at my request) to the wiki, where it was conspicuously absent.

 

BTW, if it isn't obvious to you, my tutorial goes well-out-of-the-way to explain a few "real-time" and "multi-tasking" issues. I did this because I presume that most people working with the ISY are not familiar with these concepts. Most people cannot initially grasp the idea that all of their devices might not be in some nice, clean, known state when a program runs. It takes them a little effort, and some examples, for them to understand that their program needs to gracefully handle things in an intermediate state, and/or to handle a "race condition" -- especially between their own programs.

 

For example, people typically assume single-threaded execution, as that is essentially what they see on the screen when editing the program details. They cannot help but unconsciously think "Hey, since I see just this one program on my screen, then I guess this is the only thing happening when my program is running." It's human nature -- unless something else has been explained to you.

 

If any of you want to email your own little tidbits of wisdom, I will (a) be pleased to learn them, and (B) will add them to my slowly-growing toolbag of tips 'n tricks. jra [at] adamsj.com

Link to comment

John, nice job. Thank you. I've been playing with the ISY-99i for some time now with X-10 devices and have just started using Insteon devices. Through these forums and trial-and-error, I've figured out many of the your tips and tricks but not all.

 

Can you explain why "don't have actions that operate on a scene with controllers"? Currently I have only 2 SwitchLinc devices which are in a single scene - a "virtual circuit". Both are controllers. I do have a program that performs an action on that scene. I do this to have the light turned on when an X-10 motion sensor detects motion or an X-10 RF switch is pressed. So far, this has been working fine.

 

BTW - I'm impressed with the way Insteon works and its reliability. My plan is to replace all my X-10 devices with Insteon over the next few months.

 

Don

Link to comment
The way that 'Wait' causes re-evaluation

 

I did not believe that the wait statement actually caused a re-evaluation. Rather, I understood that a re-evaluation COULD occur during a wait state, at which point, a program would be either halted or restarted.

 

This is exactly the sort of thing I was talking about when referring to program triggers and programs restarting prior to conclusion. For example, let's say a switchlinc is on and a program is running which includes the status of the switch. If the switchlinc is told to turn on again (either locally or otherwise), the program resets, even though nothing seemed to happen.

 

Essentially, any traffic on the system referring to an insteon device will restart a program containing a "status" line for that device, regardless of whether that traffic caused a change in the status or not.

 

I was playing with writing programs where the "if" and "then" section were written into two separate programs. The "if" program runs the "then" program with the "then" program's first line to disable the "if" program and the last line turning it back on. It seemed to work for me, but another poster was not having as much luck.

Link to comment
Essentially, any traffic on the system referring to an insteon device will restart a program containing a "status" line for that device, regardless of whether that traffic caused a change in the status or not.

 

This is how I understood it. This is different, however, than saying that the "wait" statement itself causes a re-evaluation.

 

While the syntax and programming structure may be unlike what one is used to, I remain unconvinced that this makes it wrong. In the case re-evaluation during program execution, I might even argue that this can offer advantages in certain situations (think motion sensors). Furthermore, there are ways to avoid the stopping-of-execution-in-the-middle-of wait-statements.

 

Learning the ISY is like learning any other computer skill....computers, cell phones, calculators, Sony Dash, It takes a little time to be able to fully explit the available capability, but becomes pretty intuitive once learned. At least, that is how I find it. Maybe I am just weird.

Link to comment

Overall very nice write up!

 

couple of comments ...

 

4. The 'Wait' and 'Repeat' Statements Cause the If to be Re-Evaluated

This is not intuitive, but is important and useful! If your program is assessing a possibly dynamic situation, ...

 

This actually describes the side effect of what is going on.

 

When an event occurs that would normally cause the program to run (either the 'Then' or the 'Else') then the program stops if it is currently running, and picks up again at the 'Then' or 'Else'.

 

The reason it appears as if 'Wait' and 'Repeat' evaluate the 'If' is these are the only actions that return control to the "program cycle" which actually tests conditions when new events come in. In other words, the set of actions between a 'Wait' or 'Repeat' is essentially atomic (not the nuclear kind :)).

 

 

9. Every Part of the If Clause is Tested

For those of you familiar with modern programming languages, you probably expect for If clauses to be evaluated left-to-right (well, top-to-bottom in the ISY GUI), and of course you expect parentheses to be honored.

 

What might surprise you is to learn that the entire If clause is always processed -- even when further evaluation is not needed. This should not introduce any side-effects, but does mean that you don't need to bother and try to be "efficient" when constructing a bulky expression. ...

 

This should not cause performance problems because the system only actually re-evaluates conditions that are affected by whatever event has occurred, and therefore uses the previous true/false value for unaffected conditions. This is also one of the reasons we don't short circuit the expression.

Link to comment

The reason it appears as if 'Wait' and 'Repeat' evaluate the 'If' is these are the only actions that return control to the "program cycle" which actually tests conditions when new events come in. In other words, the set of actions between a 'Wait' or 'Repeat' is essentially atomic (not the nuclear kind :)).

 

Chris,

 

Another way of stating this (pls correct if/where I am wrong): when a 'Wait' statement is encountered, the executive suspends execution of the program, and schedules the program to run again after the specified interval. The twist, however, is that the program resumes execution "at the top" (eg, the If is re-evaluated). If the expression evaluates to True, then execution proceeds with the statement immediately following the 'Wait' which was just recently in effect.

 

Question #1: is the previous paragraph correct? Or, instead, when execution resumes after the Wait, does execution begin at the top of the 'Then' instead of just after the previous 'Wait'?

 

Question #2: suppose my program performs a Wait. After the interval completes, will the 'Else' portion of my program execute in the event the 'If" expression evaluates to False?

 

Question #3: is my assertion regarding "the If is re-evaluated" actually an simplified (but often close-to-correct) overstatement? And the proper thing to state is that any change in status to an Insteon device which is referenced in the If will cause the If to be re-evaluated. BTW, which I think is incredibly non-obvious. If I want that behavior, it would seem more natural for the logic to look something like this:

   while ( some_condition_is_true )
   {
         do_some_stuff();
         sleep(x seconds);
   }

 

Maybe some changes to wording would be useful. If the syntax was 'SleepAndReEvaluateIfUponReEntry' I would find that much clearer :-). This would also allow for other forms of behavior, such as 'SleepAndContinueExecutingRightHereNoMatterWhat'. I'm not suggesting this exact syntax, though :-).

 

Thanks for clearing this stuff up.

Link to comment

I guess we will all see what Chris confirms, but I can tell you that the wait statements in my programs resume at the next step in the program following the wait, not the beginning. If this were not true, programs such as:

 

set light on

wait 2 minutes

set light off

 

would never work. My programs are not re-evaluated, either. If this were done, several of my programs would never finish.

 

I understood Chris to say that a program will only stop execution if something happens that affect the "if" conditions. This is consistent with my experience.

Link to comment
Hello apostolakisl,

 

One comment on the Delete vs. Remove:

As you may have already gathered, user input is very important for us and is usually implemented especially if it's something trivial and non-intrusive (just look at the enhancement section of each release: all those with numbers are user requested features).

 

All you have to do is submit a request.

 

With kind regards,

Michel

 

Michel,

 

If you are looking for other simple to implement ideas, here is one. Instead of the 1011 in the green box next to devices that need to be written to, why not put the word "pending". While they are writing, the most obvious word "writing" shows up so why not be just as simple when the write is pending? I have seen a number of posts on here where people were confused as to what the 1011 meant.

 

One other thing. I don't really understand what the bar that gives a percent of job completion means. It keeps either slowly or rapidly jumping accross the screen only to start at 0 again or maybe not. Perhaps those percentages really mean something, but I don't know what. It might be just as well to put one of those spining clocks or something just to indicate that the system is writing rather than what seems to be meaningless percentages.

 

Lou

Link to comment

Hello apostolakisl,

 

I agree with the icon and renaming Remove to Delete. May I trouble you to post these requirements in our Product Requests forum ( http://forum.universal-devices.com/viewforum.php?f=7 )?

 

As far as the percentage, they do mean A LOT. For network related activities (such as backup, restore, upgrade) they are 100% accurate since the worst case scenario is an error which stops the process.

 

For INSTEON commands, there are 3 parameters:

1. Number of commands pending to be written to the device

2. Delay between each command (usually 500 ms)

3. The time it takes for each command to complete

 

So, in ISY, we send the Admin Console a pretty accurate rendition of the above parameters. In an ideal case, the progress bar will be quite accurate. But, in the case of a non-responding device, the progress bar will be out of synch since ISY will retry each command 4 times before giving up. So, we could have assumed the worst case scenario, or the best case scenario, but instead we chose the middle case scenario. As such, in case there are no errors, the progress bar shall be pretty accurate. In case of error, the client queries ISY for the number of commands and makes necessary adjustments and heuristics.

 

 

With kind regards,

Michel

Link to comment

Michel,

 

Unless my unit is doing something different than it is supposed to, my progress bars don't seem as straight forward as you describe.

 

For example, if I add a switch to a scene, it does not start at zero and go to 100% in a single orderly fashion. It starts at 0 and goes to 100 many times depending on the size of the scene. Some of those times it flies across so fast that I can't hardly see it and other times it is quite slow. It might do a 0 to 100% 6 or 7 times when building a scene. And it isn't like it does this once per device in the scene. I really never know for any maneuver how many times it needs to go across. Also, sometimes, I have the "writing" labels on devices and the progress bar isn't there at all. It seems to be writing because it will progress from "1011" to "writing" on device after device, but no progress bar shows up at all. In this case it I know it is done when all of the green labels are gone.

 

My main gripe really is that never can you watch the bar and have a real idea about how close it is to being done. I just think that a percentage bar should be there so that you can estimate when the job will be done, and this progress bar doesn't do that.

 

It seems that if communication failures occur then it shouldn't keep going across, it should stop. After all, it isn't actually making progress.

 

And if it has 10 jobs to do to build a scene, it should start at 0 and go 100 a single time as it does those 10 jobs. Perhaps a little flag comes up if it is having comm difficulty to let you know about that and pausing during that time.

Link to comment
It seems that if communication failures occur then it shouldn't keep going across, it should stop. After all, it isn't actually making progress.

 

I tend to agree that an accurate progress bar would be nice. However, I have also used the event viewer to get a sense of communication issues. Set it to level 3 and one can see if there are hangups. While not the most elegant, it is a functional solution for those of us who like to keep track of such things.

Link to comment

Another way of stating this (pls correct if/where I am wrong): when a 'Wait' statement is encountered, the executive suspends execution of the program, and schedules the program to run again after the specified interval. The twist, however, is that the program resumes execution "at the top" (eg, the If is re-evaluated). If the expression evaluates to True, then execution proceeds with the statement immediately following the 'Wait' which was just recently in effect.

 

Question #1: is the previous paragraph correct? Or, instead, when execution resumes after the Wait, does execution begin at the top of the 'Then' instead of just after the previous 'Wait'?

 

Question #2: suppose my program performs a Wait. After the interval completes, will the 'Else' portion of my program execute in the event the 'If" expression evaluates to False?

 

 

Question #3: is my assertion regarding "the If is re-evaluated" actually an simplified (but often close-to-correct) overstatement? ...

 

 

I think you are reading too much into this, the simplest way to think of the program cycle is this:

 

1. When an event is received that causes a program to run, it runs either the Then or the Else

2. A running program can only be interrupted during a Wait or Repeat.

3. If a running program is interrupted (See 2.) by an event that would normally cause the program to run, then the program is stopped, and run again, either the Then or Else path.

 

 

In other words, at wait/repeat statements, programs can be interrupted and restarted by incoming events.

Link to comment

Chris,

 

Thank you very much for taking the time for your last post. That is what I got from the Wiki but so many different opinions were being posted that did not agree I was beginning to think I had interpreted the Wiki wrong. Really appreciate an explanation from the experts.

 

Lee

Link to comment

Thanks for the great information John!

 

I printed your document and then poured through my programs to determine if any were in violation of your recommendations. I found several cases of programs attempting to control scenes containing controllers. These had all been working in the past but I followed your recommendation and created additional scenes with only responders and modified the programs to only trigger these.

 

I'm trying to understand why I needed to do this. Is the problem that programs triggering scenes with controllers will cause the controllers to send additional unneeded traffic that would potentially make the system less reliable or is there some other reason?

 

Thanks!

 

Greg

Link to comment

I don't understand where this came from John.

 

There should not be any issues controlling scenes from the ISY that have controllers in them. The controllers should act like responders when the PLM is the controller, the same as setting up any scene with multiple controllers (3-way switches, for example).

 

Rand

 

Thanks for the great information John!

 

I printed your document and then poured through my programs to determine if any were in violation of your recommendations. I found several cases of programs attempting to control scenes containing controllers. These had all been working in the past but I followed your recommendation and created additional scenes with only responders and modified the programs to only trigger these.

 

I'm trying to understand why I needed to do this. Is the problem that programs triggering scenes with controllers will cause the controllers to send additional unneeded traffic that would potentially make the system less reliable or is there some other reason?

 

Thanks!

 

Greg

Link to comment
I don't understand where this came from John.

 

There should not be any issues controlling scenes from the ISY that have controllers in them. The controllers should act like responders when the PLM is the controller, the same as setting up any scene with multiple controllers (3-way switches, for example).

 

Rand

 

Rand, I got the idea from you and/or Darrell :-)

 

Yes, your statement above is correct, and consistent with point #7 on the web page:

http://adamsj.com/isy/programming.htm

 

However, the "full story" is slightly more complicated, and bears explaining. Which is exactly why I created the webpage -- to avoid dozens of minor modifications such as one finds in the forum. It is always nice to have a definitive, and clear, explanation.

 

The warning that I speak of in point #7 refers to the notion of listing devices, instead of referring to a group of devices which are described by a multi-way circuit (aka scene).

 

In other words, if you want to turn off all the lights in a virtual circuit with 3 lights, you want to have 3 separate Off commands in the list of Actions. You should not take the short-cut of simply setting the scene (that manages the multi-way circuit) to Off. If you do send an Off command to a scene, make sure that the devices listed in that scene are only acting as Responders for that scene.

 

I have tweaked the wording in point #7 to clarify this.

 

If the revised language in point #7 is not correct, or is unclear in any way, somebody please speak up!

Link to comment
There should not be any issues controlling scenes from the ISY that have controllers in them.

 

In other words, if you want to turn off all the lights in a virtual circuit with 3 lights, you want to have 3 separate Off commands in the list of Actions. You should not take the short-cut of simply setting the scene (that manages the multi-way circuit) to Off. If you do send an Off command to a scene, make sure that the devices listed in that scene are only acting as Responders for that scene.

 

I use programs to turn off scenes (including those with controller devices) all the time, without issues that I know about. In fact, I thought the response to scene commands was more robust than the response to individual devices. Like Sub-routine and gviliunas, I am having trouble understanding why you think this is a bad idea.

 

If the revised language in point #7 is not correct, or is unclear in any way, somebody please speak up!

 

Consider me to have spoken up. I believe this is not correct.

Link to comment
Consider me to have spoken up. I believe this is not correct.

 

Thanks for your input. I'm glad this discussion is getting some visibility. As I noted, I was advised by UDI to list the devices, and avoid putting the multi-way scene itself in the Action list. And my experience was that my program worked much better after I listed the devices individually.

 

A forum is a great place to raise questions and issues, but not such a great way to disseminate "known-to-be-good" examples, documentation, etc.

 

I look forward to learning the clear and complete "verdict" on this topic so that it can be documented once and for all (and not documented thousands of times in the forums, each time with a slightly different error, omission, or quirk).

Link to comment

Archived

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


×
×
  • Create New...