Jump to content

Time waits for no-one... KPL-8 used as timer


poetaaron

Recommended Posts

Hi! Thank you for offering up some of your experience and knowledge to us newbies. I haven't used an isy994i in a long time, and the last time it was using Indigo on a macbook about 6 years ago. I have very little experience writing programs but am very familiar with Insteon devices. Today, no Macbook, no Indigo.

I have a specific problem I'm trying to solve. If you can help me with this I would be so grateful.

Devices:
Controller:  8-button KeypadLinc (7)
Responder: SwitchLinc Dimmer Switch (14)

I want to use each column of buttons on the keypads as a timer control for a single LED light, controlled by a SwitchLinc Dimmer. I set the toggle on the KeypadLincs to ON only so that each press should start a timer that turns on a light as follows: (there's even more excitement at the end...)

Left side of KeypadLinc 1 controls LED 1
A= 30 mins
C= 60 mins
E= 90 mins
G= 120 mins

Right side of KeypadLinc 1 controls LED 2
B= 30 mins
D= 60 mins
F= 90 mins
H= 120 mins
etc...

and now for the highlight:  I would also like the light to flash on and off 8-10 times, 5 minutes before it turns off.   

Any suggestions?

Thanks in advance!

Link to comment

This was a duplicate post from @poetaaron

  •  

Here is how I would do it.
I would create 8 scenes, each containing only one KPL LED = On

Then I would create four programs for each side like this
If
    $sLED1.timer >= 90
Then
   set ledG.scene On
Else
   set ledG.scene Off
 

If
    $sLED1.timer >= 60
Then
   set ledE.scene On
Else
   set ledE.scene Off
 

If
    $sLED1.timer >= 30
Then
   set ledC.scene On
Else
    set ledC.scene Off
 

If
    $sLED1.timer > 0
Then
   set ledA.scene On
Else
    set ledA.scene Off
 

 

Set up a program to decrement the timer state variable $sLED1.timer by 1 minute each repeat as in other variable based timer programs.
Turn off the LED bulb when 0 is reached.

 

Set up a program to advance the state variable timer $sLED1.timer by 15 minutes each timer button A is pushed>

If
    KPL.A is switched On
    AND
    $sLED1.timer <= 90
Then
    $sLED1.timer += 30
Else
   $sLED1.timer = 0
 

Duplicate the whole thing for the other side buttons.

When you press the top left button your LED1 timer variable should advance by 30 minutes each press. Your KPL LEDs should advance in a column by one more for each press, and also decrease for every 30 minutes that the state variable timer $sLED1.timer counts down, indicating the time left on the bulbs.

One too many presses and the timer should reset back to 0 and LED1 bulb should turn off, and the sequence start over again.

 

Let me know how you make out. This is untested and bugs may be found that should be easily fixed.

Link to comment

A couple high level points about the start that @larryllix is suggesting:

  • You cannot control individual LED's on a keypad, but they can be added to scenes and then you can control the scene.  So Larry is suggesting that you create eight scenes (ledA.scene - ledH.scene) where the only member is the corresponding keypad button.
  • You need a variable to hold the number of minutes left on your timer.  Since you're going to want to react to this timer (e.g. turn light off when it reaches 0, etc) you need to make it a STATE variable not an INTEGER variable.  That is why Larry prefixed the variable name with a small "s" (e.g. $sLED1.timer instead of $iLED1.timer).  When you duplicate the programs for the buttons on the right sided of the keypad, you'll need a second timer variable (e.g. $sLED2.timer).

The first four programs Larry provided take care of illuminating appropriate keypad button lights according to how much time is on the timer.  They don't, however, take care of turning the keypad button light off as the timer decrements, so I would change all four by adding a command to the ELSE section.  For example:

If
    $sLED1.timer >= 90
Then
   set ledG.scene On
Else
   set ledG.scene Off

This will do a couple things.  As your timer counts down, when it goes to 89, 59, 29, 0 it will turn off the appropriate keypad button light.  It will also keep the lights in sync.  Let's say there's 57 minutes left on the timer (so both buttons A and C should be off) and someone presses button C.  You don't have any programs looking for a keypress of button C so the ISY won't do anything, but the actual button hardware will illuminate button C which would put the lights out of sync with your timer.  Luckily, when the timer drops to 56 the appropriate program will run and turn OFF keypad button C.

 

Link to comment
17 minutes ago, kclenden said:

A couple high level points about the start that @larryllix is suggesting:

  • You cannot control individual LED's on a keypad, but they can be added to scenes and then you can control the scene.  So Larry is suggesting that you create eight scenes (ledA.scene - ledH.scene) where the only member is the corresponding keypad button.
  • You need a variable to hold the number of minutes left on your timer.  Since you're going to want to react to this timer (e.g. turn light off when it reaches 0, etc) you need to make it a STATE variable not an INTEGER variable.  That is why Larry prefixed the variable name with a small "s" (e.g. $sLED1.timer instead of $iLED1.timer).  When you duplicate the programs for the buttons on the right sided of the keypad, you'll need a second timer variable (e.g. $sLED2.timer).

The first four programs Larry provided take care of illuminating appropriate keypad button light according to how much time is on the timer.  They don't, however, take care of turning the keypad button light off as the timer decrements, so I would change all four by adding a command to the ELSE section.  For example:

If
    $sLED1.timer >= 90
Then
   set ledG.scene On
Else
   set ledG.scene Off

This will do a couple things.  As your timer counts down, when it goes to 89, 59, 29, 0 it will turn off the appropriate keypad button light.  It will also keep the lights in sync.  Let's say there's 57 minutes left on the timer (so both buttons A and C should be off) and someone presses button C.  You don't have any programs looking for a keypress of button C so the ISY won't do anything, but the actual button hardware will illuminate button C which would put the lights out of sync with your timer.  Luckily, when the timer drops to 56 the appropriate program will run and turn OFF keypad button C.

 

Nice catch! The force is strong with this one!

Modified post to match. I was originally mentally designing to have all four LEDs in each scene and use it that way. Need an ISY "select" construct here. :)

I don't like all scenes being hit on every minute simultaneously though. KPLs are all in one device address. hmmmm....maybe disable 3/4 and call each in a daisychain of progressive value tests? Maybe wait and see if the OP comes back with something.

Link to comment
On 8/16/2020 at 11:14 PM, larryllix said:

I don't like all scenes being hit on every minute simultaneously though

I was originally thinking that wouldn't be a problem because the ISY doesn't send an ON or OFF command if it already thinks a device is ON or OFF respectively.  But this would be sending a scene command which I believe the ISY would always send.  So I'd probably go back to your original programs and add a test of the button's state to the IF and add a second set of programs that would look to see if the button should be turned OFF.  For example:

If
    $sLED1.timer >= 90 AND KPL.G is OFF
Then
   set ledG.scene On
Else
 

If
    $sLED1.timer < 90 AND KPL.G is ON
Then
   set ledG.scene Off
Else
 

Link to comment

Hey guys...  so, I've been just using one of the 7 KPLswitches to prototype, so controlling lanes 1 and 2 leds/timers.

I've created a scene for each of the buttons on KPL1
1A.SCENE, 1B.SCENE, etc

I've created these programs:
$sSL1.TIMER.30
(the program)
IF          $sS.L1.TIMER  >=  30
THEN   SET   '1A.SCENE'  ON

ELSE    SET   '1A.SCENE'  OFF

The rest are done the same
$sSL1.TIMER.60, $sSL1.TIMER.90, $sSL1.TIMER.120
$sSL2.TIMER.30, $sSL2.TIMER.60, $sSL2.TIMER.90, $sSL2.TIMER.120


And created these state variables:
sS.L1.TIMER   init 0  value 0
sS.L2.TIMER   init 0  value 0


If this looks like I'm on the right track, please let me know, and if I'm way off, please steer me back on course.

I've been trying to figure out the Timer program referenced by Larryllix (larry?) :
   "Set up a program to decrement the timer state variable $sLED1.timer by 1 minute each repeat as in other variable based timer programs.
    Turn off the LED bulb when 0 is reached."


I've searched timer, countdown, decrement. I've googled and Wiki'd, and even broke down and asked Alexa, who thinks I'm an idiot anyway.

Can you help me with that that vital piece of code?  And please don't hesitate to laugh at my attempts or even publicly demean me, as long as you can help through this pain.

Thank you!
 

Link to comment

@poetaaronFirst get rid of the Else code for each program. When the variable changes to any number less than 30, all program Elses sections will attempt to run simultaneously. Your Insteon system won't like that much traffic.

 

Rather than finding it I will create the countdown timer from mental confusion. :)

If
     $sLED1.timer > 0
Then
    Wait 1 minute
   $sLED1.timer -= 1
Else
   set lamp Off

That's it. Self triggering and self- retriggerring, and simple.

ISY is amazing! :):)

 

 

Oh! BTW! You can right click on your program name in the program tree and select copy to clipboard. Paste into your post.

Link to comment

Good morning!

 

Thanks for the copy to clipboard tip!
 

$L1.TIMER - [ID 000B][Parent 0001]

If
        $sS.L1.TIMER < 0
 
Then
        Wait  1 minute 
        $sS.L1.TIMER -= 1
 
Else
        Set '1A.SCENE' Off   
_________________________________ 

$sSL1.TIMER.030 - [ID 0006][Parent 0001]

If
        $sS.L1.TIMER >= 30
 
Then
        Set '1A.SCENE' On
 
Else
   - No Actions - (To add one, press 'Action')

______________________________________________

$L1.ADD30 - [ID 0003][Parent 0001] 
"I was looking at this as the trigger program that sets the rest in motion when KPL1.A
is pressed, although It's possible that I'm missing something (everything)".

If
        'LANE1-30' is switched On 
    And $sS.L1.TIMER <= 90
 
Then
        $sS.L1.TIMER += 30
        Wait  2 seconds
        Run Program '$sSL1.TIMER.030' (If)
 
Else
   - No Actions - (To add one, press 'Action')

___________________________________________


I wrote that last one mostly so I can see if I'm understanding the logic and the flow.

Do the programs run automatically or only when triggered by an event?

Thank you!  If it would help seeing it live, I could probably use a shared-screen somehow.

I would not normally think of using someone else's time to solve my problems, but being able to get help on this is likely going to save my neck. Not only that though... I'm liking the feel of programming again, and now I'm encouraged to learn programming on the ISY so I can more easily bring the "out of the box" ideas that I seem to have an endless supply of to life. To me, this language uses all the principals of a relational database structure, where the devices are just data fields that can either be constants, variables, triggers, calculations, etc. I started DB design & programming back in mid-eighties with Dbase, HyperCard / HyperPad, Skipper, FoxPro, DataEase, and Access. But being able to apply those techniques to real-world scenarios will make it easier to learn this new skill. ?
 

Link to comment

I do NOW!!  Thank you!!  Oh yeah...  just cruised through and I cannot wait to start building things with it. I've installed Insteon components in a dozed theater environments, but have not taken full advantage of the power and versatility when coupled to an ISY. This is a good opportunity for me. The cookbook is just what I needed!

Thanks Brian!

Link to comment
6 hours ago, poetaaron said:

Good morning!

 

Thanks for the copy to clipboard tip!
 

$L1.TIMER - [ID 000B][Parent 0001]

If
        $sS.L1.TIMER < 0          <-------- wrong operator. Program will cycle forever and not do anything.
 
Then
        Wait  1 minute 
        $sS.L1.TIMER -= 1
 
Else
        Set '1A.SCENE' Off      <---------------- what is this Hopefully this is a scene that controls the light?
_________________________________ 

$sSL1.TIMER.030 - [ID 0006][Parent 0001]

If
        $sS.L1.TIMER >= 30
 
Then
        Set '1A.SCENE' On
 
Else
   - No Actions - (To add one, press 'Action')

______________________________________________

$L1.ADD30 - [ID 0003][Parent 0001] 
"I was looking at this as the trigger program that sets the rest in motion when KPL1.A
is pressed, although It's possible that I'm missing something (everything)".

If
        'LANE1-30' is switched On 
    And $sS.L1.TIMER <= 90
 
Then
        $sS.L1.TIMER += 30
        Wait  2 seconds
        Run Program '$sSL1.TIMER.030' (If)  <---- what does this do? ISY is event triggered. Testing loops are not required.
 
Else
   - No Actions - (To add one, press 'Action')   <------- you lost the recycle part in case you want to rotate until 0 happens again.

___________________________________________


I wrote that last one mostly so I can see if I'm understanding the logic and the flow.

Do the programs run automatically or only when triggered by an event?

Thank you!  If it would help seeing it live, I could probably use a shared-screen somehow.

I would not normally think of using someone else's time to solve my problems, but being able to get help on this is likely going to save my neck. Not only that though... I'm liking the feel of programming again, and now I'm encouraged to learn programming on the ISY so I can more easily bring the "out of the box" ideas that I seem to have an endless supply of to life. To me, this language uses all the principals of a relational database structure, where the devices are just data fields that can either be constants, variables, triggers, calculations, etc. I started DB design & programming back in mid-eighties with Dbase, HyperCard / HyperPad, Skipper, FoxPro, DataEase, and Access. But being able to apply those techniques to real-world scenarios will make it easier to learn this new skill. ?
 

 

You need to pay closer attention to all the lines in the programs. I am totally confused by what you have done. I suggest you copy verbatim until you get it running and then experiment for education purposes.

Link to comment

Will do. Going to go verbatim and will send the text when I'm done.

1A.SCENE is the name of the scene that contains KPL1 Button A.
So 1A.SCENE thru 1G.SCENE for the 8 buttons on the KPL1

Let me rewrite this and I'll post the results. Working on it most of the night...  I'll get this.

 

 

Link to comment

Good morning, larryllix...

Ok... so here's what I have.   

--------------------------------------------------------------- 

$L1.ADD30       "This is the program that runs when button KPL1.A is pressed. Then $L2.ADD30, $L3.ADD30, etc?"

If
        'LANE1-30' is switched On       "LANE1-30 is KPL1.A"  
    And $sS.L1.TIMER >= 90
 
Then
        $sS.L1.TIMER += 30
 
Else
        $sS.L1.TIMER  = 0

_____________________________________________

$L1.TIMER     "The timer program as you gave it to me... untouched... pristine even."

If
        $sS.L1.TIMER > 0
 
Then
        $sS.L1.TIMER -= 1
 
Else
        Set '1A.SCENE' Off
____________________________________________

$sSL1.TIMER.000     "The first of the four programs for each lane"

If
        $sS.L1.TIMER >= 0
 
Then
        Set '1A.SCENE' On
 
Else
       - No Actions - (To add one, press 'Action')
_____________________________________________

$sSL1.TIMER.030    "There will need to be a total of 56 programs like this, all the way to 'SL14.TIMER.090'".

If
        $sS.L1.TIMER >= 30
 
Then
        Set '1C.SCENE' On
 
Else
        - No Actions - (To add one, press 'Action')
___________________________________________

Two quickie questions:
When I click "Run (IF)" on a program, is that the same as physically pressing the button on the switch?
Is there any way to edit these programs in a text file?

Hope you have a great day!

Link to comment

Here is the program I posted:
If
    KPL.A is switched On
    AND
    $sLED1.timer <= 90
Then
    $sLED1.timer += 30
Else
   $sLED1.timer = 0
 

Here is what you posted:
        'LANE1-30' is switched On 
    And $sS.L1.TIMER >= 90
Then
        $sS.L1.TIMER += 30
Else
        $sS.L1.TIMER  = 0

 

Do you see any difference other than the element names? Your other programs have been even worse.
You need to proofread more closely.

Link to comment

Yes...   <= 90     not     >=90. 

Damn...  I'm sorry...  I'll be re-reading everything sent to me now.

I've already found at least one other omission in the timer program:  I forgot to add the "WAIT one minute" statement...

I'm sure there are more. I won't post again until I'm confident that my programs are correct and written exactly as you've explained to me.

Take care!

Link to comment
3 minutes ago, poetaaron said:

Yes...   <= 90     not     >=90. 

Damn...  I'm sorry...  I'll be re-reading everything sent to me now.

I've already found at least one other omission in the timer program:  I forgot to add the "WAIT one minute" statement...

I'm sure there are more. I won't post again until I'm confident that my programs are correct and written exactly as you've explained to me.

Take care!

Yeah, programming is critical. Without that 1 minute delay that program could hang your ISY so it may never catch up. :)

Link to comment

Archived

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


×
×
  • Create New...