Zigbee2MQTT enOcean PTM 215Z (Friends of Hue) switch

Have a look at my post to get the most of the Zigbee2MQTT way

Did you have a look at your logbook after pressing a button ? Sometimes, you think your press button 1 and you press 1 and 3 together… It is a known issue.
I do use this blueprint since a year without any issue at all.

An other point to check is how you paired your switch to your network. Did use the “permit join all” or “permit join specific device”. Have a look there Green Power Devices.

Based on the nice work of @vandalon, I have been able to create a functional blueprint for the PTM216Z.

blueprint:
  name: Controller - EnOcean PTM 216Z switch
  description:
    "
    Controller automation for executing press/hold/release after hold actions triggered by EnOcean PTM 216Z switch.
    \n\n
    Make sure that **Elapsed** is enabled in the z2m advanced settings.
    \n\n
    Make sure to manually create a separate **Text Helper** per controller and define its entity in the automation. It's used to store the last controller event to filter possible
    empty events and handle 'button hold' actions.
    \n\n
    This blueprint is mainly based on the hard work of @vandalon and his great blueprint for the PTM 215Z (Friend of Hue).
    "
  domain: automation
  input:
    controller:
      name: (Zigbee2MQTT) Controller Name
      description: The name of the controller as defined in z2m (e.g. Livingroom Switch)
      default: ""
    base_topic:
      name: (Zigbee2MQTT) Base mqtt topic
      description: The base topic as configured in z2m
      default: zigbee2mqtt
    helper_last_controller_event:
      name: (Required) Helper - Last Controller Event
      description:
        Input Text used to store the last event fired by the controller.
        You will need to manually create a text input Helper entity for this.
      default: ""
      selector:
        entity:
          domain: input_text
          multiple: false
    hold_delay:
      name: Hold delay
      description: If the button has been held more than the configured Hold delay, the corresponding held action is triggered.
      default: 500
      selector:
        number:
          min: 100.0
          max: 1000.0
          unit_of_measurement: milliseconds
          mode: box
          step: 10.0
    button_1_pressed:
      name: Button 1 Pressed
      description: Action to run, when button 1 is pressed.
      default: []
      selector:
        action: {}
    button_1_held:
      name: Button 1 Held
      description: Action to run, when the button 1 is held.
      default: []
      selector:
        action: {}
    button_1_released:
      name: Button 1 released
      description: Action to run, when the button 1 is released after long press.
      default: []
      selector:
        action: {}
    button_2_pressed:
      name: Button 2 Pressed
      description: Action to run, when the button 2 pressed.
      default: []
      selector:
        action: {}
    button_2_held:
      name: Button 2 Held
      description: Action to run, when the button 2 is held.
      default: []
      selector:
        action: {}
    button_2_released:
      name: Button 2 released
      description: Action to run, when the button 2 is released after long press.
      default: []
      selector:
        action: {}
    button_3_pressed:
      name: Button 3 Pressed
      description: Action to run, when the button 3 is pressed.
      default: []
      selector:
        action: {}
    button_3_held:
      name: Button 3 Held
      description: Action to run, when the button 3 is held.
      default: []
      selector:
        action: {}
    button_3_released:
      name: Button 3 released
      description: Action to run, when the button 3 is released after long press.
      default: []
      selector:
        action: {}
    button_4_pressed:
      name: Button 4 Pressed
      description: Action to run, when the button 4 is pressed.
      default: []
      selector:
        action: {}
    button_4_held:
      name: Button 4 Held
      description: Action to run, when the button 4 is held.
      default: []
      selector:
        action: {}
    button_4_released:
      name: Button 4 released
      description: Action to run, when the button 4 is released after long press.
      default: []
      selector:
        action: {}
    button_1_and_3_pressed:
      name: Button 1 and 3 Pressed
      description: Action to run, when buttons 1 and 3 are pressed.
      default: []
      selector:
        action: {}
    button_1_and_3_held:
      name: Button 1 and 3 Held
      description: Action to run, when buttons 1 and 3 are held.
      default: []
      selector:
        action: {}
    button_1_and_3_released:
      name: Button 1 and 3 released
      description: Action to run, when buttons 1 and 3 are released after long press.
      default: []
      selector:
        action: {}
    button_2_and_4_pressed:
      name: Button 2 and 4 Pressed
      description: Action to run, when buttons 2 and 4 are pressed.
      default: []
      selector:
        action: {}
    button_2_and_4_held:
      name: Button 2 and 4 Held
      description: Action to run, when buttons 2 and 4 are is held.
      default: []
      selector:
        action: {}
    button_2_and_4_released:
      name: Button 2 and 4 released
      description: Action to run, when buttons 2 and 4 are is released after long press.
      default: []
      selector:
        action: {}
#  source_url:
mode: restart
max_exceeded: silent
variables:
  hold_delay: !input hold_delay
trigger_variables:
  base_topic: !input base_topic
  controller: !input controller
trigger:
  - platform: mqtt
    topic: '{{ base_topic ~ "/" ~ controller }}'
condition:
# This line is to avoid a warning at startup only
  - '{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.zigbee2mqtt_bridge_connection_state.last_changed)
      | int > 40 }}'
  - '{{ ("release" in trigger.payload_json.action and trigger.payload_json.elapsed is defined)
        or "press_" in trigger.payload_json.action }}'
action:
  - variables:
      controller: !input controller
      helper_last_controller_event: !input helper_last_controller_event
      command: '{{ trigger.payload_json.action }}'
      prev_command: '{{ states(helper_last_controller_event) }}'
  - service: input_text.set_value
    data:
      entity_id: !input helper_last_controller_event
      value: "{{ command }}"
  - choose:
      - conditions: '{{ "release" in trigger.payload_json.action and trigger.payload_json.elapsed | int < hold_delay }}'
        sequence:
          - choose:
              - conditions: 
                  - '{{ command == "release" and prev_command == "press_1" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_1_pressed
              - conditions:
                  - '{{ command == "release" and prev_command == "press_2" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_2_pressed
              - conditions:
                  - '{{ command == "release" and prev_command == "press_3" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_3_pressed
              - conditions:
                  - '{{ command == "release" and prev_command == "press_4" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_4_pressed
              - conditions:
                  - '{{ command == "release" and prev_command == "press_1_and_3" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_1_and_3_pressed
              - conditions:
                  - '{{ command == "release" and prev_command == "press_2_and_4" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_2_and_4_pressed
      - conditions: '{{ "press_" | string in trigger.payload_json.action }}'
        sequence:
          - delay:
              milliseconds: !input hold_delay
          - choose:
              - conditions: '{{ trigger.payload_json.action == "press_1" }}'
                sequence: !input button_1_held
              - conditions: '{{ trigger.payload_json.action == "press_2" }}'
                sequence: !input button_2_held
              - conditions: '{{ trigger.payload_json.action == "press_3" }}'
                sequence: !input button_3_held
              - conditions: '{{ trigger.payload_json.action == "press_4" }}'
                sequence: !input button_4_held
              - conditions: '{{ trigger.payload_json.action == "press_1_and_3" }}'
                sequence: !input button_1_and_3_held
              - conditions: '{{ trigger.payload_json.action == "press_2_and_4" }}'
                sequence: !input button_2_and_4_held
      - conditions:
          - '{{ "release" in trigger.payload_json.action and trigger.payload_json.elapsed | int > hold_delay }}'
        sequence:
          - choose:
              - conditions: 
                  - '{{ command == "release" and prev_command == "press_1" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_1_released
              - conditions:
                  - '{{ command == "release" and prev_command == "press_2" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_2_released
              - conditions:
                  - '{{ command == "release" and prev_command == "press_3" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_3_released
              - conditions:
                  - '{{ command == "release" and prev_command == "press_4" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_4_released
              - conditions:
                  - '{{ command == "release" and prev_command == "press_1_and_3" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_1_and_3_released
              - conditions:
                  - '{{ command == "release" and prev_command == "press_2_and_4" }}'
                  - '{{ trigger.payload_json.action == "release" }}'
                sequence: !input button_2_and_4_released

Well,

is a bit generous. It “compiles” but it doesn’t run as expected.
First of all you check for command = "release", which it will never be. It wil be like release_1. So each release action will never trigger.
Furthermore you added the command variable (:+1:), used it to compare but additionally compare to the payload as well. Once compare would be enough :wink:

I have not yet deployed one of those switches long term, that’s why im not sure if your text helper apprach is actually useful tbh.

But anyways, here is your blueprint, but fixed
blueprint:
  name: Controller - EnOcean PTM 216Z switch
  description:
    "
    Controller automation for executing press/hold/release after hold actions triggered by EnOcean PTM 216Z switch.
    \n\n
    Make sure that **Elapsed** is enabled in the z2m advanced settings.
    \n\n
    Make sure to manually create a separate **Text Helper** per controller and define its entity in the automation. It's used to store the last controller event to filter possible
    empty events and handle 'button hold' actions.
    \n\n
    This blueprint is mainly based on the hard work of @vandalon and his great blueprint for the PTM 215Z (Friend of Hue).
    "
  domain: automation
  input:
    controller:
      name: (Zigbee2MQTT) Controller Name
      description: The name of the controller as defined in z2m (e.g. Livingroom Switch)
      default: ""
    base_topic:
      name: (Zigbee2MQTT) Base mqtt topic
      description: The base topic as configured in z2m
      default: zigbee2mqtt
    helper_last_controller_event:
      name: (Required) Helper - Last Controller Event
      description:
        Input Text used to store the last event fired by the controller.
        You will need to manually create a text input Helper entity for this.
      default: ""
      selector:
        entity:
          domain: input_text
          multiple: false
    hold_delay:
      name: Hold delay
      description: If the button has been held more than the configured Hold delay, the corresponding held action is triggered.
      default: 500
      selector:
        number:
          min: 100.0
          max: 1000.0
          unit_of_measurement: milliseconds
          mode: box
          step: 10.0
    button_1_pressed:
      name: Button 1 Pressed
      description: Action to run, when button 1 is pressed.
      default: []
      selector:
        action: {}
    button_1_held:
      name: Button 1 Held
      description: Action to run, when the button 1 is held.
      default: []
      selector:
        action: {}
    button_1_released:
      name: Button 1 released
      description: Action to run, when the button 1 is released after long press.
      default: []
      selector:
        action: {}
    button_2_pressed:
      name: Button 2 Pressed
      description: Action to run, when the button 2 pressed.
      default: []
      selector:
        action: {}
    button_2_held:
      name: Button 2 Held
      description: Action to run, when the button 2 is held.
      default: []
      selector:
        action: {}
    button_2_released:
      name: Button 2 released
      description: Action to run, when the button 2 is released after long press.
      default: []
      selector:
        action: {}
    button_3_pressed:
      name: Button 3 Pressed
      description: Action to run, when the button 3 is pressed.
      default: []
      selector:
        action: {}
    button_3_held:
      name: Button 3 Held
      description: Action to run, when the button 3 is held.
      default: []
      selector:
        action: {}
    button_3_released:
      name: Button 3 released
      description: Action to run, when the button 3 is released after long press.
      default: []
      selector:
        action: {}
    button_4_pressed:
      name: Button 4 Pressed
      description: Action to run, when the button 4 is pressed.
      default: []
      selector:
        action: {}
    button_4_held:
      name: Button 4 Held
      description: Action to run, when the button 4 is held.
      default: []
      selector:
        action: {}
    button_4_released:
      name: Button 4 released
      description: Action to run, when the button 4 is released after long press.
      default: []
      selector:
        action: {}
    button_1_and_3_pressed:
      name: Button 1 and 3 Pressed
      description: Action to run, when buttons 1 and 3 are pressed.
      default: []
      selector:
        action: {}
    button_1_and_3_held:
      name: Button 1 and 3 Held
      description: Action to run, when buttons 1 and 3 are held.
      default: []
      selector:
        action: {}
    button_1_and_3_released:
      name: Button 1 and 3 released
      description: Action to run, when buttons 1 and 3 are released after long press.
      default: []
      selector:
        action: {}
    button_2_and_4_pressed:
      name: Button 2 and 4 Pressed
      description: Action to run, when buttons 2 and 4 are pressed.
      default: []
      selector:
        action: {}
    button_2_and_4_held:
      name: Button 2 and 4 Held
      description: Action to run, when buttons 2 and 4 are is held.
      default: []
      selector:
        action: {}
    button_2_and_4_released:
      name: Button 2 and 4 released
      description: Action to run, when buttons 2 and 4 are is released after long press.
      default: []
      selector:
        action: {}
#  source_url:
mode: restart
max_exceeded: silent
variables:
  hold_delay: !input hold_delay
trigger_variables:
  base_topic: !input base_topic
  controller: !input controller
trigger:
  - platform: mqtt
    topic: '{{ base_topic ~ "/" ~ controller }}'
condition:
# This line is to avoid a warning at startup only
  - '{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.zigbee2mqtt_bridge_connection_state.last_changed)
      | int > 40 }}'
  - '{{ ("release" in trigger.payload_json.action and trigger.payload_json.elapsed is defined)
        or "press_" in trigger.payload_json.action }}'
action:
  - variables:
      controller: !input controller
      helper_last_controller_event: !input helper_last_controller_event
      command: '{{ trigger.payload_json.action }}'
      prev_command: '{{ states(helper_last_controller_event) }}'
  - service: input_text.set_value
    data:
      entity_id: !input helper_last_controller_event
      value: "{{ command }}"
  - choose:
      - conditions: '{{ "release" in command and trigger.payload_json.elapsed | int < hold_delay }}'
        sequence:
          - choose:
              - conditions: 
                  - '{{ command == "release_1" and prev_command == "press_1" }}'
                sequence: !input button_1_pressed
              - conditions:
                  - '{{ command == "release_2" and prev_command == "press_2" }}'
                sequence: !input button_2_pressed
              - conditions:
                  - '{{ command == "release_3" and prev_command == "press_3" }}'
                sequence: !input button_3_pressed
              - conditions:
                  - '{{ command == "release_4" and prev_command == "press_4" }}'
                sequence: !input button_4_pressed
              - conditions:
                  - '{{ command == "release_1_and_3" and prev_command == "press_1_and_3" }}'
                sequence: !input button_1_and_3_pressed
              - conditions:
                  - '{{ command == "release_2_and_4" and prev_command == "press_2_and_4" }}'
                sequence: !input button_2_and_4_pressed
      - conditions: '{{ "press_" | string in command }}'
        sequence:
          - delay:
              milliseconds: !input hold_delay
          - choose:
              - conditions: '{{ command == "press_1" }}'
                sequence: !input button_1_held
              - conditions: '{{ command == "press_2" }}'
                sequence: !input button_2_held
              - conditions: '{{ command == "press_3" }}'
                sequence: !input button_3_held
              - conditions: '{{ command == "press_4" }}'
                sequence: !input button_4_held
              - conditions: '{{ command == "press_1_and_3" }}'
                sequence: !input button_1_and_3_held
              - conditions: '{{ command == "press_2_and_4" }}'
                sequence: !input button_2_and_4_held
      - conditions:
          - '{{ "release" in command and trigger.payload_json.elapsed | int > hold_delay }}'
        sequence:
          - choose:
              - conditions: 
                  - '{{ command == "release_1" and prev_command == "press_1" }}'
                sequence: !input button_1_released
              - conditions:
                  - '{{ command == "release_2" and prev_command == "press_2" }}'
                sequence: !input button_2_released
              - conditions:
                  - '{{ command == "release_3" and prev_command == "press_3" }}'
                sequence: !input button_3_released
              - conditions:
                  - '{{ command == "release_4" and prev_command == "press_4" }}'
                sequence: !input button_4_released
              - conditions:
                  - '{{ command == "release_1_and_3" and prev_command == "press_1_and_3" }}'
                sequence: !input button_1_and_3_released
              - conditions:
                  - '{{ command == "release_2_and_4" and prev_command == "press_2_and_4" }}'
                sequence: !input button_2_and_4_released

Well,

It was not the best place to post I do agree.

Some people asked for a working blueprint for the PTM216Z which does not behave the same as the PTM215Z.

PTM216Z is not sending a release_1 or something else but only a release command. See Zigbee2mqtt device page. This explains why there is a need to compare the previous command. Any update of my code is really appreciated anyway.

To avoid the “helper” I created this version.

blueprint:
  name: Zigbee2mqtt - EnOcean  Simpel PTM 215Z (Friends of Hue) blueprint
  description: Using HA triggers
  domain: automation
  input:
    switch:
      name: HA device name, action entity
      description: If more switches share same functionality, you can choose 2 or more
      selector:
        entity:
          integration: mqtt
          domain: sensor
          multiple: true  
    hold_delay:
      name: Hold delay (seconds)
      description: If the button has been held more than the configured Hold delay,
        the corresponding long release action will be triggered
      default: 1
      selector:
        number:
          min: 1
          max: 4
          unit_of_measurement: seconds
          step: 1
    button_1_press:
      name: Button 1 Pressed (upper left)
      description: Action to run, when button 1 is pressed.
      default: []
      selector:
        action: {}
    button_1_short_release:
      name: Button 1 short released (upper left)
      description: Action to run, when the button 1 is released after short pres.
      default: []
      selector:
        action: {}
    button_1_long_release:
      name: Button 1 long released (upper left)
      description: Action to run, when the button 1 is released after long press.
      default: []
      selector:
        action: {}

    button_2_press:
      name: Button 2 Pressed (lower left)
      description: Action to run, when button 2 is pressed.
      default: []
      selector:
        action: {}
    button_2_short_release:
      name: Button 2 short released (lower left)
      description: Action to run, when the button 2 is released after short press.
      default: []
      selector:
        action: {}
    button_2_long_release:
      name: Button 2 long released (lower left)
      description: Action to run, when the button 2 is released after long press.
      default: []
      selector:
        action: {}

    button_3_press:
      name: Button 3 Pressed (upper right)
      description: Action to run, when button 3 is pressed.
      default: []
      selector:
        action: {}
    button_3_short_release:
      name: Button 3 short released (upper right)
      description: Action to run, when the button 3 is released after short press.
      default: []
      selector:
        action: {}
    button_3_long_release:
      name: Button 3 long released (upper right)
      description: Action to run, when the button 3 is released after long press.
      default: []
      selector:
        action: {}

    button_4_press:
      name: Button 4 Pressed (lower right)
      description: Action to run, when button 4 is pressed.
      default: []
      selector:
        action: {}
    button_4_short_release:
      name: Button 4 short released (lower right)
      description: Action to run, when the button 4 is released after short press.
      default: []
      selector:
        action: {}
    button_4_long_release:
      name: Button 4 long released (lower right)
      description: Action to run, when the button 4 is released after long press.
      default: []
      selector:
        action: {}

mode: restart
max_exceeded: silent

trigger:
  - platform: state
    entity_id: !input 'switch'
    to:
      - release_1
      - release_2
      - release_3
      - release_4
      - press_1
      - press_2
      - press_3
      - press_4

action:
- variables:
    keypress: '{{ trigger.to_state.state }}'
    holddelay: !input 'hold_delay'
    timediff: >-
      {{ (trigger.to_state.last_changed -
      trigger.from_state.last_changed).total_seconds() }}

- choose:
  - conditions: '{{ keypress == ''press_1'' }}'
    sequence: !input button_1_press

  - conditions: '{{ keypress == ''press_2'' }}'
    sequence: !input button_2_press

  - conditions: '{{ keypress == ''press_3'' }}'
    sequence: !input button_3_press

  - conditions: '{{ keypress == ''press_4'' }}'
    sequence: !input button_4_press

  - conditions: '{{ keypress == ''release_1'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_1_long_release
      default:
      - sequence: !input button_1_short_release

  - conditions: '{{ keypress == ''release_2'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_2_long_release
      default:
      - sequence: !input button_2_short_release

  - conditions: '{{ keypress == ''release_3'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_3_long_release
      default:
      - sequence: !input button_3_short_release

  - conditions: '{{ keypress == ''release_4'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_4_long_release
      default:
      - sequence: !input button_4_short_release




1 Like

Thanks for the Blueprint!
Could you please add the “pressed 1 and 3” and “pressed 2 and 4” functions aswell? :slight_smile:

Did not know that was a possibility. Will have a look

Nice thanks!
You can find it in the OP here: gist.githubusercontent.com/vandalon/d2a327297d579b304549e96c66765992/raw/cead3c14d46c66a73667e38241ac8c087a831dcc/z2m%2520EnOcean%2520PTM%2520215Z%2520(Friends%2520of%2520Hue)%2520switch.yaml

One more update. Without helper and including key 1+3 and key 2+4.

blueprint:
  name: Zigbee2mqtt - EnOcean  Simpel PTM 215Z (Friends of Hue) blueprint
  description: Using HA triggers
  domain: automation
  input:
    switch:
      name: HA device name, action entity
      description: If more switches share same functionality, you can choose 2 or more
      selector:
        entity:
          integration: mqtt
          domain: sensor
          multiple: true  
    hold_delay:
      name: Hold delay (seconds)
      description: If the button has been held more than the configured Hold delay,
        the corresponding long release action will be triggered
      default: 1
      selector:
        number:
          min: 1
          max: 4
          unit_of_measurement: seconds
          step: 1
    button_1_press:
      name: Button 1 Pressed (upper left)
      description: Action to run, when button 1 is pressed.
      default: []
      selector:
        action: {}
    button_1_short_release:
      name: Button 1 short released (upper left)
      description: Action to run, when the button 1 is released after short pres.
      default: []
      selector:
        action: {}
    button_1_long_release:
      name: Button 1 long released (upper left)
      description: Action to run, when the button 1 is released after long press.
      default: []
      selector:
        action: {}

    button_2_press:
      name: Button 2 Pressed (lower left)
      description: Action to run, when button 2 is pressed.
      default: []
      selector:
        action: {}
    button_2_short_release:
      name: Button 2 short released (lower left)
      description: Action to run, when the button 2 is released after short press.
      default: []
      selector:
        action: {}
    button_2_long_release:
      name: Button 2 long released (lower left)
      description: Action to run, when the button 2 is released after long press.
      default: []
      selector:
        action: {}

    button_3_press:
      name: Button 3 Pressed (upper right)
      description: Action to run, when button 3 is pressed.
      default: []
      selector:
        action: {}
    button_3_short_release:
      name: Button 3 short released (upper right)
      description: Action to run, when the button 3 is released after short press.
      default: []
      selector:
        action: {}
    button_3_long_release:
      name: Button 3 long released (upper right)
      description: Action to run, when the button 3 is released after long press.
      default: []
      selector:
        action: {}

    button_4_press:
      name: Button 4 Pressed (lower right)
      description: Action to run, when button 4 is pressed.
      default: []
      selector:
        action: {}
    button_4_short_release:
      name: Button 4 short released (lower right)
      description: Action to run, when the button 4 is released after short press.
      default: []
      selector:
        action: {}
    button_4_long_release:
      name: Button 4 long released (lower right)
      description: Action to run, when the button 4 is released after long press.
      default: []
      selector:
        action: {}

    button_13_press:
      name: Button 1 and 3 Pressed (lower right)
      description: Action to run, when button 1 and 3 is pressed.
      default: []
      selector:
        action: {}
    button_13_short_release:
      name: Button 1 and 3 short released (lower right)
      description: Action to run, when the button 1 and 3 is released after short press.
      default: []
      selector:
        action: {}
    button_13_long_release:
      name: Button 1 and 3 long released (lower right)
      description: Action to run, when the button 1 and 3 is released after long press.
      default: []
      selector:
        action: {}

    button_24_press:
      name: Button 2 and 4 Pressed (lower right)
      description: Action to run, when button 1 and 3 is pressed.
      default: []
      selector:
        action: {}
    button_24_short_release:
      name: Button 2 and 4 short released (lower right)
      description: Action to run, when the button 1 and 3 is released after short press.
      default: []
      selector:
        action: {}
    button_24_long_release:
      name: Button 2 and 4 long released (lower right)
      description: Action to run, when the button 1 and 3 is released after long press.
      default: []
      selector:
        action: {}

mode: restart
max_exceeded: silent
trace:
  stored_traces: 20

trigger:
  - platform: state
    entity_id: !input 'switch'
    to:
      - release_1
      - release_2
      - release_3
      - release_4
      - release_1_and_3
      - release_2_and_4
      - press_1
      - press_2
      - press_3
      - press_4
      - press_1_and_3
      - press_2_and_4

action:
- variables:
    keypress: '{{ trigger.to_state.state }}'
    holddelay: !input 'hold_delay'
    timediff: >-
      {{ (trigger.to_state.last_changed -
      trigger.from_state.last_changed).total_seconds() }}

- choose:
  - conditions: '{{ keypress == ''press_1'' }}'
    sequence: !input button_1_press

  - conditions: '{{ keypress == ''press_2'' }}'
    sequence: !input button_2_press

  - conditions: '{{ keypress == ''press_3'' }}'
    sequence: !input button_3_press

  - conditions: '{{ keypress == ''press_4'' }}'
    sequence: !input button_4_press

  - conditions: '{{ keypress == ''press_1_and_3'' }}'
    sequence: !input button_13_press

  - conditions: '{{ keypress == ''press_2_and_4'' }}'
    sequence: !input button_24_press

  - conditions: '{{ keypress == ''release_1'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_1_long_release
      default:
      - sequence: !input button_1_short_release

  - conditions: '{{ keypress == ''release_2'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_2_long_release
      default:
      - sequence: !input button_2_short_release

  - conditions: '{{ keypress == ''release_3'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_3_long_release
      default:
      - sequence: !input button_3_short_release

  - conditions: '{{ keypress == ''release_4'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_4_long_release
      default:
      - sequence: !input button_4_short_release

  - conditions: '{{ keypress == ''release_1_and_3'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_13_long_release
      default:
      - sequence: !input button_13_short_release

  - conditions: '{{ keypress == ''release_2_and_4'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay) }}'
        sequence: !input button_24_long_release
      default:
      - sequence: !input button_24_short_release


2 Likes

Hi, thank you for this blueprint, im figuring out what to use when holding a button to keep increasing or decreasing the brightness till you release the button, just like when you have them connected to hue itself.

This can be achived, I actually had a working version some time ago. I will find it again, and post here.

It was not a perfect setup,.

  1. the dimming effect was not smooth, at least not for my liking
  2. as the switch will go into “pairing mode” after you press a button more than 7 seconds, my kids was constantly breaking the setup. How Hue is solving this part I do not know.
1 Like

Here is the blueprint with a “Hue style dimming posibility”. It works, however with the above mentioned problems. Any suggestions on how to make it better is welcome.

The dimming +/- is done suing the “action.light.on” and set the “precentage change”. Easily done in the GUI

blueprint:
  name: Zigbee2mqtt - EnOcean PTM 215Z (Friends of Hue) switch (Hue Dimming Version)
  description: Using HA triggers, Own version
  domain: automation
  input:
    switch:
      name: HA device name, action entity
      description: If more switches share same functionality, you can choose 2 or more
      selector:
        entity:
          integration: mqtt
          domain: sensor
          multiple: true  
    hold_delay:
      name: Hold delay
      description: If the button has been held more than the configured Hold delay,
        the corresponding repeat action will be triggered
      default: 1000
      selector:
        number:
          min: 300
          max: 3000
          unit_of_measurement: milliseconds
          step: 100
    repeat_delay:
      name: Repeat delay
      description: If the button has been held more than the configured Hold delay,
        time between repeated actions
      default: 1000
      selector:
        number:
          min: 300
          max: 3000
          unit_of_measurement: milliseconds
          step: 100
    repeat_number:
      name: Repeat Number
      description: If the button has been held more than the configured Hold delay,
        Maximum repeated actions.
      default: 1
      selector:
        number:
          min: 1
          max: 100
          step: 1

    button_1_press:
      name: Button 1 Pressed (upper left)
      description: Action to run, when button 1 is pressed.
      default: []
      selector:
        action: {}
    button_1_repeat:
      name: Button 1 Repeted action (upper left)
      description: Action to repeat, when the button 1 is held.
      default: []
      selector:
        action: {}
    button_1_short_release:
      name: Button 1 short released (upper left)
      description: Action to run, when the button 1 is released after short pres.
      default: []
      selector:
        action: {}
    button_1_long_release:
      name: Button 1 long released (upper left)
      description: Action to run, when the button 1 is released after long press.
      default: []
      selector:
        action: {}

    button_2_press:
      name: Button 2 Pressed (lower left)
      description: Action to run, when button 2 is pressed.
      default: []
      selector:
        action: {}
    button_2_repeat:
      name: Button 2 Repeted action (lower left)
      description: Action to repeat, when the button 2 is held.
      default: []
      selector:
        action: {}
    button_2_short_release:
      name: Button 2 short released (lower left)
      description: Action to run, when the button 2 is released after short press.
      default: []
      selector:
        action: {}
    button_2_long_release:
      name: Button 2 long released (lower left)
      description: Action to run, when the button 2 is released after long press.
      default: []
      selector:
        action: {}

    button_3_press:
      name: Button 3 Pressed (upper right)
      description: Action to run, when button 3 is pressed.
      default: []
      selector:
        action: {}
    button_3_repeat:
      name: Button 3 Repeted action (upper right)
      description: Action to repeat, when the button 3 is held.
      default: []
      selector:
        action: {}
    button_3_short_release:
      name: Button 3 short released (upper right)
      description: Action to run, when the button 3 is released after short press.
      default: []
      selector:
        action: {}
    button_3_long_release:
      name: Button 3 long released (upper right)
      description: Action to run, when the button 3 is released after long press.
      default: []
      selector:
        action: {}

    button_4_press:
      name: Button 4 Pressed (lower right)
      description: Action to run, when button 4 is pressed.
      default: []
      selector:
        action: {}
    button_4_repeat:
      name: Button 4 Repeted action (lower right)
      description: Action to repeat, when the button 4 is held.
      default: []
      selector:
        action: {}
    button_4_short_release:
      name: Button 4 short released (lower right)
      description: Action to run, when the button 4 is released after short press.
      default: []
      selector:
        action: {}
    button_4_long_release:
      name: Button 4 long released (lower right)
      description: Action to run, when the button 4 is released after long press.
      default: []
      selector:
        action: {}

mode: restart
max_exceeded: silent

trigger:
  - platform: state
    entity_id: !input 'switch'
    to:
      - release_1
      - release_2
      - release_3
      - release_4
      - press_1
      - press_2
      - press_3
      - press_4

action:
- variables:
    keypress: '{{ trigger.to_state.state }}'
    holddelay: !input 'hold_delay'
    timediff: >-
      {{ (trigger.to_state.last_changed -
      trigger.from_state.last_changed).total_seconds() }}

- choose:
  - conditions: '{{ keypress == ''press_1'' }}'
    sequence: 
    - choose:
      - conditions: '{{ true }}'
        sequence: !input button_1_press
    - delay:
        milliseconds: !input hold_delay
    - repeat: 
        count: !input repeat_number
        sequence:
          - choose:
            - conditions: '{{ true }}'
              sequence: !input button_1_repeat
          - delay:
              milliseconds: !input repeat_delay

  - conditions: '{{ keypress == ''press_2'' }}'
    sequence: 
    - choose:
      - conditions: '{{ true }}'
        sequence: !input button_2_press
    - delay:
        milliseconds: !input hold_delay
    - repeat: 
        count: !input repeat_number
        sequence:
          - choose:
            - conditions: '{{ true }}'
              sequence: !input button_2_repeat
          - delay:
              milliseconds: !input repeat_delay

  - conditions: '{{ keypress == ''press_3'' }}'
    sequence: 
    - choose:
      - conditions: '{{ true }}'
        sequence: !input button_3_press
    - delay:
        milliseconds: !input hold_delay
    - repeat: 
        count: !input repeat_number
        sequence:
          - choose:
            - conditions: '{{ true }}'
              sequence: !input button_3_repeat
          - delay:
              milliseconds: !input repeat_delay

  - conditions: '{{ keypress == ''press_4'' }}'
    sequence: 
    - choose:
      - conditions: '{{ true }}'
        sequence: !input button_4_press
    - delay:
        milliseconds: !input hold_delay
    - repeat: 
        count: !input repeat_number
        sequence:
          - choose:
            - conditions: '{{ true }}'
              sequence: !input button_4_repeat
          - delay:
              milliseconds: !input repeat_delay


  - conditions: '{{ keypress == ''release_1'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay/1000) }}'
        sequence: !input button_1_long_release
      default:
      - choose:
        - conditions: '{{ true }}'
          sequence: !input button_1_short_release

  - conditions: '{{ keypress == ''release_2'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay/1000) }}'
        sequence: !input button_2_long_release
      default:
      - choose:
        - conditions: '{{ true }}'
          sequence: !input button_2_short_release

  - conditions: '{{ keypress == ''release_3'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay/1000) }}'
        sequence: !input button_3_long_release
      default:
      - choose:
        - conditions: '{{ true }}'
          sequence: !input button_3_short_release

  - conditions: '{{ keypress == ''release_4'' }}'
    sequence:
    - choose:
      - conditions: '{{ timediff > (holddelay/1000) }}'
        sequence: !input button_4_long_release
      default:
      - choose:
        - conditions: '{{ true }}'
          sequence: !input button_4_short_release




1 Like

i will give it a try, thank you.
About the smooth transition i found it to be the problem (zigbee2mqtt) within the settings of the light on the console from zigbee2mqtt i put transition to 1 sec for my lights and the dimming goes smooth.

I experience the same issue, very annoying. I have checked the lqi and it is 212, so the signal should be strong enough for a stable connection.
Found anyway around it?

most lights support dimming via MQTT directly, no need to manually loop / iterate dimming commands.
To start dimming, call once (as button held action):

service: mqtt.publish
data:
  topic: "zigbee2mqtt/Device Friendly Name/set"
  payload: '{"brightness_move_onoff": 50}'

where 50 is the speed of the dimming (negative numbers to dim down)

To stop dimming, call (as button release action):

service: mqtt.publish
data:
  topic: "zigbee2mqtt/Device Friendly Name/set"
  payload: '{"brightness_move": "stop"}'

CC @Peke @khvej8

1 Like

OK, next time I read the full message:-)

I will try during the weekend, and if working, then post here

@svkoch, been trying to get this to work. The dimming part works perfectly, however it do not “stop” when I fire the stop part. It continues to dim down. Im trying on a Hue bulb using Z2M. Any idea.

Here is my test automation.

alias: 0 Test MQTT dimming light
description: ""
trigger: []
condition: []
action:
  - action: light.turn_on
    metadata: {}
    data:
      brightness_pct: 100
    target:
      entity_id:
        - light.kokkenbord
  - delay:
      hours: 0
      minutes: 0
      seconds: 2
      milliseconds: 0
  - action: mqtt.publish
    data:
      topic: zigbee2mqtt/kokkenbord/set
      payload: "{\"brightness_move_onoff\": -50}"
  - delay:
      seconds: 3
  - action: mqtt.publish
    data:
      topic: zigbee2mqtt/kokkenbord/set
      payload: "{\"brightness_move\": stop}"
mode: single

If I can get the stop part to work, then it will be super easy to build into the blueprint. And it dims very smooth.

OK, found a easy workarround. I set the move to zero, then it stops dimming. Will create a blueprint during the weekend.

  - action: mqtt.publish
    data:
      topic: zigbee2mqtt/kokkenbord/set
      payload: "{\"brightness_move_onoff\": 0}"

payload: "{\"brightness_move\": \"stop\"}" or payload: '{"brightness_move": "stop"}'
wrap the stop as string and it works, just tried it

(forget that in the original message, edited it to fix that problem, thanks)

1 Like