Z2M - Philips Hue Tap Dial - Media Controls

Hi.

This blueprint supports controlling a media device and additional custom automations with a Philips Hue Tap Dial control. It is specific to Z2M.

Features of this blueprint:

  • Simple selection of a single media device to be controlled

  • User-specifiable volume steps - if your physical device uses a volume range other than 1-100, you can specify that range and this automation will scale incremental steps appropriately

  • The controller generates three rotation speed events : step, slow, and fast. This blueprint allows you to specify how many volume increments should be applied for each speed. You may, for example, set “step” to 1, slow to “3”, and fast to “5”. Because some volume ranges can result in rounding or truncation issues downstream of the automation, the blueprint allows these steps to be set as decimal values such as “1.5”

  • A short press of button 1 will toggle the play state of the target media device. Short presses of buttons 3 and 4 are, respectively, Previous Track and Next Track. The picture below illustrates this - apologies for the low quality of my homemade stickers

  • Short press of button 2 and long presses of all buttons are configurable automation sequences. Do whatever you like with them

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
# Media control via Philips Hue Tap Dial by gTunes
#
# Works only with Home Assistant and Zigbee2MQTT
# 
# Version History:
#   - v 0.1 Dec 2023 : Initial version
#
# Based on earlier work by:
#      - https://community.home-assistant.io/t/z2m-ikea-symfonisk-gen2-e2123-media-control-v1-53/559523 Shawsky
#      - https://gist.github.com/erkr/a437ebcb98a2b5ba2deebabd02f5ffae Eric Kreuwels
#      - https://gist.github.com/alexwmaustin/2c25cfa1a0ade1ab9fc1ef0940289672 Alex Austin

  name: Z2M - Philips Hue Tap Dial Media Control
  description: 
    'Control the selected media player (and any joined to it) with a Philips Hue Tap Dial controller via Zigbee2MQTT (Z2M)

    Supports volume control by rotating the dial 
    A single press of Button 1 is Toggle Play / Pause 
    Single presses of Buttons 3 and 4 are Previous Track and Next Track 
    Single press of button 2 is configurable as are long presses of all buttons'
  domain: automation
  input:
    remote:
      name: Remote
      description: The Philips Hue Tap Dial to use
      selector:
        device:
          integration: mqtt
          manufacturer: Philips
          model: Hue Tap dial switch (8719514440937/8719514440999)
          multiple: false
    base_topic:
      name: Zigbee2MQTT Base mqtt topic
      description: The base topic configured in Zigbee2MQTT. If you haven't changed this, leave the default here ("zigbee2mqtt")
      default: zigbee2mqtt
    media_player:
      name: Media Player
      description: The media player to control with this automation
      selector:
        entity:
          domain: media_player
          multiple: false
    volume_steps:
      name: Volume number of steps
      description: Controls the volume scale. Set this to the number of steps supported by your playback device
      default: 100
      selector:
        number:
          min: 5
          max: 100
          step: 1
          unit_of_measurement: "Num"
          mode: slider
    step_rotation_increments:
      name: "\"Step\" rotation volume increments"
      description: Number of volume increments for a "step" rotation event
      default: 1.0
      selector:
        number:
            min: 0.1
            max: 5.0
            step: 0.1
            unit_of_measurement: "Num"
            mode: slider
    slow_rotation_increments:
      name: "\"Slow\" rotation volume increments"
      description: Number of volume increments for a "slow" rotation event
      default: 2
      selector:
        number:
            min: 0.1
            max: 5.0
            step: 0.1
            unit_of_measurement: "Num"
            mode: slider
    fast_rotation_increments:
      name: "\"Fast\" rotation volume increments"
      description: Number of volume increments for a "fast" rotation event
      default: 3
      selector:
        number:
            min: 0.1
            max: 5.0
            step: 0.1
            unit_of_measurement: "Num"
            mode: slider
    button_1_hold:
      name: Button 1 (Long)
      description: Action to run on a long press of Button 1
      default: []
      selector: 
        action: {}
    button_2_short:
      name: Button 2 (Short)
      description: Action to run on a short press of Button 2
      default: []
      selector:
        action: {}
    button_2_hold:
      name: Button 2 (Long)
      description: Action to run on a long press of Button 2
      default: []
      selector: 
        action: {}
    button_3_hold:
      name: Button 3 (Long)
      description: Action to run on a long press of Button 3
      default: []
      selector: 
        action: {}
    button_4_hold:
      name: Button 4 (Long)
      description: Action to run on a long press of Button 4
      default: []
      selector: 
        action: {}
mode: restart
max_exceeded: silent

trigger_variables:
  base_topic: !input base_topic
  controller: !input remote

trigger:
  - platform: mqtt
    topic: "{{ base_topic }}/+/action"
action:
  - variables:
      controllertopic: "{{ base_topic }}/{{ device_attr(controller, 'name') }}/action"
      player: !input 'media_player'
      steps: !input volume_steps
      stepsize: '{{ 1.0 / steps }}'
      stepmultiplier: {
          'dial_rotate_right_step' : !input step_rotation_increments,
          'dial_rotate_left_step' : !input step_rotation_increments,
          'dial_rotate_right_slow' : !input slow_rotation_increments,
          'dial_rotate_left_slow' : !input slow_rotation_increments,
          'dial_rotate_right_fast' : !input fast_rotation_increments,
          'dial_rotate_left_fast' : !input fast_rotation_increments
      }
  - choose:
    - conditions:
      - "{{ trigger.payload != ''}}"
      - "{{ trigger.topic == controllertopic }}"
      sequence:
        - choose:
          ## Commands

          # Play / Pause
          - conditions: "{{ trigger.payload == 'button_1_press_release' }}"
            sequence:
            - service: media_player.media_play_pause
              entity_id: !input 'media_player'
          # Next Track
          - conditions: "{{ trigger.payload == 'button_4_press_release' }}"
            sequence:
            - service: media_player.media_next_track
              entity_id: !input 'media_player'
          # Previous Track
          - conditions: "{{ trigger.payload == 'button_3_press_release' }}"
            sequence:
            - service: media_player.media_previous_track
              entity_id: !input 'media_player'
          # Rotate Right (Volume Up)
          - conditions: "{{ trigger.payload in ['dial_rotate_right_step', 'dial_rotate_right_slow', 'dial_rotate_right_fast'] }}"
            sequence:
              - service: media_player.volume_set
                target:
                  entity_id: "{{ player }}"
                data:
                  volume_level: >-
                    {% set volume = state_attr(player, "volume_level") + (stepsize * stepmultiplier[trigger.payload]) %}
                    {{ 1.0 if volume > 1.0 else volume }}
           
          # Rotate Left (Volume Down)
          - conditions: "{{ trigger.payload in ['dial_rotate_left_step', 'dial_rotate_left_slow', 'dial_rotate_left_fast'] }}"
            sequence:
              - service: media_player.volume_set
                target:
                  entity_id: "{{ player }}"
                data:
                    volume_level: >-
                      {% set volume = state_attr(player, "volume_level") - (stepsize * stepmultiplier[trigger.payload]) %}
                      {{ 0.0 if volume < 0.0 else volume }}

          ## Actions
          # Button 1 Long Press
          - conditions: "{{ trigger.payload == 'button_1_hold' }}"
            sequence: !input button_1_hold
          # Button 2 Short Press
          - conditions: "{{ trigger.payload == 'button_2_press_release' }}"
            sequence: !input button_2_short
          # Button 2 Long Press
          - conditions: "{{ trigger.payload == 'button_2_hold' }}"
            sequence: !input button_2_hold
          # Button 3 Long Press
          - conditions: "{{ trigger.payload == 'button_3_hold' }}"
            sequence: !input button_3_hold
          # Button 4 Long Press
          - conditions: "{{ trigger.payload == 'button_4_hold' }}"
            sequence: !input button_4_hold

Setup:

Select your device, adjust your MQTT base topic if necessary, the choose the media_player to control.

Choose volume steps, increments, etc. and configure the custom sequences as desired.

Thanks to the creators of previous blueprints from which this is derived. They’re credited in the blueprint.

1 Like

Thank you very much. Please excuse the naive and slightly off topic question: What’s the default support of the Hue Tap Dial in HA and Z2M? I’m looking into purchasing a Tap Dial to control a light (rotate for dimming, buttons for on/off, color cycle, scene cycle) and am wondering if I can conveniently and easily configure all that myself in HA or if I’d need to spend hours fiddling with mqtt commands (which is something I never did before). Thanks!

Already replied to you in another thread, but this answers your specific question re support.

This site should be your go-to before buying any zigbee device - I suggest you bookmark it.

Thanks. I’m aware of that site and use it regularly. But even if a device exposes actions in mqtt this does not yet mean there’s a convenient way to configure the device in HA.

I will look into the blueprint you posted, thanks. I just think I’ve seen people mentioning last summer that a firmware update of the device broke compatibility with the currently available blueprints, which is why I assumed that a blueprint of 2022 does not work anymore for new devices (with a new firmware).

Don’t worry about it, it’ll work. I bought my Hue tap dials on Black Friday and used the blueprint around a month later with no issues whatsoever (Edit: even after updating the firmware on my test device).

1 Like