Jump to content

Tricky timing issue with keypad FadeUp


h0m3h4kk3r

Recommended Posts

I have a strange problem with a 2334-2 v.44 KeypadLinc Dimmer and some programs I'm using to get the behavior I want.   Mostly, the solution I have is working, but there's a timing dependency that I don't understand--and if you get the timing just right, the program doesn't work correctly and the keypad button even seems to malfunction. 

In a nutshell, the goal is for a keypad button to control two devices (a pump and a status light relay) that will run on a timer.  @kclenden and @apostolakisl will recognize this application, since they were kind enough to help me sort out an efficient way to control this same pump with a different setup.  @apostolakisl's suggestion to use an ApplianceLinc to control the pump directly is what started me down this path.  For the new setup, I want a normal keypad button press to start a short timer, and a long press to start a longer timer.  I realize there are other ways to do this (use a different button for long timer, or use a double-tap for long timer, etc....).  The short-press/long-press approach is desirable to me because it mimics the way the devices are controlled by the analog buttons. 

For feedback (and again, to mimic they way the analog buttons will work), I want the user at the keypad to trigger the long timer by pressing the keypad button and waiting until the keypad button lights up before the user releases the button.   I'm differentiating between short press and long press by responding to the Control "On" (for short timer) and Control "Fade Up" (for long timer).  (Thanks again, @kclenden, for helping me understand the difference between Control and Status!)   The problem is to do with the "long-press" behavior.   Here's the program that starts the pump and the timer:

 

KeypadLongTrip - [ID 0027][Parent 001A]

If
        Control 'Family Rm KPD - Can Lights / Family Rm KPD.C' is switched Fade Up
    And $iTestTimerRunning is 0
 
Then
        Set Scene 'TESTING / Test-RunningLights' On
        Set 'TESTING / TEST-LampLinc' On
        Set 'TESTING / TEST-Relay' On
        Run Program 'SensorLongTimer' (Then Path)
 
Else
   - No Actions - (To add one, press 'Action')

 

Note, "TEST-LampLinc" is my stand-in for the ApplicanceLinc that will control the pump -- that should arrive tomorrow.   "Test-RunningLights" is the Scene that has the keypad button as a responder.  And here's the timer program that cuts the pump off again (ignore the conditions for this timer program -- those are there to give me the behavior I want with the analog buttons):

 

SensorLongTimer - [ID 0026][Parent 001A]

If
        Control 'TESTING / TEST-Sensor' is switched Off
    And $iTestTimerRunning is 0
    And $iTestInSensorTrip is 0
 
Then
        $iTestTimerRunning  = 1
        Wait  60 seconds
        Set 'TESTING / TEST-LampLinc' Off
        Set 'TESTING / TEST-Relay' Off
        Set Scene 'TESTING / Test-RunningLights' Off
        $iTestTimerRunning  = 0
 
Else
   - No Actions - (To add one, press 'Action')

 

The KeypadLongTrip program starts running about 1-1.5s after the user presses the keypad button, and "Set Scene 'TESTING / Test-RunningLights' On" changes the state of the button, so the button backlight comes on.  (Presumably the button state changes to "on" as well.)  If I hold the button for about another second, all of this works splendidly.  Releasing the button leaves the button backlight on, and the LampLinc and Relay are both on, and the long timer is running.  Everything is copacetic.

However, if I press the keypad button, and release it as soon as I see the button backlight come on, havoc ensues:

  • The keypad button state goes OFF
  • In the ISY Event Viewer, I see two "OFF" events from the keypad button (which is weird because the normal behavior after "Fade Up" would be "Fade Stop" -- exactly what I see if I hold the button for an extra second after the light comes on...)
  • Pump and relay are OFF, and no timer is running.  (This is ensured by a separate program that responds to the Keypad "OFF" event.)
  • Keypad button appears to be in a seriously hosed state.  The next keypad button press (regardless of whether it's a short press or a long press) does not seem to generate any event at all, but it does change the button state to "On".  You have to do this, and then tap the button again (turn it off) before the button will correctly send "On" or "Fade Up" signals.

If I take the "Set Scene 'TESTING / Test-RunningLights' On" command out of the KeypadLongTrip program, I don't seem to have the problem.  And that seems reasonable-- if there's an issue, it seems likely to me that changing the state of the button while the button is in a transient state (fade) could be the culprit...   But, of course, if I take out that Scene-On command, I get no feedback for the user at the keypad, and it's harder to tell whether I've held the button long enough to mean "Long Timer".  And I'm confused about why the problem doesn't occur if I hold the button just a little longer... It's still in the same transient "fade" state, and I've still changed the state externally...  So, I'm puzzled.

I don't really have enough experience reading the event log to know what I'm looking for-- so I've attached the event logs for a "Normal" Long-timer trip (where I hold the button long enough to get the correct behavior), and for a "Failure Mode" trip (where I hold the button long enough to start the long timer program, but release it immediately after the button backlight comes on).  Perhaps wiser, more experienced forum members may spot the issue?  For reference, I've also attached the event log for a normal short-run.  If it would be helpful to post the event log for "recovery", where I cycle the button on and off to get it back into a correct/stable state, I have that as well, and I'm happy to post it.

 

ISY-LongRun-Normal.txt

ISY-LongRun-FailureMode.txt

ISY-LongRun-Normal.txt

Link to comment

While the "long press" is technically feasible, it would mean capturing fade up  and fade down messages. That's what  a long press means to an Insteon switch, brighten or dim linked controllers when long pressing.   That would get tricky as fade up and fade down alternate... The switches assume the first press is fade up and the following press is fade down.

It will be more predictable to use the key double tap, aka "Fast On". Your program can use this logic for that:

If
    'keypad key' is switched Fast On
Then
   stuff

That will respond directly to a double tap when the switch is currently off.  Or Fast off if the switch is on... that will reliably capture the "double press" behavior from the kepad key.

Paul

Link to comment
16 minutes ago, paulbates said:

While the "long press" is technically feasible, it would mean capturing fade up  and fade down messages. That's what  a long press means to an Insteon switch, brighten or dim linked controllers when long pressing.   That would get tricky as fade up and fade down alternate... The switches assume the first press is fade up and the following press is fade down.

It will be more predictable to use the key double tap, aka "Fast On". Your program can use this logic for that:

If
    'keypad key' is switched Fast On
Then
   stuff

That will respond directly to a double tap when the switch is currently off.  Or Fast off if the switch is on... that will reliably capture the "double press" behavior from the kepad key.

Paul

Understood.  (I mentioned that option as well).   But the long-press should work, if my assumption is correct:  Specifically, if the button is in the "off" state, a long-press will generate "Fade Up" signals, followed by "Fade Stop" when you let go.  The alternating behavior of Fade-Up and Fade-Down only occurs when the button is in the "ON" state when the long-press occurs -- and I don't care about that case at all.  (If the button is in the "ON" state, the pump is already running.)

In any case, even if I don't end up keeping the long-press behavior as my goal, I'd still like to understand what's going on with the timing of this solution if only to deepen my knowledge for future projects.  The timing-sensitive behavior tells me that I'm missing something that's probably pretty fundamental.

Link to comment

The long press will not have consistent behavior. For instance, let's assume the switch is off, and the default local on level is 80%.

When you "long press" the switch on, it will climb to 100%, and then stop sending fast ons.  Similar for dimming to off.

You can experiment with this by linking a lamplinc to a key and watching the behavior.  My point is that smarhome designed long press to support dimmer operation, not discrete remote control by a program.

Paul

Link to comment
7 minutes ago, paulbates said:

The long press will not have consistent behavior. For instance, let's assume the switch is off, and the default local on level is 80%.

When you "long press" the switch on, it will climb to 100%, and then stop sending fast ons.  Similar for dimming to off.

You can experiment with this by linking a lamplinc to a key and watching the behavior.  My point is that smarhome designed long press to support dimmer operation, not discrete remote control by a program.

Paul

How might I verify that the "default local on level" is what's causing the inconsistent behavior I see?   I don't see how that can be in play here, since every event related to pump control explicitly sets the scene to 100% or 0% once the program is responding.  In my case, where I get the wrong behavior, I *know* that my program has indeed begun executing, because the button light comes on.  That doesn't happen if my program is disabled, no matter how long I hold the keypad button.

Link to comment

I created the same two programs in my system, with the exception of leaving out the Lamplinc and Relay commands.  I got exactly the same results as you.  So I looked at your logs but didn't see anything that stuck out as wrong.  So, like you, I removed the "scene on" command and then everything worked as expected.  Then instead of readding the "scene on" command, I added a "beep" command so that there would be some feedback.  The programs continued to work as expected.  But I also noticed that the button light was still coming on when I released it, and going off when the timer turned it off.  This got me to thinking about the keypad toggle modes.  Mine was clearly in "toggle ON/OFF" mode.  Clearly the keypad has to use something to know whether to toggle ON or OFF.  Perhaps it was using the button light as that indicator.  So I changed my button to "non-toggle ON", and added the "scene on" command back to the program.  Magically the programs continue to work correctly.

image.png.eb2ff00bd21257063d2d52637d82ea60.png

So my theory is that turning the button light on while in the middle of a fade up is confusing the keypad.  But I don't know why holding it down an extra second and a half keeps the keypad from becoming confused.  In any case, by taking it out of "toggle ON/OFF" mode, it seems to relieve the keypad of the need to monitor the toggle state and keeps it from becoming confused.

By the way, while I was doing this testing, I used a trick that I think might be useful for you in the future.  I have a state variable called "sCodeCheck".  At various points in the programs I want to check, I add "sCodeCheck=x" where "x" is unique at each point in the code.  So I had "sCodeCheck=1" as the first line of the THEN in "KeypadLongTrip", and "sCodeCheck=2" as the first line of the ELSE.  The first line of "SensorLongTimer" THEN was "sCodeCheck=3" and the first line of the ELSE was "sCodeCheck=4".  Immediately following each of those lines was "sCodeCheck=0".  The reason I do this is because the Event Viewer log shows changes in state variable values.  This not only allows me to confirm in the Event Viewer that specific sections of code were executed, but also makes it easier to tell which Insteon communication was a result of which section of code.  The "sCodeCheck=0" is to make sure that if a section of code is executed sequentially (e.g. because a WAIT is interrupted and the IF is reevaluated with the same result as before) the value assigned to the state variable will be different and the action will be shown in the Event Viewer.  For example, if you assign 1 to a variable, that will appear in the Event Viewer.  If you again assign 1 to the variable it will not appear in the Event Viewer because the value has not changed.  By assigning 0 in between, You'll see both times that 1 is assigned.

Link to comment
10 hours ago, kclenden said:

I created the same two programs in my system, with the exception of leaving out the Lamplinc and Relay commands.  I got exactly the same results as you.  So I looked at your logs but didn't see anything that stuck out as wrong.  So, like you, I removed the "scene on" command and then everything worked as expected.  Then instead of readding the "scene on" command, I added a "beep" command so that there would be some feedback.  The programs continued to work as expected.  But I also noticed that the button light was still coming on when I released it, and going off when the timer turned it off.  This got me to thinking about the keypad toggle modes.  Mine was clearly in "toggle ON/OFF" mode.  Clearly the keypad has to use something to know whether to toggle ON or OFF.  Perhaps it was using the button light as that indicator.  So I changed my button to "non-toggle ON", and added the "scene on" command back to the program.  Magically the programs continue to work correctly.

Indeed!   This makes the long-press behavior work perfectly and reliably, as far as I can tell thus far.

It does have an unexpected (and somewhat undesirable) side-effect on the short-press behavior, though.  Now, with the keypad button in "Non-toggle On" mode, when I short-press the button, the button light comes on, goes off, comes on again, goes off again, and then comes on a third time and stays on while the short timer is running.  The flashing behavior surprised me.   I need to do a little more experimentation to figure out what's causing that...

10 hours ago, kclenden said:

By the way, while I was doing this testing, I used a trick that I think might be useful for you in the future.  I have a state variable called "sCodeCheck".  At various points in the programs I want to check, I add "sCodeCheck=x" where "x" is unique at each point in the code.  So I had "sCodeCheck=1" as the first line of the THEN in "KeypadLongTrip", and "sCodeCheck=2" as the first line of the ELSE.  The first line of "SensorLongTimer" THEN was "sCodeCheck=3" and the first line of the ELSE was "sCodeCheck=4".  Immediately following each of those lines was "sCodeCheck=0".  The reason I do this is because the Event Viewer log shows changes in state variable values.  This not only allows me to confirm in the Event Viewer that specific sections of code were executed, but also makes it easier to tell which Insteon communication was a result of which section of code.  The "sCodeCheck=0" is to make sure that if a section of code is executed sequentially (e.g. because a WAIT is interrupted and the IF is reevaluated with the same result as before) the value assigned to the state variable will be different and the action will be shown in the Event Viewer.  For example, if you assign 1 to a variable, that will appear in the Event Viewer.  If you again assign 1 to the variable it will not appear in the Event Viewer because the value has not changed.  By assigning 0 in between, You'll see both times that 1 is assigned.

10 points for Gryffindor!!!   This is the debugging equivalent of printf, which I was sorely missing.  Brilliant suggestion.  Thanks!   I will use this strategy to try to see what's causing the button flashing on the short-press now that I've disabled toggle...

Link to comment

By way of an update: I've had the solution @kclenden recommended in place now for several days, and apart from the button flashing twice on a short-press, it's working flawlessly.  I still have no idea what's causing the flashing.  Apart from this application, I've never used a keypad button in "Non-Toggle (On)" mode.  Perhaps it's normal behavior for a non-toggle (on) button to flash twice?   I don't see an obvious way to prevent it (especially if I don't know what's causing it in the first place...)

Anyway, thanks again @kclenden for your excellent advice.

Link to comment
10 hours ago, h0m3h4kk3r said:

I don't see an obvious way to prevent it (especially if I don't know what's causing it in the first place...)

I setup a short-press routine and my button blinks twice also.  I tried setting the button to non-toggle OFF and the button still blinks twice when pressed.  I tried playing with button options like (LED on TX and No LED), but couldn't prevent the blinking while also having the LED illuminated.  So I think the blinking is normal behavior, done by the switch, and is probably meant to confirm that your button press was accepted.  In toggle ON/OFF mode you don't need the blinking as confirmation because the LED changes state from ON to OFF or OFF to ON.  Interestingly, the length of time that the button blinks in non-toggle mode is similar to the length of time that you have to hold the button down in toggle mode to get consistent fade results.  I wonder if that is a coincidence.

Link to comment

Archived

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


  • Recently Browsing

    • No registered users viewing this page.
  • Forum Statistics

    • Total Topics
      36.9k
    • Total Posts
      370.2k
×
×
  • Create New...