Jump to content

Programming Gotcha's


rleidy

Recommended Posts

Right.  In a normal if/then/else world, that isn't expected but I do see the need in the case of an ISY (e.g. motion sensor).  It seems to me though, there could be a need for the ability to 'sleep' without being surprised and having the execution jump from the THEN to the ELSE.  Maybe it is a simple counter that is in the IF that gets incremented in the THEN.

 

Anyway, that wasn't the main point of my post.  My point was that the IF/THEN/ELSE in the ISY world is substantially different than normal programming logic and documenting the details of it on a wiki or in the user guide (or preferably both) would be helpful to newbies like me.   I found this thread by trying to understand the process.  There's been some discussion on the forums the past couple days about how to make it easier for people to start using the ISY and I think IF statements are one of those areas that people stumble.

 

Could you provide a real world example of how other systems operate using the IF, THEN, ELSE? I'm having a hard time envisioning what parameters would be drastically different.

 

Perhaps most of us have been using the ISY too long and its just natural?

Link to comment

   CALL checkmotion         <--- linear programming has to have an executive to make this happen, ISY does surprise magic

   If Motion = true Then 

         if (Time > sunrise) and (time < sunset) then     <--- sunrise/sunset never do anything. They are just condition filters

              do something

              do something else

         Else                                 <-----nested If/Then/Else  has to be done with programs in ISY

   Else

       print "nothing is happening"

  Gosub somewhere else          <-----linear programming will wait for the subroutine to finish before continuing,

                                                         ISY spawns multitasking and order or operation can be a surprise

      Next line is always in order.

Link to comment

   CALL checkmotion         <--- linear programming has to have an executive to make this happen, ISY does surprise magic

   If Motion = true Then 

         if (Time > sunrise) and (time < sunset) then     <--- sunrise/sunset never do anything. They are just condition filters

              do something

              do something else

         Else                                 <-----nested If/Then/Else  has to be done with programs in ISY

   Else

       print "nothing is happening"

  Gosub somewhere else          <-----linear programming will wait for the subroutine to finish before continuing,

                                                         ISY spawns multitasking and order or operation can be a surprise

      Next line is always in order.

 

Oh yeah, the nested if!  At 4 am last night I woke up and was thinking about my simple front door light I'm trying to get the program working right.  I kept thinking I needed a nested if and then I remembered people were calling other programs and I realized that was why they were doing that -- essentially a nested if via programs.

Link to comment

Larrylix,

 

Your example, then, begs the question: what is an "executive"? Certainly, the ISY can CALL other programs manually, or within programs (aka nested if, or subroutine). So, how does " executive" differ from "surprise magic"?

LOL.

Simply put the "Executive" would be a supervising program that has to dispatch to that point in the program. This would usually be  some multitasking "overview" program that dispatches to, and makes sure all programs, are run when needed. 

 

ISY has a trigger based event processing executive so the user doesn't have to write complex job handlers and be where and when CPU attention is needed.

 

I worked on a large real-time executive software program that did electrical grid protection handling as well as SCADA function reporting and control. It's system just scanned through lines of code top to bottom and repeated at high speed. From a user's view it worked very similar to ISY but there was no broader If constructs, only inline If/then/else that would do similar to ISY's variable substitution.

 

Anyway from the code writer's view ISY does things as if by magic. You just say when and it happens.

In linear programming you have to continually "test the waters" on each program to even make things work.

Link to comment

Here's an example of a program I'm trying to get to work but failing to do so even though it seems simple.

 

(None of this is insteon, so I'm limited a bit in what I can see of the systems.  This is DSClink plus a serial command to my lighting system.)

 

The goal:

IF the front door is opened, turn on the chandelier.

IF the door was opened and there isn't any motion in the entry anymore, after 15 seconds turn the chandelier off.

 
Front Door - Chandelier - [ID 000C][Parent 0001]
If
        $sAlarmZ01_FrontDoor is 1
Then
        Resource 'Centralite-EntryChandelierOn'
        Run Program 'Front Door-Chandelier Off' (If)
Else
   - No Actions - (To add one, press 'Action')
Front Door-Chandelier Off - [ID 000D][Parent 0001][Not Enabled]
If
        $sAlarmZ17_FrontEntryMotion is 1
Then
   - No Actions - (To add one, press 'Action')
Else
        Wait  15 seconds
        Resource 'Centralite-EntryChandelierOff'

Using a nested program structure is needed to avoid a problem I had where someone could turn on the chandelier inside with the switch and then the program was turning it back off.

 

The chandelier doesn't get turned off in the example above because I think the 2nd program THEN executes and the ELSE does not due to motion.  I haven't found a combination that works yet moving the wait around to different parts of the program(s).

 

Any ideas?

Link to comment

Good morning,

I believe the else does not execute because there is no trigger to execute the else.

I think you need to do something like this, pardon the syntax I just did copy and paste of your text above:

 

If
$sAlarmZ17_FrontEntryMotion is 1 and $sAlarmZ17_FrontEntryMotion not 0
Then
- No Actions - (To add one, press 'Action')
Else

Wait 15 seconds
Resource 'Centralite-EntryChandelierOff'

 

Also think about what happens when the door closes, you may have to also call the chandelier off program in the else part of the first program as well.

 

Edited some lines after thinking about it some more.

 

cheers.

Link to comment

Good morning,

I believe the else does not execute because there is no trigger to execute the else.

I think you need to do something like this, pardon the syntax I just did copy and paste of your text above:

 

If

$sAlarmZ17_FrontEntryMotion is 1 and $sAlarmZ17_FrontEntryMotion not 0

Then

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

Else

 

 

cheers.

 

I originally was not using 2 programs, but I found with 1 program that the ELSE was always running.  If someone turned the chandelier on inside using the switch, the motion detection would trigger the IF and cause the ELSE to run.

 

What advantage does the "not 0" add if the only two possible values are 0 and 1?  I've seen this approach on others examples but I though it was due to the way dimmers report values.

Link to comment

Here's an example of a program I'm trying to get to work but failing to do so even though it seems simple.

 

(None of this is insteon, so I'm limited a bit in what I can see of the systems.  This is DSClink plus a serial command to my lighting system.)

 

The goal:

IF the front door is opened, turn on the chandelier.

IF the door was opened and there isn't any motion in the entry anymore, after 15 seconds turn the chandelier off.

 
Front Door - Chandelier - [ID 000C][Parent 0001]
If
        $sAlarmZ01_FrontDoor is 1
Then
        Resource 'Centralite-EntryChandelierOn'
        Run Program 'Front Door-Chandelier Off' (If)
Else
   - No Actions - (To add one, press 'Action')
Front Door-Chandelier Off - [ID 000D][Parent 0001][Not Enabled]
If
        $sAlarmZ17_FrontEntryMotion is 1
Then
   - No Actions - (To add one, press 'Action')
Else
        Wait  15 seconds
        Resource 'Centralite-EntryChandelierOff'

Using a nested program structure is needed to avoid a problem I had where someone could turn on the chandelier inside with the switch and then the program was turning it back off.

 

The chandelier doesn't get turned off in the example above because I think the 2nd program THEN executes and the ELSE does not due to motion.  I haven't found a combination that works yet moving the wait around to different parts of the program(s).

 

Any ideas?

Try this one

 

Front Door - Chandelier - [iD 000C][Parent 0001]

If

        $sAlarmZ01_FrontDoor is 1

Then

        Resource 'Centralite-EntryChandelierOn'

        Enable Program 'Front Door-Chandelier Off'

        Run Program 'Front Door-Chandelier Off' (Then)

       

Else

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

 

 

 

Front Door-Chandelier Off - [iD 000D][Parent 0001][Not Enabled]

If

        $sAlarmZ17_FrontEntryMotion is Not 1

Then 

       Wait  15 seconds                               <--- you may want to extend this if you don't move fast enough

        Resource 'Centralite-EntryChandelierOff'

        Wait 1 second

        Disable Program 'Front Door-Chandelier Off'

 

Else

       -----

EDIT: Some last minute corrections

 

 

Link to comment

Try this one

 

Front Door - Chandelier - [iD 000C][Parent 0001]

If

        $sAlarmZ01_FrontDoor is 1

Then

        Resource 'Centralite-EntryChandelierOn'

        Enable Program 'Front Door-Chandelier Off'

        Run Program 'Front Door-Chandelier Off' (Then)

       

Else

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

 

 

 

Front Door-Chandelier Off - [iD 000D][Parent 0001][Not Enabled]

If

        $sAlarmZ17_FrontEntryMotion is Not 1

Then 

       Wait  15 seconds                               <--- you may want to extend this if you don't move fast enough

        Resource 'Centralite-EntryChandelierOff'

        Wait 1 second

        Disable Program 'Front Door-Chandelier Off'

 

Else

       -----

EDIT: Some last minute corrections

 

 

 

Ahh, I get it.  Jumping from the THEN to the ELSE -- kind of like an old fashioned GOTO.  This does seem to behave correctly.  I've extended my 'wait' commands a bit since my motion sensor seems to want more time.  I'll tweak and try all use cases.  Thanks for the info.

Link to comment

 

 

It seems to me though, there could be a need for the ability to 'sleep' without being surprised and having the execution jump from the THEN to the ELSE.

You can accomplish this approximately by having your program trigger a second (disabled) programs ''RunThen" which has the wait as the first element. This would not restricted since the second program would be disabled, and wouldn't have anything in the 'If' section.

Link to comment

If often thought that a better construct for ISY would be something like:

 

When

DoorLock changes to Unlocked

If

Hall Light is not 80%

Then

Set Hall Light to 80%

Send Notification 'Door Unlocked'

Wait 10 minutes

Set Hall Light to Off

ELSE

Send Notification 'Door Unlocked'

 

Basically, only events that trigger events can show up when building the 'When' construct, and its a block that discretely defines what should trigger this program - separately from the 'If' construct that is a conditional or suppressive construct. Basically, trigger on these events, only if these conditions match'.

 

So, in the example - the light changing state (for instance the user dimming the light) would not reevaluate the program - but a change in any condition in the 'When' (door being unlocked again) would.

 

I've many times wanted to use a light state as a conditional without having a change in state trigger the program. Right now, its convoluted. I create a second (disabled) program with the status check in the 'If' clause, and 'RunIf' from the main program. It's a pain to keep track of.

 

This way would be easy to automatically upgrade to as well - basically a new 'When' clause would be added to all programs populated with the current 'If' clause without non-triggering events. Overall - it would allow new users to more visually interpret the event driven nature of ISY.

Link to comment

If often thought that a better construct for ISY would be something like:

 

When

DoorLock changes to Unlocked

If

Hall Light is not 80%

Then

Set Hall Light to 80%

Send Notification 'Door Unlocked'

Wait 10 minutes

Set Hall Light to Off

ELSE

Send Notification 'Door Unlocked'

 

Basically, only events that trigger events can show up when building the 'When' construct, and its a block that discretely defines what should trigger this program - separately from the 'If' construct that is a conditional or suppressive construct. Basically, trigger on these events, only if these conditions match'.

 

So, in the example - the light changing state (for instance the user dimming the light) would not reevaluate the program - but a change in any condition in the 'When' (door being unlocked again) would.

 

I've many times wanted to use a light state as a conditional without having a change in state trigger the program. Right now, its convoluted. I create a second (disabled) program with the status check in the 'If' clause, and 'RunIf' from the main program. It's a pain to keep track of.

 

This way would be easy to automatically upgrade to as well - basically a new 'When' clause would be added to all programs populated with the current 'If' clause without non-triggering events. Overall - it would allow new users to more visually interpret the event driven nature of ISY.

There was a  huge discussion of this hoping v5 would pan out some construct changes almost exactly as you indicated. Some thought it would be better to just have a checkbox next to each If line that could disable triggers individually. The When section could make old programs forward compatible easily.

 

I thought the whole syntax should leave the old syntactically incorrect constructs and old programs  behind and clean it up but a lot of barking ensued. (not a legal term :))

 

Just a javascript cross compiler on a Win 10 machine could convert anything to anything and restore it back in.

Link to comment

I originally was not using 2 programs, but I found with 1 program that the ELSE was always running.  If someone turned the chandelier on inside using the switch, the motion detection would trigger the IF and cause the ELSE to run.

 

What advantage does the "not 0" add if the only two possible values are 0 and 1?  I've seen this approach on others examples but I though it was due to the way dimmers report values.

 

Good evening,

Larry has provided a very elegant way of doing what you want I think.

 

As far as your question, I believe the advantage of Not 0 is that it provides a way to trigger the ELSE, that is my understanding.

I am a newbie like you, so before I mislead you I would appreciate if the experts correct me in case I am way off base.

 

I believe if you just have:

 

Front Door-Chandelier Off - [ID 000D][Parent 0001][Not Enabled]

If

$sAlarmZ17_FrontEntryMotion is 1

Then

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

Else

Wait 15 seconds

Resource 'Centralite-EntryChandelierOff'

 

The ELSE never triggers as you have experienced, because the IF in this case only triggers for a state of 1, it does not know what to do (no trigger) when state is 0.

 

cheers. 

Link to comment

Ahh, I get it.  Jumping from the THEN to the ELSE -- kind of like an old fashioned GOTO.  This does seem to behave correctly.  I've extended my 'wait' commands a bit since my motion sensor seems to want more time.  I'll tweak and try all use cases.  Thanks for the info.

Sorry. I missed the alternative shut the sequence off properly.

Here is the correction

 

Front Door - Chandelier - [iD 000C][Parent 0001]

If

        $sAlarmZ01_FrontDoor is 1

Then

        Resource 'Centralite-EntryChandelierOn'

        Enable Program 'Front Door-Chandelier Off'

        Run Program 'Front Door-Chandelier Off' (Then)

       

Else

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

 

 

 

Front Door-Chandelier Off - [iD 000D][Parent 0001][Not Enabled]

If

        $sAlarmZ17_FrontEntryMotion is Not 1

Then 

       Wait  15 seconds                               <--- you may want to extend this if you don't move fast enough

        Resource 'Centralite-EntryChandelierOff'

        Wait 1 second

        Disable Program 'Front Door-Chandelier Off'

 

Else

        Wait 1 second                                                           <--- add these lines to reset the sequence after motion

        Disable Program 'Front Door-Chandelier Off'

Link to comment

Sorry. I missed the alternative shut the sequence off properly.

Here is the correction

 

Front Door - Chandelier - [iD 000C][Parent 0001]

If

        $sAlarmZ01_FrontDoor is 1

Then

        Resource 'Centralite-EntryChandelierOn'

        Enable Program 'Front Door-Chandelier Off'

        Run Program 'Front Door-Chandelier Off' (Then)

       

Else

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

 

 

 

Front Door-Chandelier Off - [iD 000D][Parent 0001][Not Enabled]

If

        $sAlarmZ17_FrontEntryMotion is Not 1

Then 

       Wait  15 seconds                               <--- you may want to extend this if you don't move fast enough

        Resource 'Centralite-EntryChandelierOff'

        Wait 1 second

        Disable Program 'Front Door-Chandelier Off'

 

Else

        Wait 1 second                                                           <--- add these lines to reset the sequence after motion

        Disable Program 'Front Door-Chandelier Off'

 

There's definitely a knack to develop for these.  I think seeing and understanding the flows are important. Thanks for taking time to walk me through it.

Link to comment

Archived

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


×
×
  • Create New...