Philips Tap Dial Switch with double tap and 4 dial actions

Hey Freddie and everyone.
First of all, thanks for your hard and beautiful work with Hue Tap, especially with the blueprint to make the life easier. I love Hue Taps as I think they can do almost everything what you need for your lights and music in one device. I was trying to use your blueprint, but unfortunately, I can’t set up few things the way I would like to.
I came to slightly different idea, but have no idea how can I achieve it as I don’t have any knowledge it yaml coding or programming at all. So please don’t judge me too much. I was trying to do it in UI itself, but couldn’t get anywhere near. So I’m trying to twist you yaml, but it’s not working too.
My idea is to get rid of the last pressed helper and use a double tap detection as a trigger to related buttons. The main reason for that is. If I used button 1 for lights then I won’t be able adjust volume on button 3 until I press it and if my Sonos if on already it will switch it off and obviously vice versa.
Below is my target for all actions that I would like to archive and yaml with your coding that I’m trying to twist.
Would you mind please to have a look at it what I’m doing wrong as I’m getting error when I’m trying to save the blue print.

Button 1
Press - On/Off Lights
Hold - Favourite Scene - e.g Main Light
Double Press - Activate Dimming
Turn Left/Right for Dimming Up/Down - Main lights

Button 2
Press - Scroll Scenes
Hold - Back to Scene 1
Double Press - Activate Dimming
Turn Left/Right for Dimming Up/Down - Selected lights

Button 3
Press - On/Off Sonos Player
Hold - Change Favourite Radio Station
Double Press - Activate Volume
Turn Left/Right for Volume Up/Down

Button 4
Press - On YouTube Music Playlist Shuffled
Hold - Back to Radio Favourites
Double Press - Activate Action
Turn Left - Previous Track
Turn Right - Next Track

blueprint:
name: Philips Tap Dial
description: Control Actions and Volume for Lights and Media Player

domain: automation
input:
mqtt_topic:
name: MQTT Topic
description: Topic of the Philips Hue Tap Dial Switch
default: zigbee2mqtt/
tap_counter:
name: Counter Helper
description: Create a counter helper within Home Assistant to monitor the number
of button presses on the switch, distinguishing between single and multiple
clicks. This helper can be used for various switches, provided that they are
not pressed at the same time
selector:
entity:
domain:
- counter
multiple: false

button_1_single_press:
    name: Button 1 Single Press
    description: Action to run on button 1 single press
    default: []
    selector:
      action: {}
button_1_hold:
  name: Button 1 Hold
  description: Action to run on button 1 hold
  default: []
  selector:
    action: {}
dial_rotate_left_after_double_press_button_1:
  name: Dial Left After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}
dial_rotate_right_after_double_press_button_1:
  name: Dial Right After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}
  
button_2_single_press:
  name: Button 2 Single Press
  description: Action to run on button 2 single press
  default: []
  selector:
    action: {}
button_2_hold:
  name: Button 2 Hold
  description: Action to run on button 2 hold
  default: []
  selector:
    action: {}
dial_rotate_left_after_double_press_button_2:
  name: Dial Left After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}
dial_rotate_right_after_double_press_button_2:
  name: Dial Right After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}

button_3_single_press:
  name: Button 3 Single Press
  description: Action to run on button 3 single press
  default: []
  selector:
    action: {}
button_3_hold:
  name: Button 3 Hold
  description: Action to run on button 3 hold
  default: []
  selector:
    action: {}
dial_rotate_left_after_double_press_button_3:
  name: Dial Left After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}
dial_rotate_right_after_double_press_button_3:
  name: Dial Right After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {} 

button_4_single_press:
  name: Button 4 Single Press
  description: Action to run on button 4 single press
  default: []
  selector:
    action: {}
button_4_hold:
  name: Button 4 Hold
  description: Action to run on button 4 hold
  default: []
  selector:
    action: {}
dial_rotate_left_after_double_press_button_4:
  name: Dial Left After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}
dial_rotate_right_after_double_press_button_4:
  name: Dial Right After Double Press Button 1
  description: To be controlled with the dial
  selector:
    action: {}

mode: parallel
max: 10
max_exceeded: silent

trigger:

  • platform: mqtt
    topic: !input mqtt_topic

condition:

  • condition: template
    value_template: ‘{{ trigger.payload_json.action != ‘’’’ }}’
    action:

  • variables:
    counter_var: !input tap_counter

  • choose:
    button 1 Action

    • conditions:
      value_template: ‘{{ trigger.payload_json.action is match(’‘^button_1_press$’‘)
      }}’
      sequence:
      • if:
        • condition: template
          value_template: ‘{{ trigger.payload_json.action is match(’‘button_1_single_press’‘)
          }}’
          then:
      • delay:
        milliseconds: 250
      • if:
        • condition: template
          value_template: ‘{{ states(counter_var) > ‘‘1’’ }}’
          then:
        • stop: Double tap detected
          sequence:
          • choose:
            • conditions:
              • condition: template
                value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_left_’‘)
                }}’
                sequence: !input dial_rotate_left_after_double_press_button_1
            • conditions:
              • condition: template
                value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_right_’‘)
                }}’
                sequence: !input dial_rotate_right_after_double_press_button_1
            • service: counter.reset
              target:
              entity_id: ‘{{ counter_var }}’
    • conditions:
      • condition: template
        value_template: ‘{{ trigger.payload_json.action == ‘‘button_1_single_press’’
        }}’
        sequence: !input button_1_single_press
    • delay:
      seconds: 1
    • service: counter.reset
      target:
      entity_id: ‘{{ counter_var }}’
    • conditions:
      • condition: template
        value_template: ‘{{ trigger.payload_json.action == ‘‘button_1_hold’’ }}’
        sequence: !input button_1_hold

button 2 Action

  • conditions:
    value_template: ‘{{ trigger.payload_json.action is match(’‘^button_2_press$’‘)
    }}’
    sequence:
  • if:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action is match(’‘button_2_single_press’‘)
      }}’
      then:
    • delay:
      milliseconds: 250
    • if:
      • condition: template
        value_template: ‘{{ states(counter_var) > ‘‘1’’ }}’
        then:
      • stop: Double tap detected
        sequence:
        • choose:
          • conditions:
            • condition: template
              value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_left_’‘)
              }}’
              sequence: !input dial_rotate_left_after_double_press_button_2
          • conditions:
            • condition: template
              value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_right_’‘)
              }}’
              sequence: !input dial_rotate_right_after_double_press_button_2
          • service: counter.reset
            target:
            entity_id: ‘{{ counter_var }}’
  • conditions:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action == ‘‘button_2_single_press’’
      }}’
      sequence: !input button_2_single_press
    • delay:
      seconds: 1
  • service: counter.reset
    target:
    entity_id: ‘{{ counter_var }}’
  • conditions:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action == ‘‘button_2_hold’’ }}’
      sequence: !input button_2_hold

button 3 Action

  • conditions:
    value_template: ‘{{ trigger.payload_json.action is match(’‘^button_3_press$’‘)
    }}’
    sequence:
  • if:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action is match(’‘button_3_single_press’‘)
      }}’
      then:
    • delay:
      milliseconds: 250
    • if:
      • condition: template
        value_template: ‘{{ states(counter_var) > ‘‘1’’ }}’
        then:
      • stop: Double tap detected
        sequence:
        • choose:
          • conditions:
            • condition: template
              value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_left_’‘)
              }}’
              sequence: !input dial_rotate_left_after_double_press_button_3
          • conditions:
            • condition: template
              value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_right_’‘)
              }}’
              sequence: !input dial_rotate_right_after_double_press_button_3
          • service: counter.reset
            target:
            entity_id: ‘{{ counter_var }}’
  • conditions:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action == ‘‘button_3_single_press’’
      }}’
      sequence: !input button_3_single_press
    • delay:
      seconds: 1
    • service: counter.reset
      target:
      entity_id: ‘{{ counter_var }}’
  • conditions:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action == ‘‘button_3_hold’’ }}’
      sequence: !input button_3_hold

button 4 Action

  • conditions:
    value_template: ‘{{ trigger.payload_json.action is match(’‘^button_4_press$’‘)
    }}’
    sequence:
  • if:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action is match(’‘button_4_single_press’‘)
      }}’
      then:
    • delay:
      milliseconds: 250
    • if:
      • condition: template
        value_template: ‘{{ states(counter_var) > ‘‘1’’ }}’
        then:
      • stop: Double tap detected
        sequence:
        • choose:
          • conditions:
            • condition: template
              value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_left_’‘)
              }}’
              sequence: !input dial_rotate_left_after_double_press_button_4
          • conditions:
            • condition: template
              value_template: ‘{{ trigger.payload_json.action is match(’‘^dial_rotate_right_’‘)
              }}’
              sequence: !input dial_rotate_right_after_double_press_button_4
          • service: counter.reset
            target:
            entity_id: ‘{{ counter_var }}’
  • conditions:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action == ‘‘button_4_single_press’’
      }}’
      sequence: !input button_4_single_press
  • delay:
    seconds: 1
  • service: counter.reset
    target:
    entity_id: ‘{{ counter_var }}’
  • conditions:
    • condition: template
      value_template: ‘{{ trigger.payload_json.action == ‘‘button_4_hold’’ }}’
      sequence: !input button_4_hold

Hi @SmartSparx, welcome to the forum!

I have a comparable setup to yours. Which is another reason why we decided to publish both the blueprint and the automation on our blog post at smarthomegeeks.io. Adjusting the automation (through UI) to specific needs is a lot easier than adjusting the blueprint (in yaml).

Some thought pointers for you…

  1. the last press and counter helper are the core function in our code to detect the double tap for the hue tds, you will not be able to identify a double tap without these

  2. the way I solved it, is to move the update last button press action to the end of the automation. This way, you can use the single press for two functions:

  • if the last press button is equal to the one you are pressing now, you execute the desired action (i.e. play/pause)
  • if the last press button is different from the one you are pressing now, then you only update the last press button helper. This way you allow the dial to adjust the volume without toggling play/pause

The biggest drawback is that you don’t know what is the last press button, as there is no visual feedback (light/display) on the Hue Tap Dial Switch.

Hi @Purpleturtle

This is also possible. Quickest way is to use the automation, remove the dial options for button 2, 3 and 4 and for dial option 1 remove the condition that validates the last press button.

This way you have only one option for actioning a dial rotation, independent from the last press helper

I’m using a similar blueprint to yours and ran into the same issue. The way I handled it was to set a timer which switches last pressed back to button 1.

That way the default rotation dims my main lights, then a double click of any other button makes the dial rotation correspond to the button I just double clicked. After X time of no activity, the dial defaults to controlling the main lights again

2 Likes

Nice one! I’m using it mainly for controlling speaker volumes, where I have enriched the automation to set the last pressed based on which speaker is playing music.

1 Like

Hi JeroendB. Thank you for your replay. It’s totally clear to me about the counter and the last press. It makes a sense when you press button 1 (example) for your lights and dim your lights straight away or the same think with a music player, but when you’re in the middle somewhere it doesn’t work. So that’s why I thought, may be it’s possible to get rid of last press and use “double click” as a trigger to that button - if it’s lights the dim, if it’s music layer then volume and etc.
But if you say it’s impossible it’s impossible.
I think I managed to re-sort targets on my buttons and do it they way I want. I will try to do toggle on/off on the single press (lights/player) and then only toggle on a double press. Didn’t try it yet, but thinking it should work.

Button 1
Press - On/Off Main Lights
Hold - Scroll Scenes
Double Press - On Main Ligths
Turn Left/Right for Dimming Up/Down - Main lights

Button 2
Press - Favorite Scene
Hold - Back to Scenes 1
Double Press - Favorite Scene
Turn Left/Right for Dimming Up/Down - Selected lights

Button 3
Press - On/Off Music Player
Hold - Change Favourite Radio Station
Double Press - On Music Player
Turn Left/Right for Volume Up/Down

Button 4
Press - On YouTube Music Playlist Shuffled
Hold - Back to Radio Favourites
Double Press - On Music Player
Turn Left - Previous Track
Turn Right - Next Track

I’m struggling to get get this Blueprint (Z2MQTT) to make my button respond. It doesn’t action my automation despite following:

  1. SmartHomeGeeks guide
  2. Tried Disabling Home Assistant legacy triggers and Home Assistant legacy entity attributes. Also tried with them enabled

The dial does work, but just not with this Blueprint. What am I doing wrong?

Based on your screenshot, it seems the MQTT topic might be incorrect. I suggest using MQTT Explorer to verify the correct topic. It appears you might have used the Home Assistant entity name, which is likely not the right one for this purpose.

Hi! I originally had this automation working on a tap dial using the old version of the code (pre-blueprint), but accidentally hosed it when I added a second tap dial to homeassistant and couldn’t get it back to working.

I tried to incorporate the new blueprint, but am having the same issue with the counter not incrementing above 1. I tried reloading the blueprint, enabling/disabling the two legacy options in Z2M, but the end result is always the same - counter will not increment above 1! I almost had it working on one of the tap dials at one point, but the counter would increment by 2 every time I clicked, even when the step size was set to 1.

At this point, I’m at a loss and am only just starting to get familiar with the debugging tools available. In the Z2M logs, a single button press yields the below (first time trying to format code so apologies if it doesn’t work!). Double pressing just doubles the same messages. It almost seems like each button press is registering twice. Any insight at all would be greatly appreciated! The old code was PERFECT for my uses. The new blueprint is a million times easier to set up, but I’m stuck with getting it to work now!

Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial', payload '{"action":"button_4_press","action_direction":null,"action_step_size":null,"action_time":null,"action_type":null,"battery":100,"brightness":null,"linkquality":81,"update":{"installed_version":33569561,"latest_version":33569561,"state":"idle"},"update_available":false}'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial/action', payload 'button_4_press'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial', payload '{"action":"button_4_press","action_direction":null,"action_step_size":null,"action_time":null,"action_type":null,"battery":100,"brightness":null,"linkquality":81,"update":{"installed_version":33569561,"latest_version":33569561,"state":"idle"},"update_available":false}'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial/action', payload 'button_4_press'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial', payload '{"action":"button_4_press_release","action_direction":null,"action_step_size":null,"action_time":null,"action_type":null,"battery":100,"brightness":null,"linkquality":78,"update":{"installed_version":33569561,"latest_version":33569561,"state":"idle"},"update_available":false}'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial/action', payload 'button_4_press_release'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial', payload '{"action":"button_4_press_release","action_direction":null,"action_step_size":null,"action_time":null,"action_type":null,"battery":100,"brightness":null,"linkquality":81,"update":{"installed_version":33569561,"latest_version":33569561,"state":"idle"},"update_available":false}'
Zigbee2MQTT:info  2024-04-06 11:14:19: MQTT publish: topic 'zigbee2mqtt/Bedroom Tap Dial/action', payload 'button_4_press_release'

Hi @jriggit,

From your log it appears that the single button press triggers 2 MQTT messages for each command. As a result, the helper (rightfully) jumps with an increment of 2.

When you added the second tap dial switch to Z2M, did you give it a unique name? It looks like this is between z2m and mqtt and not in HA or the automation / blueprint.

You could consider the following troubleshooting:

  • ensure you have unique helpers for each tap dial switch
  • ensure the helpers are correctly assigned in the blueprint
  • ensure the zigbee topic is correct

Thanks so much for the guidance. I worded my question poorly and apologize!

My issue is that the counter won’t increment above 1. If I change the blueprint to use the helper names as you list them in the blog (counter.philips_hue_dial_switch_button_counter), the automation increments by FOUR in the latest blueprint, but it at least succeeds in incrementing.

It’s possible it’s incrementing by multiples due to issues on my end, but could you test if double tap in your blueprint works for you if you name the helpers to something else?

I’m beginning to wonder if the code accidentally refers to a static variable for incrementing the counter, instead of updating the variable defined in the blueprint… The behavior seems to change if I use the helper names you use in the blog vs. my own helper names - if that makes sense.

If you can’t replicate my problem, I may need to settle for no double-taps to avoid frustrating my SO too much since we haven’t been able to control bedroom lights for the last week now :). Thanks so much for all of your help.

EDIT: I found a fix that will work for now! I deleted all of my variables and automations, removed the tap dial from Z2M, and factory reset the tap dial device. Now, the automations are only detecting TWO (2) button presses for every single button press. Using the YAML version of the code, I updated the double-tap detection to look for a counter value >2 (instead of >1). Everything seems to be working as it did before. I suspect I need to put in a separate inquiry with the Zigbee2MQTT teams to see if I can figure out why my tap dials are registering double presses. Wondering if “debouncing” is a subject I need to explore further…

Thanks again for this code! Digging around has been so helpful for teaching me the YAML syntax for assigning “global” variables among other robust and concise coding methods.

1 Like

Hi @JeroendB
Would you be willing to share a .yaml automation file that implements the solution outlined in thought pointer 2?
Many thanks to you and @fleeman for your work and help.

Hello,
Thanks a lot to fleeman for this! Wonderfull.
Is there someone who could adapter this in node red? I try to do the same thing with Delay, Tigger Switch etc.
Because with this automation i can"t use the modification with dial and température as i can do with brightness.
The Idea to count the press and time between this press and release and also follow the dial is excellent but i’m a newbee in Node red to do this :frowning:
Someone could help to do this in node red.? I can’t add my flow in this forum because i don’t find a way to upload Json File and the code (copy paste of this flow exceed the number of caractère in a post :frowning: )

Br

Thank you for this. Just got Hue Tap Switch today. But I have some problems.

  • Click and double clicks work fine. I am able to enable to scene
  • Rotation after click does not work very well, especially when I select full floor for lights selector (I have 3 Hue lamps in the system now)

I have my Hue mobile app in parallel, and it seems that something is moving in the hue app, but lights to no change consistently when I select full floor. If I select single lamp only, and slowly rotate the tap, there is a slow movement.

I’m using HA Green, if that matters with Z2M adapter.

Thank You for this blueprints. It makes the automation very easy.
Can you help me?

On one button i have a LED-Strip:

  • button single press: Strip on / select stripe
  • button hold: Strip off
  • rotate clockwise: brightness_increase
  • rotate counter clockwise: brightness_decrease

now i want on button double press change the color of the strip, how can i do this?

@sowingseeds - what do you mean with the thought pointer 2?

@tilz0R Did you configure both helpers? And do they update correctly? I’m particularly interested in the ‘last pressed’ helper. Can you check in the developer tools from HA if the state of the last pressed helper correctly changes to the button you press?

@sky88 How exactly do you foresee to change the color after the double press? I’d recommend against changing the color of a strip without a visual indicator or a fixed ‘list’ of preconfigured colors that you would like to cycle to (which requires templating)

Helpers work fine. I realized that the issue is at Hue side, not at the implementation side. Blueprint works perfectly for me.

But if I use the rotation for brightness control, there are too many events sent to hue and then lights don’t really control brightness in a smooth way. You have to slowly move the rotation, one by one.

1 Like

hello! i really like the idea of this automation but i’m having a few troubles. i think everything is set up correctly but it appears to me that each button press is being received twice by the automation. I can’t get the single button press automation to run from the button, but if i test it from the automation config it works fine.

When i check the counter it does indeed count a single press as 2 and a double press as 4. i thought during my reading before installing this i read of someone having similar issues and i think the fix was to recreate the counter - i tried that and its still double counting.

i also find the increase in brightness a bit rough, but i’m sure i can find a way to work around that.

appreciate any tips on fixing this - cheers

Yes, that is correct. We’ve also noticed this difference in behaviour between various rotary controls (for example between the hue tap dial and the IKEA symfonisk sound controller and how they communicate with MQTT.

At high level, the difference is that the IKEA controller sends an individual command for each ‘rotary step’ whereas the Hue tap dial switch identifies a fast rotation as a repeating rotation and then it sends a separate attribute with the degrees of rotation.

Did you also follow the subsequent fix that @jriggit found:

Did you also follow the subsequent fix that @jriggit found:

i did not but i’m not really sure how to do that. i guess i need to edit the file under config\blueprints\automation\fleeman\ - do i just find and replace >1 with >2?