Capture single and double-tap events for switch


#1

1) Give a description of the problem
I’m trying to update the smarts of our pantry light switch (a Zoos S2 Zen26 on/off) and it’s not working. I’m sure there’s a similar example around here somewhere but I’ve been unable to find it. I believe the problem is that I’m not able to capture the events that I’m using as triggers, which are either a single or double tap on the up paddle of the switch. All other aspects of the piston work.

2) What is the expected behaviour?
The part of the piston that is not working should work like:

  • IF switch button for single tap OR switch button for double tap is pressed THEN set variable to true
  • I then use that variable to add an additional 25 minute delay on turning the switch off

3) What is happening/not happening?
According to the logs, it looks like the variable is never getting set to true. The Zoos support article says that a single tap on the up paddle is button 1 and a double tap is button 3. When I set up the button press trigger it offers me buttons #1-32, but the button values in the log are “up” and “up_2x”
Oddly (to me), if I single or double-tap the switch, then the light just never turns off, so the event is somehow causing it to skip the initial 5-minute turn off timer I have set, but not use the second 25 minute timer to turn off.

**4) Post a Green Snapshot of the piston!

5) Attach logs after turning logging level to Full
11/16/2020, 11:41:51 PM +81ms
+1ms ╔Received event [Pantry Light].button = up_2x with a delay of 39ms
+371ms ║RunTime Analysis CS > 15ms > PS > 338ms > PE > 18ms > CE
+374ms ║Runtime (40927 bytes) successfully initialized in 338ms (v0.3.110.20191009) (372ms)
+375ms ║╔Execution stage started
+386ms ║║Condition #2 evaluated false (7ms)
+387ms ║║Condition group #1 evaluated false (state did not change) (8ms)
+404ms ║║Condition #6 evaluated false (13ms)
+405ms ║║Condition group #5 evaluated false (state did not change) (15ms)
+410ms ║║Comparison (enum) up_2x gets (string) pushed = false (1ms)
+411ms ║║Condition #23 evaluated false (4ms)
+412ms ║║Condition group #22 evaluated false (state did not change) (5ms)
+423ms ║║Condition #10 evaluated false (8ms)
+424ms ║║Condition group #9 evaluated false (state did not change) (10ms)
+426ms ║╚Execution stage complete. (50ms)
+427ms ╚Event processed successfully (426ms)
11/16/2020, 11:35:27 PM +92ms
+1ms ╔Received event [Home].time = 1605594928042 with a delay of -950ms
+158ms ║RunTime Analysis CS > 39ms > PS > 97ms > PE > 21ms > CE
+161ms ║Runtime (40925 bytes) successfully initialized in 97ms (v0.3.110.20191009) (159ms)
+162ms ║╔Execution stage started
+163ms ║╚Execution stage complete. (1ms)
+165ms ╚Event processed successfully (164ms)
11/16/2020, 11:31:18 PM +5ms
+1ms ╔Received event [Pantry Light].button = up with a delay of 40ms
+93ms ║RunTime Analysis CS > 16ms > PS > 61ms > PE > 17ms > CE
+95ms ║Runtime (40803 bytes) successfully initialized in 61ms (v0.3.110.20191009) (94ms)
+96ms ║╔Execution stage started
+107ms ║║Condition #2 evaluated false (7ms)
+108ms ║║Condition group #1 evaluated false (state did not change) (8ms)
+116ms ║║Condition #6 evaluated false (6ms)
+117ms ║║Condition group #5 evaluated false (state did not change) (7ms)
+123ms ║║Comparison (enum) up gets (string) pushed = false (0ms)
+124ms ║║Condition #23 evaluated false (4ms)
+125ms ║║Condition group #22 evaluated false (state did not change) (6ms)
+134ms ║║Cancelling condition #10’s schedules…
+135ms ║║Condition #10 evaluated false (8ms)
+136ms ║║Cancelling condition #9’s schedules…
+137ms ║║Condition group #9 evaluated false (state changed) (10ms)
+139ms ║╚Execution stage complete. (43ms)
+140ms ╚Event processed successfully (140ms)
11/16/2020, 11:30:27 PM +897ms
+2ms ╔Received event [Pantry Light].switch = on with a delay of 39ms
+92ms ║RunTime Analysis CS > 20ms > PS > 56ms > PE > 16ms > CE
+95ms ║Runtime (40807 bytes) successfully initialized in 56ms (v0.3.110.20191009) (92ms)
+96ms ║╔Execution stage started
+107ms ║║Cancelling condition #2’s schedules…
+108ms ║║Condition #2 evaluated false (8ms)
+109ms ║║Cancelling condition #1’s schedules…
+110ms ║║Condition group #1 evaluated false (state changed) (10ms)
+118ms ║║Condition #6 evaluated false (6ms)
+119ms ║║Condition group #5 evaluated false (state did not change) (7ms)
+128ms ║║Condition #23 evaluated false (7ms)
+129ms ║║Condition group #22 evaluated false (state did not change) (8ms)
+134ms ║║Comparison (enum) on changes_to (string) on = true (1ms)
+135ms ║║Cancelling condition #10’s schedules…
+136ms ║║Condition #10 evaluated true (5ms)
+137ms ║║Cancelling condition #9’s schedules…
+138ms ║║Condition group #9 evaluated true (state changed) (7ms)
+140ms ║║Cancelling statement #16’s schedules…
+143ms ║║Executed virtual command [Pantry Light].wait (0ms)
+145ms ║║Requesting a wake up for Mon, Nov 16 2020 @ 11:35:28 PM MST (in 300.0s)
+148ms ║╚Execution stage complete. (52ms)
+150ms ║Setting up scheduled job for Mon, Nov 16 2020 @ 11:35:28 PM MST (in 299.996s)
+156ms ╚Event processed successfully (156ms)
11/16/2020, 11:30:27 PM +120ms
+1ms ╔Received event [Pantry Door].contact = open with a delay of 55ms
+91ms ║RunTime Analysis CS > 17ms > PS > 58ms > PE > 15ms > CE
+93ms ║Runtime (40813 bytes) successfully initialized in 58ms (v0.3.110.20191009) (91ms)
+94ms ║╔Execution stage started
+101ms ║║Comparison (enum) open changes_to (string) open = true (1ms)
+103ms ║║Cancelling condition #2’s schedules…
+103ms ║║Condition #2 evaluated true (5ms)
+104ms ║║Cancelling condition #1’s schedules…
+105ms ║║Condition group #1 evaluated true (state changed) (7ms)
+107ms ║║Cancelling statement #3’s schedules…
+254ms ║║Executed physical command [Pantry Light].on() (143ms)
+255ms ║║Executed [Pantry Light].on (144ms)
+260ms ║║Executed virtual command [Pantry Light].setVariable (2ms)
+265ms ║║Comparison (enum) open changes_to (string) closed = false (1ms)
+267ms ║║Condition #6 evaluated false (4ms)
+267ms ║║Condition group #5 evaluated false (state did not change) (5ms)
+276ms ║║Condition #23 evaluated false (6ms)
+277ms ║║Condition group #22 evaluated false (state did not change) (8ms)
+285ms ║║Condition #10 evaluated false (6ms)
+286ms ║║Condition group #9 evaluated false (state did not change) (7ms)
+288ms ║╚Execution stage complete. (194ms)
+289ms ╚Event processed successfully (289ms)


#2

It looks like the device integration has been updated to use ‘up’ and ‘up_2x’ for press and double press so that is what you need to test for. You’ll have to enter those values manually as expressions as webCoRE doesn’t know about them.

The use of button numbers was a fudge to get around the button capability only having values for pushed and held, and it was also used for multi-button devices. This fudge became a de facto standard used in stock handlers and by webCoRE and Smart Lighting. Automations do not support it. The modern approach is to use the full range of button attribute values, with composite devices used for multiple buttons. Although it is a little behind the times, webCoRE is flexible enough to cope.


#3

Thank you very much for the help! I haven’t used expressions before, but looking at some examples I updated the piston as shown below, but the PantryLightXtendTimer variable is still not getting set to “true.” What am I doing wrong?

11/17/2020, 9:54:07 AM +101ms
+1ms ╔Received event [Pantry Light].button = up_2x with a delay of 40ms
+95ms ║RunTime Analysis CS > 15ms > PS > 59ms > PE > 21ms > CE
+98ms ║Runtime (40785 bytes) successfully initialized in 59ms (v0.3.110.20191009) (96ms)
+99ms ║╔Execution stage started
+110ms ║║Condition #2 evaluated false (7ms)
+111ms ║║Condition group #1 evaluated false (state did not change) (8ms)
+119ms ║║Condition #6 evaluated false (5ms)
+120ms ║║Condition group #5 evaluated false (state did not change) (7ms)
+128ms ║║Calculating (boolean) true (boolean) true >> (boolean) true
+130ms ║║Comparison (enum) up_2x gets (boolean) true = false (1ms)
+132ms ║║Condition #23 evaluated false (8ms)
+133ms ║║Condition group #22 evaluated false (state did not change) (10ms)
+142ms ║║Condition #10 evaluated false (7ms)
+144ms ║║Condition group #9 evaluated false (state did not change) (8ms)
+145ms ║╚Execution stage complete. (47ms)
+146ms ╚Event processed successfully (146ms)
11/17/2020, 9:53:50 AM +804ms
+2ms ╔Received event [Pantry Light].button = up with a delay of 52ms
+95ms ║RunTime Analysis CS > 19ms > PS > 58ms > PE > 20ms > CE
+97ms ║Runtime (40780 bytes) successfully initialized in 58ms (v0.3.110.20191009) (94ms)
+98ms ║╔Execution stage started
+109ms ║║Condition #2 evaluated false (7ms)
+110ms ║║Condition group #1 evaluated false (state did not change) (8ms)
+118ms ║║Condition #6 evaluated false (5ms)
+118ms ║║Condition group #5 evaluated false (state did not change) (6ms)
+125ms ║║Calculating (boolean) true (boolean) true >> (boolean) true
+127ms ║║Comparison (enum) up gets (boolean) true = false (0ms)
+128ms ║║Condition #23 evaluated false (7ms)
+129ms ║║Condition group #22 evaluated false (state did not change) (8ms)
+137ms ║║Cancelling condition #10's schedules...
+138ms ║║Condition #10 evaluated false (7ms)
+139ms ║║Cancelling condition #9's schedules...
+140ms ║║Condition group #9 evaluated false (state changed) (9ms)
+142ms ║╚Execution stage complete. (44ms)
+143ms ╚Event processed successfully (144ms)

#4

I changed the expression to just use “up” instead of the {“up” || “up_2x”} and that seems to be correctly setting the variable. The wiki said that || is the logical operator for OR, but I must not be using it correctly. I want the variable to get set to true on either a single or double tap, because experience shows that someone will forget which one it is.

Edit: Although it now sets the variable to true it is not turning the switch off after the time elapses. So, my current problems are:

  1. How to write the expression so that the variable is set to true on either a single OR double tap.
  2. How to turn the switch off after the specified time period when the variable is true.

#5

It might be clearest to use two conditions so you have:

If
Keypad 1’s button gets {“up”}
Or
Keypad 1’s button gets {“up_2x”}
Then

As far as the timer goes, I’m not entirely clear what events appear and when. It might be that you need to change the Task Cancellation Policy for your two ‘wait’ statements (edit either the wait statements or the withs preceding them, select the settings cog, and set the Task Cancellation Policy to ‘Never Cancel’). That would prevent the waits being cancelled if an event happens during the wait.


#6

I followed both of your recommendations and that appears to have it working the way I want. Thank you very much! Here’s the working piston, in case anyone comes across this thread in the future.