Jump to content

Triggers and conditions and IFs, oh my!


dnl

Recommended Posts

Upon reflection, it seems to me that as long as the programstatements in the loop do not involve conditions requiring interaction from devices, but rather work with variables and programs which also are mainly internal to the ISY, the latencies and load from even a fair number of such programs should be low. After all the ISY is a 200mHz processor. In the above example the only device interaction will be when the loop count completes and a valve and perhaps a kpl light gets turned on or off, every 10-30 minutes. Am I understanding things right?

 

thus if one codes to use minimal device status or queries, but use variables and program status for logic, and mainly use the powerline to generate actual control commands there should not be much traffic on the powerline.

 

TIA

Link to comment
  • 2 months later...

Thanks for the tough editing work. Through this post I finally understand State Machine programming. Now I will read the post that modifies it using variables with an actual understanding of the basic concept.

 

One edit for the original post:

 

ISY Programming Methodology

(state-machine approach)

edited from posts by ergodic in June 2010

 

I’ll start with a simple example:

  • Press a keypad button ("KPL A") three times in succession to turn on a light.
    If more than 5 seconds elapses between presses,
    then the sequence resets and you have to start over.

 

I think this should be KPL-D not KPL-A based on the text in the rest of the post.

Link to comment
I think this should be KPL-D not KPL-A based on the text in the rest of the post.

 

Thanks Illusion. Right you are. Actually, there was more than one instance of "KPL A" in the first example and I updated the post to correct them.

Link to comment

It is also possible to implement a variable wait using a pair of programs - one to start the process and one to 'step down' to zero. And a simple (non-state) variable to implement the wait interval.

 

For instance, this turns on a light after $V seconds (30 seconds in this case):

 

//___________________
//Program TestVarWait

If
Then
       $V  = 30
       Run Program 'Wait.V' (If)

//______________
//Program Wait.V

If
       $V > 0
Then
       Wait  2 seconds
       $V -= 2
       Run Program 'Wait.V' (If)
Else
       Set Scene 'Scene: U/S Office Desk' On

 

The main advantage of this design is you can treat "Wait.V" as a subroutine of sorts, callable with different wait times from different programs. Note that this does lose the initial value set into $V.

 

The main issue with this is that the "Run Program Wait.V" (at the end of TestVarWait) executes asynchronously and so execution continues immediately. That is not an issue here, but if you are waiting for the event to occur before you proceed on, you need to add logic to initialize and in effect wait for "Wait.V" to become false. This seems to require creation of yet a third program. I've tried a bit to concoct something simpler using state variables to handle this, but without any real success - maybe someone else has an idea.

 

Even with a 1 second increment, the variability I've seen seems quite small, though I wouldn't use that for something involving hours. And since even trigger / state variables aren't used for this and the actual executions are trivial, I'd be astonished if this adds any real loading to the ISY.

Link to comment
The main issue with this is that the "Run Program Wait.V" (at the end of TestVarWait) executes asynchronously and so execution continues immediately. That is not an issue here, but if you are waiting for the event to occur before you proceed on, you need to add logic to initialize and in effect wait for "Wait.V" to become false. This seems to require creation of yet a third program. I've tried a bit to concoct something simpler using state variables to handle this, but without any real success - maybe someone else has an idea.

Hi ergodic,

 

I think your example code could use the ELSE clause to achieve some synchronization. Execution of the following code would be initiated by setting $F = 0. What do you think?

//___________________
//Program TestVarWait

If  $F = 0
Then
       $V  = 30
       Run Program 'Wait.V' (If)
Else
       Run Program 'DoItNow' (If)
//______________
//Program Wait.V

If
       $V > 0
Then
       Wait  2 seconds
       $V -= 2
       Run Program 'Wait.V' (If)
Else
       $F = 1

Link to comment
Pardon my ignorance, but what is the advantage of this over simply:

 

Wait 60 seconds
Run Program 'DoItNow' (If)

?

The advantage is that the delay time is programmable. Some day I am sure UDI will support the use of variables in a wait statement but until then something else is needed.

Link to comment

I guess I don't see how coding the setting of a variable to a specific value and then calling a program to perform the wait is any more "programmable" or flexible than simply coding the Wait statement with the desired value. In fact, it seems to add complexity and an additional program that is not otherwise needed. I guess if you wanted to set the variable with a REST call and then execute the program, but I don't think that is possible as of now, right?

Link to comment

I was confuse on the wait variables at first but mike explained it to me like this. When you invoke a wait statement the wait xx time later it will rerun to the if checks and if one of them is false the program stops. That is why you do your wait in a separate program of your Ifs to invoke the wait and then at the end of the wait run the end of the program or goto a new program to be ran. I hope this helped you also.

 

 

 

---

 

- Sent from my iPhone using Tapatalk

Link to comment
I guess I don't see how coding the setting of a variable to a specific value and then calling a program to perform the wait is any more "programmable" or flexible than simply coding the Wait statement with the desired value. In fact, it seems to add complexity and an additional program that is not otherwise needed. I guess if you wanted to set the variable with a REST call and then execute the program, but I don't think that is possible as of now, right?

Agreed the complexity is greater but I can see some ways where this technique might be used to advantage.

  • 1) The delay time can be the result of a calculation. The ability to do calculations right now is limited but not non-existant.
    2) The delay code can be packaged as a subroutine and called from multiple places, reducing program maintenance. Of course, it may be necessary to take care not to call the routine again before it completes.
    3) I don't know whether a variable can be set directly from a REST call but I believe it is possible to do it indirectly by controlling which programs execute and having those programs set a variable as desired.

 

There may not be many instances where we need or want to do any of these things but if we do, some approach like what ergodic suggests is needed.

Link to comment

This post allowed me to understand how this works, thanks. If I can make on suggestion, it seems that the way we have to use this programming, some types of programs, the ones with the IFs or WHENEVERs would be triggers and other ones would be the real PROGRAMS or procedures that are called from triggers and some could be considered VARIABLES, cause they are currently used as boolean variables after verifying/meeting a condition in some ways.

 

My 2 cents.

Link to comment

The main advantage of this design is you can treat "Wait.V" as a subroutine of sorts, callable with different wait times from different programs.

 

Just be cautious in your use of it that way since it would be shared between any programs that happen to trigger during the same time. Such as the one that runs a sprinkler valve to top off your pool for 5 minutes and the one that closes your garage after an hour.

Link to comment
  • 11 months later...

I have been trying to make sense of the "hit the button 3 times within 5 seconds example." I am totally confused. Is there any way you can tell me what the other SCond and SBody programs would be so i can stare at it and try and make sense of it. WIth just S1 and part of S3 I am very confused.

Link to comment
  • 4 months later...

the 5 second wait is useful in that when you press the button, it transitions from off to on between each of the 4 states (0,1,2,3). the kepad will light from "off" to "on" on the first press. The program then clears the light back to "off" giving you feedback that the 5 second wait is counting down. press the button again, the light goes on, program turns the light off, letting you know to press again. third press, light goes on, at this point you're in the s3_body code, so you can leave the light on letting you know that it took. note in s3_body I set a state variable, I use this elsewhere to trigger code to "activate" whatever I intended the 3 presses to do.

 

 

the programs are as follows:

(note, i renamed them to shorten them up but you can easily follow the flow)

 

=========================================

s0_body

=========================================

If

- No Conditions - (To add one, press 'Schedule' or 'Condition')

 

Then

Run Program 'S1_body' (Else Path)

Run Program 'S2_body' (Else Path)

Run Program 'S3_body' (Else Path)

 

Else

- No Actions - (To add one, press 'Action')

 

 

=========================================

s1_cond

=========================================

If

Program 'S0_body' is True

And Control 'Key_g' is switched On

 

Then

Run Program 'S1_body' (Then Path)

 

Else

- No Actions - (To add one, press 'Action')

 

 

=========================================

s1_body

=========================================

If

- No Conditions - (To add one, press 'Schedule' or 'Condition')

 

Then

Run Program 'S0_body' (Else Path)

Run Program 'S2_body' (Else Path)

Run Program 'S3_body' (Else Path)

Set Scene 'Key_g' Off

$State_1 = 0

Wait 5 seconds

Run Program 'S0_body' (Then Path)

 

Else

- No Actions - (To add one, press 'Action')

 

 

=========================================

s2_cond

=========================================

If

Program 'S1_body' is True

And Control 'Key_g' is switched On

 

Then

Run Program 'S2_body' (Then Path)

 

Else

- No Actions - (To add one, press 'Action')

 

 

=========================================

s2_body

=========================================

If

- No Conditions - (To add one, press 'Schedule' or 'Condition')

 

Then

Run Program 'S0_body' (Else Path)

Run Program 'S1_body' (Else Path)

Run Program 'S3_body' (Else Path)

Set Scene 'Key_g' Off

Wait 5 seconds

Run Program 'S0_body' (Then Path)

 

Else

- No Actions - (To add one, press 'Action')

 

 

=========================================

s3_cond

=========================================

If

Program 'S2_body' is True

And Control 'Key_g' is switched On

 

Then

Run Program 'S3_body' (Then Path)

 

Else

- No Actions - (To add one, press 'Action')

 

 

=========================================

s3_body

=========================================

If

- No Conditions - (To add one, press 'Schedule' or 'Condition')

 

Then

Run Program 'S0_body' (Else Path)

Run Program 'S1_body' (Else Path)

Run Program 'S2_body' (Else Path)

Set Scene 'Key_g' On

$State_1 = 1

Run Program 'S0_body' (Then Path)

 

Else

- No Actions - (To add one, press 'Action')

Link to comment
  • 3 months later...

I was wondering if someone could help me figure out what I'm doing wrong in my programs. The programs should trigger once the last person has left the house, then the goal is to send some notifications at some intervals and eventually turn off lights and devices if no one returns.

 

My variable $X3 indicates the number of people in the house (works reliably) and $AwayNotified keeps track of whether a notification was sent (to avoid repeat notifications).

 

When $X3 turns 0 (last person has left the house), I want to send a notification saying that lights will turn off in 15 minutes. If after 15 minutes X3 is still 0, I want to send another message saying lights will turn off in 5 minutes. If after 5 minutes X3 is still 0, the ISY will turn down thermostats, turn off lights and music systems.

 

My programs are the following (all the Else conditions are empty):

 

Program Away.S0.Cond (Run at Startup)

If

- No Conditions -

Then

Run Program 'Away.S0.Body' (Then Path)

 

Program Away.S0.Body

If

- No Conditions -

Then

Run Program 'Away.S1.Body' (Else Path)

Run Program 'Away.S2.Body' (Else Path)

Run Program 'Away.S3.Body' (Else Path)

 

Program Away.S1.Cond

If

Program 'Away.S0.Body' is True

And $X3 is 0

And $AwayNotified is 0

Then

Run Program 'Away.S1.Body' (Then Path)

 

Program Away.S1.Body

If

- No Conditions -

Then

Run Program 'Away.S0.Body' (Else Path)

Run Program 'Away.S2.Body' (Else Path)

Run Program 'Away.S3.Body' (Else Path)

Send Notification to 'Default' content 'Absence 1'

 

Program Away.S2.Cond

If

Program 'Away.S1.Body' is True

And $X3 is 0

And $AwayNotified is 0

Then

Run Program 'Away.S2.Body' (Then Path)

 

Program Away.S2.Body

If

- No Conditions -

Then

Run Program 'Away.S0.Body' (Else Path)

Run Program 'Away.S1.Body' (Else Path)

Run Program 'Away.S3.Body' (Else Path)

Wait 15 minutes

Send Notification to 'Default' content 'Absence 2'

 

Program Away.S3.Cond

If

Program 'Away.S2.Body' is True

And $X3 is 0

And $AwayNotified is 0

Then

Run Program 'Away.S3.Body' (Then Path)

 

Program Away.S3.Body

If

- No Conditions -

Then

Run Program 'Away.S0.Body' (Else Path)

Run Program 'Away.S1.Body' (Else Path)

Run Program 'Away.S2.Body' (Else Path)

Wait 5 minutes

Resource 'DenonPwrOff'

Resource 'SonosMBRStop'

Resource 'SonosMediaRoomStop'

Resource 'SonosLivRoomStop'

Resource 'TStatOffice Away'

Resource 'TStatUpstairs Away'

$AwayNotified = 1

Run Program 'Away.S0.Body' (Then Path)

 

Program Away.Notified.Reset

If

$X3 > 0

And $AwayNotified is 1

Then

$AwayNotified = 0

 

Currently, what happens when $X3 turns 0 is that S2Body runs and ends but S3Body does not run. I'd appreciate any tips. Thanks.

Link to comment

I got lost trying to follow that logic so I thought about the requirement and have the following to offer:

 

I am assuming $X3 is a State variable.

 

If 
  $X3 = 0

Then
  wait 5 minutes
  Notify #1 - 15 mins till shutdown...
  $AwayNotified = 1
  wait 10 minutes
  Notify #2 - 5 Minutes till Shutdown...
  wait 5 minutes
  Set scenes off
  Set thermostat back.

 

 

If 
  $X3 > 0
  and
  $AwayNotified > 0

then
  Notify Away Mode cancelled
  Set Thermostat to normal settings.
  Set whatever else
  $AwayNotfied = 0

 

Why wouldn't that work?

 

-Xathros

Link to comment

Thanks for your suggestion, Xanthros. Yes, $X3 is a state variable.

 

If $X3 changes to >0 during the wait, I'd like to stop further processing, i.e., no more notifications and no turning off scenes.

 

I am not clear on how exactly the wait command works. Would your code accomplish the interruption? I'll have a chance to try it this evening.

Link to comment

Not sure if I am reading it correctly or if my logic is correct but I believe "Program Away.S3.Body" is not running because it is dependant on the statement "Program 'Away.S2.Body' is True" however that program's 'If' is not called therefore it is never evaluated true or false.

~Mike

Link to comment
Thanks for your suggestion, Xanthros. Yes, $X3 is a state variable.

 

If $X3 changes to >0 during the wait, I'd like to stop further processing, i.e., no more notifications and no turning off scenes.

 

I am not clear on how exactly the wait command works. Would your code accomplish the interruption? I'll have a chance to try it this evening.

 

$X3 being a state variable will cause the If to reevaluate any time it's value changes. The waits will be canceled when it changes to anything > 0. The timers will only expire if $X3 remains at 0 for the full duration. I'm quite sure that will meet your requirements.

 

-Xathros

Link to comment
Not sure if I am reading it correctly or if my logic is correct but I believe "Program Away.S3.Body" is not running because it is dependant on the statement "Program 'Away.S2.Body' is True" however that program's 'If' is not called therefore it is never evaluated true or false.

~Mike

 

Good to know. This helps my understanding going forward. I was actually thinking of using explicit state variables to keep track of state instead of relying on a program's returned value.

 

I'll try Xanthros' code but your suggestion is helpful for multi-state programs. Thanks.

Link to comment
I got lost trying to follow that logic so I thought about the requirement and have the following to offer:

 

I am assuming $X3 is a State variable.

 

If 
  $X3 = 0

Then
  wait 5 minutes
  Notify #1 - 15 mins till shutdown...
  $AwayNotified = 1
  wait 10 minutes
  Notify #2 - 5 Minutes till Shutdown...
  wait 5 minutes
  Set scenes off
  Set thermostat back.

 

 

If 
  $X3 > 0
  and
  $AwayNotified > 0

then
  Notify Away Mode cancelled
  Set Thermostat to normal settings.
  Set whatever else
  $AwayNotfied = 0

 

Why wouldn't that work?

 

-Xathros

 

It worked. The only change I had to make was to move the "$AwayNotified = 1" statement to the bottom (of the first if statement). As the variable is in the condition list, the subsequent waits were being interrupted.

 

Thank you.

Link to comment
  • 1 month later...

This approach to programming the ISY is very useful once you "get it." I'm sure I could get similar results using if..then..elses with variables and etc, but troubleshooting my devices is so easy with this organization.

 

That said I keep rewriting my programs to make them increasingly efficient, organized and uniform. Thus far I've identified 9 states per switch. That's 9 X 8 changes to the Run Else lines of the program. It's tedious.

 

What's the best way to cut, "search and replace" and save method?

Link to comment
  • 2 years later...

Hi All,

 

This post is quite long-in-the-tooth (and good)... I am new to all of this.

 

Can anyone point me to the latest and greatest to learn ISY programming, but using the new variables, event programming, etc, starting with event concepts etc, using variables.  

 

I'm scared of learning concepts here, that may no longer apply using variables, etc

 

Thanks!

Edited by johnstonf
Link to comment
Guest
This topic is now closed to further replies.

×
×
  • Create New...