slammers Posted December 2, 2011 Posted December 2, 2011 I am new to ISY programming and have been struggling with this simple program. I would like my front entrance motion sensor to turn on my front entrance light for 30 seconds but only if the light is currently off. If the light is on I do not want to motion sensor to turn it off. So I wrote this program which does work If ( Status 'LightSwitches / Front Entrance Switch' is not On Or $EntranceMotionActive is 1 ) And ( Control 'Sensors / Motion Entrance-Sensor' is switched On ) And From Sunset To Sunrise (next day) Then $EntranceMotionActive = 1 Set 'LightSwitches / Front Entrance Switch' On Wait 30 seconds Set 'LightSwitches / Front Entrance Switch' Fast Off $EntranceMotionActive = 0 Else - No Actions - (To add one, press 'Action') I had to add the state variable because without it the then clause would stop running as soon as the light was turned on. So setting the state variable to 1 just before turning on the light holds the program status to true. So I then changed the program as I have a keypad link also connected to the front entrance and I wanted its button light to also turn on. If ( Status 'LightSwitches / Front Entrance Switch' is not On Or $EntranceMotionActive is 1 ) And ( Control 'Sensors / Motion Entrance-Sensor' is switched On ) And From Sunset To Sunrise (next day) Then $EntranceMotionActive = 1 Set Scene 'Front Entrance' On Wait 30 seconds Set Scene 'Front Entrance' Fast Off $EntranceMotionActive = 0 Else - No Actions - (To add one, press 'Action') With this code the program runs, the front light turns on as does the Keypadlinc light, but the then clause stops immediately so the wait does not happen and the lights never turn off. I have confirmed that the variable is set to one so I do not understand why the program exists prematurely. Is it a problem with the scene being turned on to soon after the variable is set one so the OR condition is failing? So I added a 5 second delay between setting the variable and turning off the scene and as soon as the scene is turned off the program exits. Is this a bug? I am running firmware 3.1.13 Thanks Shawn
LeeG Posted December 2, 2011 Posted December 2, 2011 The Wait was executed and the IF condition changed to False causing the Program to be reevaluated with the statements after the Wait not executed. The motion sensor may have sensed more than one motion. Is the motion sensor operating in Occupancy mode? EDIT: is that variable a state variable or integer variable
slammers Posted December 2, 2011 Author Posted December 2, 2011 I moved the Or of the state variable outside the bracket and this works. So it seems that the problem is the Control check statement Control 'Sensors / Motion Entrance-Sensor' is switched On is re-evaluated once the scene is turned off and is resulting in false. I guess this makes sense I just do not understand why if I turn the light off alone the program worked but if I turned the scene off it does not. btw I have actually been testing it with a different trigger. I have been using an IRLinc to trigger the program instead of my motion sensor. Shawn
LeeG Posted December 2, 2011 Posted December 2, 2011 The variable should be an Integer variable, not a State variable. Changing a State variable in the Program causes the Program to be reevaluated when the Wait is executed.
ergodic Posted December 2, 2011 Posted December 2, 2011 Shawn: I find the easiest way to deal with the self-canceling problem is to simply break it in two: put the triggers and tests in one program and your actual execution logic into a separate program: //Program IfMotion: If Status 'LightSwitches / Front Entrance Switch' is not On And Control 'Sensors / Motion Entrance-Sensor' is switched On And From Sunset To Sunrise (next day) Then Run Program DoMotion (Then part) Else //Program DoMotion: If Then Set 'LightSwitches / Front Entrance Switch' On Wait 30 seconds Set 'LightSwitches / Front Entrance Switch' Fast Off Else DoMotion only runs when IfMotion calls it (because DoMotion has no conditions or triggers). Any false tests and resulting unwanted 'Else' execution just gets 'absorbed' by the IfMotion program's Else part, and so cannot cancel or affect DoMotion if it is already running. If you have some reason to actually want to cancel DoMotion, you can always run DoMotion's Else part from another program. Doing it this way makes it easier to understand what's happening, you shouldn't need any variable artifice, and whatever logic problems there may be are a lot easier to diagnose. It would be really nice if the ISY just allowed you to delete the Else clause since you rarely want it anyway but this works OK.
Recommended Posts