Jump to content

Program logic problem in 5.0.16c?


Recommended Posts

The problem is related to a guard condition I set in a program, whereby the condition references the state of its own program – the idea being to prevent a race condition. I’ve reduced the bug to the following simple program:

Skylight: Temp - [ID 0021][Parent 00E6]

If
        Program 'Skylight: Temp' is False
Then
        $iClimateScratchpad += 1
Else
        $iClimateScratchpad += 10

The variables are arbitrary, just to track program execution (wouldn't program statement tracing be nice?!). Initialize the $iClimateScratchpad to zero, and test the program using RunIf – it works with the variable value changing as expected.  But if you use the RunThen or RunElse, it does not.  It does the opposite of what you expect – so, for example, RunThen executes the ELSE path!

 It gets more interesting.  If I change the condition to true, everything works OK:

If
        Program 'Skylight: Temp' is True
Then
        $iClimateScratchpad += 1
Else
        $iClimateScratchpad += 10

This implies that unconditionally running a program (RunThen / RunElse) is dependent on the program conditions.

Note I do see a discussion of statement execution in the wiki:

Quote

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.

But that's more about pre-emption which should not be happening in my above examples. And in any case the programs are run unconditionally

The operation of my first example feels wrong to me. I'd have thought that RunThen / RunElse should disregard the program conditions?! Otherwise what's the point of having them?!!

- Andrew

Link to comment

So are you considering that Run Then/Else could effect the status of the program and trigger it to evaluate on its own. Not sure if what you are seeing is what I would expect. But doesn’t sound as straight forward as you are expecting.


Sent from my iPhone using Tapatalk

Link to comment

This should not be related to execution order. The initial program is set up to oscillate and fast as ISY will allow it.

 

Which section you run should not affect anything. It is going to oscillate once started or modified from anywhere.

 

 

Sent using Tapatalk

 

 

 

 

Link to comment
3 hours ago, gviliunas said:

@andrewm I Cannot Duplicate what you are seeing- I just tried your sample code and RUN If, Run Then and Run Else all work as expected. I am using FW 5.1.0. What version of FW are you using?

I just duplicated the behavior noted by the OP on 5.0.16C.  "RunIf" works as expected (adds 10).  Runthen adds 10, Runelse adds 1.

Link to comment
45 minutes ago, JBanaszak said:

I just duplicated the behavior noted by the OP on 5.0.16C.  "RunIf" works as expected (adds 10).  Runthen adds 10, Runelse adds 1.

Always good to get confirmation - thanks!

Note that RunIf would add 10 or 1 depending on the program state; it flip-flops on every successive execution, which is correct.

 

1 hour ago, larryllix said:

Nice catch! No. It shouldn't self trigger or oscillate if an integer variable is used.

I can confirm there's no oscillation / race-condition going on. The variable values would indicate that.

 

4 hours ago, gviliunas said:

@andrewm I Cannot Duplicate what you are seeing- I just tried your sample code and RUN If, Run Then and Run Else all work as expected. I am using FW 5.1.0. What version of FW are you using?

I'm using 5.0.1c - it's in the title! I hadn't realized there was a 5.1.0 release... I'll try that, thanks

Link to comment

@andrewm @JBanaszak  I am sorry, and don't know what happened earlier. Maybe I was testing for a True program condition.  I tried this again and WAS able to duplicate this behavior in ISY v5.1.0.

 

It seems that when the If section is testing for the Program condition to be False, Run If and Run Else, if run explicitly, will be reversed. Also, as the OP indicated, testing for a True program condition will allow explicit Run If and Run Else to work properly.

Run If behaves strangely too. 

A.   If the condition is:      Program 'Skylight: Temp' is True

        Then the program runs properly and executes Then or Else based on the last state of the program. The state of the program does NOT change each time the program is run. (Correct)

B.     But, If the condition is:      Program 'Skylight: Temp' is False

         Each time I select Run If, the program's state toggles (true-false-true etc) and the appropriate Then or Else steps are executed. (I don't think that the program state should change here.)

I think that the OP raises a valid point.  I am sorry for the confusion.

 

 

Link to comment
6 hours ago, larryllix said:

This should not be related to execution order. The initial program is set up to oscillate and fast as ISY will allow it.

 

Which section you run should not affect anything. It is going to oscillate once started or modified from anywhere.

 

 

Sent using Tapatalk

 

 

 

 

I agree that given the logic of the program it should oscillate, not because of the variable changing, but because the status of the program should change based on running then or else.

Apparently this is not happening on either program, maybe because UDI built in a stop gap to keep this from occurring?  Either way, the results don't make sense (to me).

Link to comment
8 hours ago, gviliunas said:

@andrewm @JBanaszak  I am sorry, and don't know what happened earlier. Maybe I was testing for a True program condition.  I tried this again and WAS able to duplicate this behavior in ISY v5.1.0.

 

It seems that when the If section is testing for the Program condition to be False, Run If and Run Else, if run explicitly, will be reversed. Also, as the OP indicated, testing for a True program condition will allow explicit Run If and Run Else to work properly.

Run If behaves strangely too. 

A.   If the condition is:      Program 'Skylight: Temp' is True

        Then the program runs properly and executes Then or Else based on the last state of the program. The state of the program does NOT change each time the program is run. (Correct)

B.     But, If the condition is:      Program 'Skylight: Temp' is False

         Each time I select Run If, the program's state toggles (true-false-true etc) and the appropriate Then or Else steps are executed. (I don't think that the program state should change here.)

I think that the OP raises a valid point.  I am sorry for the confusion.

 

 

I don't see the confusion here. That sounds exactly as the program should behave.

The state of a program is what it last run. A program is True when it last ran True and False when it last ran False.
What am I missing?

Link to comment
3 hours ago, gzahar said:

I agree that given the logic of the program it should oscillate, not because of the variable changing, but because the status of the program should change based on running then or else.

Apparently this is not happening on either program, maybe because UDI built in a stop gap to keep this from occurring?  Either way, the results don't make sense (to me).

Integer variable changes do not trigger program to evaluate.

Link to comment
19 hours ago, andrewm said:

wouldn't program statement tracing be nice

If you really want to trace statements, you can do that using a state variable.  Create a test variable, say sTest.  Then after each statement you want to trace, assign a special value to sTest.  Changes to state variables will appear in the Event Viewer so when you see sTest change to a value, you know that the statement before actually ran.  The only thing to watch out for is that only CHANGES are shown in the Event Viewer.  So if you set sTest to 1 and then set sTest to 1 again, the second "change" won't appear because sTest didn't actually change.

19 hours ago, andrewm said:

The operation of my first example feels wrong to me

If you disable the "Skylight:Temp" program it runs as you think it should run.  That tells you all you need to know.  It means that when you tell the THEN to run, the ISY changes the program state to TRUE and then, before it actually starts to run the atomic section of the THEN, the IF is triggered because the program state has changed, at which point the IF causes the ELSE to execute.  Whether it's a bug, or not, is in the eye of the beholder.

Link to comment
1 hour ago, kclenden said:

 

If you disable the "Skylight:Temp" program it runs as you think it should run.  That tells you all you need to know.  It means that when you tell the THEN to run, the ISY changes the program state to TRUE and then, before it actually starts to run the atomic section of the THEN, the IF is triggered because the program state has changed, at which point the IF causes the ELSE to execute.  Whether it's a bug, or not, is in the eye of the beholder.

He is using Integer variables. There is no oscillation or mystery. It operates in a static toggle fashion, each time If is called, exactly the way ISY is designed. There is no bug, just bewilderment of logic IMHO.

Link to comment
Integer variable changes do not trigger program to evaluate.

Agreed. But does the status a program changing cause it to trigger? I’ve always heard (doesn’t mean it’s true) that a program was true if the last time it executed it ran ‘then’ and false if ‘else’. kclenden’s description of being based on evaluation (not execution) makes more sense to me.

 

(The if statement doesn’t contain a variable. It is the status of its own program. Even if the program changed a state variable, that shouldn’t matter. Unless I have missed the boat?).

 

Sent from my iPhone using Tapatalk

Link to comment
2 hours ago, kclenden said:

If you really want to trace statements, you can do that using a state variable.  Create a test variable, say sTest.  Then after each statement you want to trace, assign a special value to sTest.  Changes to state variables will appear in the Event Viewer so when you see sTest change to a value, you know that the statement before actually ran.  The only thing to watch out for is that only CHANGES are shown in the Event Viewer.  So if you set sTest to 1 and then set sTest to 1 again, the second "change" won't appear because sTest didn't actually change.

Good to know. But that requires changing the program, which, being intrusive, is less than ideal. Imo statement tracing should be completely non-intrusive and not require any program changes. It should be something you can just turn or or off. In this case it could easily display the source of any executed line

 

2 hours ago, kclenden said:

If you disable the "Skylight:Temp" program it runs as you think it should run.  That tells you all you need to know.  It means that when you tell the THEN to run, the ISY changes the program state to TRUE and then, before it actually starts to run the atomic section of the THEN, the IF is triggered because the program state has changed, at which point the IF causes the ELSE to execute.  Whether it's a bug, or not, is in the eye of the beholder.

Interesting. I was going to try disabling the program when I got home tonight, so you saved me some time.

So the program execution is pre-empted before it runs but after the state changes. It's not the way I would think it should work, but I tend to agree that it's in the eye of the beholder. Useful to know.

Link to comment

So the program execution is pre-empted before it runs but after the state changes. It's not the way I would think it should work, but I tend to agree that it's in the eye of the beholder. Useful to know.


I think many of us learned something new and interesting today....thanks for your original post!


Sent from my iPhone using Tapatalk
Link to comment
9 hours ago, gzahar said:

Agreed. But does the status a program changing cause it to trigger? I’ve always heard (doesn’t mean it’s true) that a program was true if the last time it executed it ran ‘then’ and false if ‘else’. kclenden’s description of being based on evaluation (not execution) makes more sense to me.

 

(The if statement doesn’t contain a variable. It is the status of its own program. Even if the program changed a state variable, that shouldn’t matter. Unless I have missed the boat?).

 

Sent from my iPhone using Tapatalk

Agreed. I think I have misjudged this whole concept here, getting sidetracked, thinking people were claiming the variables were retriggering the program. :(

Usually ISY programs cannot re-evalulate without hitting a Wait or Repeat construct and there is none in the program so it should always finish it's Then/Else code before oscillating again.

 

Link to comment
10 minutes ago, larryllix said:

Agreed. I think I have misjudged this whole concept here, getting sidetracked, thinking people were claiming the variables were retriggering the program. :(

Usually ISY programs cannot re-evalulate without hitting a Wait or Repeat construct and there is none in the program so it should always finish it's Then/Else code before oscillating again.

Regardless... Run Then should run THEN. and Run Else should run ELSE.   Read this from the first post again:

Quote

But if you use the RunThen or RunElse, it does not.  It does the opposite of what you expect – so, for example, RunThen executes the ELSE path!

That is the key to this thread......

Link to comment
49 minutes ago, MrBill said:

Regardless... Run Then should run THEN. and Run Else should run ELSE.   Read this from the first post again:

That is the key to this thread......

It seems ISY evaluation is not performed just during  a Wait or Repeat construct. This seems to prove it is also evaluating either before a variable arithmetic construct, or before the first line of every Then/Else.

I tried this, and get the same results. Also, this scenario should oscillate once the If is run and it doesn't.
I didn't believe anything is built into ISY to predict outcomes. This appears to be re-evaluation as above. How can we could prove either?
 

Test Program State - [ID 01D1][Parent 0001]

If
        Program 'Test Program State' is False
Then
        Wait  2 seconds
        $Test_Var += 100 
Else
        Wait  2 seconds
        $Test_Var += 1

My synopsis of this:
The If section evaluates the last left status of the program, and then calls the appropriate Then/Else
The program status is then re-evaluated before the first line of code even executes
The If section now cancels the current Then/Else running before any code can run
The If section then runs the appropriate and opposite  Then/Else section, based on the new logical evaluation

The If section should new do the evaluation again and oscillate but doesn't. That does appear to be UDI attempting to predict oscillation and preventing it.

Possibly a test using two cross-coupled programs may reveal some clues of an attempt by ISY to thwart self program state watching??

Link to comment

I am using v5.1.0

@andrewm <---credit due OP  @Michel Kohanim@Chris JahnWe definitely have some bugs with the evaluation of program status. To eliminate self program evaluation oscillation prevention suspicions I involved three  program statuses, based on each other reciprocally, like this.

Test Program State - [ID 01D1][Parent 0001]
If
        Program 'Test Program State3' is False
Then
        $Test_Var += 100
        Wait  2 seconds
Else
        $Test_Var += 1
        Wait  2 seconds


Test Program State2 - [ID 01D2][Parent 0001]
If
        Program 'Test Program State' is False
Then
        $Test_Var2 += 100
        Wait  2 seconds
Else
        $Test_Var2 += 1
        Wait  2 seconds


Test Program State3 - [ID 01D3][Parent 0001]
If
        Program 'Test Program State2' is False
Then
        $Test_Var3 += 100
        Wait  2 seconds
Else
        $Test_Var3 += 1
        Wait  2 seconds
 

 

After clearing all three variables to 0, and observing the programs are False, True, and False, I ran Else on the first program. The variable now showed that the programs ran False, True, and False.

Since there was no program state change of any program (by logical thinking) none of the programs should have ran, and the resultant in the program avatars showed the same status as I started out with. The variable show otherwise.

IOW:
by logical analyses :
The status of Program Test State should not have changes, the state of Program Test State2 should not have changed, and the state of Program Test State3, should not have changed. The first variable should have an update due to forced running Else, but no other program should have detected a change in the previous program's status because none occurred.

by observation of events
The status of Program Test State (else ran) did not change, the state of Program Test State2 (True ran) did not change, and the state of Program Test State3, (Else Ran) did not have change.

These program states are not evaluating according to any rules that I can tell. The fact that they do not oscillate tells me ISY has a bug, and I doubt that any program could determine a loop using three programs would oscillate, causing them only to run one time around the loop..

Link to comment
45 minutes ago, larryllix said:

These program states are not evaluating according to any rules that I can tell. The fact that they do not oscillate tells me ISY has a bug, and I doubt that any program could determine a loop using three programs would oscillate, causing them only to run one time around the loop..

Perhaps you've found an interesting quirk in the way the ISY program runtime evaluates the states vs. what would logically make sense, but I wouldn't think that justifies calling it a "bug" unless it is preventing the OP from actually doing something practical without a reasonable workaround.

Link to comment
Perhaps you've found an interesting quirk in the way the ISY program runtime evaluates the states vs. what would logically make sense, but I wouldn't think that justifies calling it a "bug" unless it is preventing the OP from actually doing something practical without a reasonable workaround.
I doubt users or UDI wants evaluation of triggers inconsistent between variables programs or other trigger items or inconsistent to the number of times the event occured.

It's a bug by making it contrary to the way all other trigger logic rules work in ISY.

This happened to state variables from REST injections in the past, but UDI wanted them consistent to their existing philosophy.

Elements should not cause program triggers if the do not change value. it could bog the ISY event engine down too much.

Sent using Tapatalk

Link to comment

I think that it's pretty simply a bug.   I hadn't actually created the example and tested until now.  We don't need to over complicate by talking about oscillating values etc.

Plain and distinct:  RUN THEN should run the THEN block.  RUN ELSE should run the ELSE block.  There is nothing about that says an evaluation should be occurring...The IF block should not matter, it should be ignored. The current true/false state of the program should not matter.  If we RUN THEN then THEN should run, If we RUN ELSE then ELSE should run, they should NEVER be interchanged the way they are. 

@Michel Kohanim and @Chris Jahn will need to review, but it's a bug.

Link to comment

Archived

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


×
×
  • Create New...