Zigbee2MQTT enOcean PTM 215Z (Friends of Hue) switch

Thanks a lot for this blueprint, i was pretty disapointed at first when i transferd my Niko FOH to Z2M at first.
This really makes it work the way i was used to.

Thanks for the blueprint. It works great! I wonder how I missed the quoted part in OP -_-

Where di you found the Elapsed function in Z2M settings?

EDIT: found it.

Hi, I’m wondering, is “hold” function no longer supported in HA-Z2M for this device/blueprint? I get only press and release actions.
br

Hold is still working on my side.

Hi Vandalon!

Thank you very much for this blueprint!

I have the hold function working and it’s great, can adjust the speed and hold delay, all good!
But! but but… :sweat_smile:

Is it somehow possible to have button_1 do, toggle on off, and dim up and down for 1 light source in a boolean or something? And in terms of the double and triple press, how is that for a challenge?

Then this could do the actuall toggle of a light source + dimming of it, and doublepress can be a scene that includes this ligts ex.

And then, it would be 4 sources with toggle + dimup/dimdown and double / triple press for scenes or turn off all etc.

br

Thanks for the blueprint! It’s working great for me.

One thing I will say. Echoing the comment above, if your lights support move via Zigbee2Mqtt it is a much better and smoother way of making the lights dim or brighten via the hold action.

For anyone looking to implement this. First, check if your lights support MOVE in the device information on Zigbee2Mqtt.

If they do, you can use the MQTT Publish service to send a move payload to the light(s). The payload can have a positive or negative value and can also be set to turn the light on if off or vice versa. You must also send a second payload on the release action. Some examples:

"brightness_move": 40, // Starts moving brightness up at 40 units per second
"brightness_move": -40, // Starts moving brightness down at 40 units per second
"brightness_move_onoff": 50  // turns light on if off and Increases brightness by 40
"brightness_move_onoff": -50  // Increases brightness by -50 and turns light off if on
"brightness_move": "stop", // Stop moving brightness

You must also find the Z2M topic, which is in the format:

zigbee2mqtt/FRIENDLY_NAME/set

This can either be an individual light or a Z2M light group.

An example from my own automation:

alias: Auto - Living Room Switch
description: ""
use_blueprint:
  path: vandalon/z2m EnOcean PTM 215Z (Friends of Hue) switch.yaml
  input:
    controller: Living Room Switch
    button_1_pressed:
      - service: light.turn_on
        data: {}
        target:
          entity_id: light.living_room_lights
    button_1_held:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Living Room Lights/set
          payload: "{\"brightness_move_onoff\": 51}"
          qos: 0
          retain: false
    button_1_released:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Living Room Lights/set
          payload: "{\"brightness_move\": \"stop\"}"
          qos: 0
          retain: false
    button_2_pressed:
      - service: light.turn_off
        data: {}
        target:
          device_id: 954f8699a96afa5436ba599fef2a3038
    button_2_held:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Living Room Lights/set
          payload: "{\"brightness_move_onoff\": -51}"
          qos: 0
          retain: false
    button_2_released:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Living Room Lights/set
          payload: "{\"brightness_move\": \"stop\"}"
          qos: 0
          retain: false

3 Likes

I’m working on doing this, if I understand your aim: making a version of @vandalon’s blueprint, but with minimal inputs: left buttons controls this entity, right side controls that entity, just for on/off/dim. Is that what you are trying to do?

I think I have figured out how - and can share the result and some notes if I get it working!

I happen to have e just done this exact thing. I’ll share it when I can :slight_smile:

Here is my blueprint for the FOH switches. Feedback more than welcome.

Features:

  • It allows you to specify a device per rocker and then use Brightness Move ZigBee2MQTT commands or home assistant on/off.
  • You can specify the action for both rockers to do the left and right action as well.

Requirements:

  • Elapsed is on in Zigbee2MQTT
  • MQTT topic is now hard-coded to the default

YAML:

Show all of the YAML
# ➡️ ⬅️ ⬆️ ⬇️ ↗️ ↘️ ↙️ ↖️

blueprint:
  name: Friends of Hue 2 wippen MQTT
  domain: automation
  description: Zigbee Green Power switches

  input:
    # Trigger settings
    device:
      name: Wippen
      selector:
        device:
          filter:
            - integration: mqtt
              model: "Pushbutton transmitter module (PTM 215Z)"
    device_name:
      name: De plaintext naam die Zigbee2MQTT gebruikt
      description: Precies wat hier boven ook staat
      selector:
        text:

    # Left rocker
    left_target_move:
      name: "⬅️ Linker target MQTT move"
      default: {}
      selector:
        target:
          entity:
            - domain: light
              integration: mqtt
    left_target_light:
      name: "⬅️ Linker target light"
      default: {}
      selector:
        target:
          entity:
            - domain: light
    left_target_switch:
      name: "⬅️ Linker target switch"
      default: {}
      selector:
        target:
          entity:
            - domain: switch

    left_top_press:
      name: "↖️ Links boven: indrukken"
      default: []
      selector:
        action:
    left_top_quick_release:
      name: "↖️ Links boven: snel weer loslaten"
      default: []
      selector:
        action:
    left_top_long_release:
      name: "↖️ Links boven: loslaten na ingedrukt te houden"
      default: []
      selector:
        action:

    left_bottom_press:
      name: "↙️ Links onder: indrukken"
      default: []
      selector:
        action:
    left_bottom_quick_release:
      name: "↙️ Links onder: snel weer loslaten"
      default: []
      selector:
        action:
    left_bottom_long_release:
      name: "↙️ Links onder: loslaten na ingedrukt te houden"
      default: []
      selector:
        action:

    # Right rocker
    right_target_move:
      name: "⬅️ Rechter target MQTT move"
      default: {}
      selector:
        target:
          entity:
            - domain: light
              integration: mqtt
    right_target_light:
      name: "⬅️ Rechter target light"
      default: {}
      selector:
        target:
          entity:
            - domain: light
    right_target_switch:
      name: "⬅️ Rechter target switch"
      default: {}
      selector:
        target:
          entity:
            - domain: switch

    right_top_press:
      name: "↗️ Rechts boven: indrukken"
      default: []
      selector:
        action:
    right_top_quick_release:
      name: "↗️ Rechts boven: snel weer loslaten"
      default: []
      selector:
        action:
    right_top_long_release:
      name: "↗️ Rechts boven: loslaten na ingedrukt te houden"
      default: []
      selector:
        action:

    right_bottom_press:
      name: "↘️ Rechts onder: indrukken"
      default: []
      selector:
        action:
    right_bottom_quick_release:
      name: "↘️ Rechts onder: snel weer loslaten"
      default: []
      selector:
        action:
    right_bottom_long_release:
      name: "↘️ Rechts onder: loslaten na ingedrukt te houden"
      default: []
      selector:
        action:

    # Both rockers

    both_also_triggers_individual_buttons:
      name: "↔️ Beide knoppen doen ook de acties van de linker en rechter wip. Hier naast doen ze de actie voor beide."
      default: false
      selector:
        boolean:
    
    both_target_move:
      name: "↔️ Beide target MQTT move"
      default: {}
      selector:
        target:
          entity:
            - domain: light
              integration: mqtt
    both_target_light:
      name: "↔️ Beide target light"
      default: {}
      selector:
        target:
          entity:
            - domain: light
    both_target_switch:
      name: "↔️ Beide target switch"
      default: {}
      selector:
        target:
          entity:
            - domain: switch
          
    both_top_press:
      name: "⬆️ Beide boven: indrukken"
      default: []
      selector:
        action:
    both_top_quick_release:
      name: "⬆️ Beide boven: snel weer loslaten"
      default: []
      selector:
        action:
    both_top_long_release:
      name: "⬆️ Beide boven: loslaten na ingedrukt te houden"
      default: []
      selector:
        action:
    
    both_bottom_press:
      name: "⬇️ Beide onder: indrukken"
      default: []
      selector:
        action:
    both_bottom_quick_release:
      name: "⬇️ Beide onder: snel weer loslaten"
      default: []
      selector:
        action:
    both_bottom_long_release:
      name: "⬇️ Beide onder: loslaten na ingedrukt te houden"
      default: []
      selector:
        action:

    # Trigger interpretation settings
    quick_release_timeout:
      name: Na hoe lang word het ingedrukt houden.
      default: 500
      selector:
        number:
          unit_of_measurement: Milliseconds
          min: 1
          max: 3000
          step: 50
          mode: slider

    # Action preferences
    move_speed:
      name: Move speed
      description: What speed should the actions use (when supported and included)
      default: 100
      selector:
        number:
          min: 1
          max: 255
          step: 5
          mode: slider

mode: parallel
max: 40

trigger_variables:
  device_name: !input device_name

trigger:
- platform: mqtt
  # To get the elapsed we need to get all device messages, as it is not in the `/action` payload
  topic: "{{ 'zigbee2mqtt/' ~ device_name}}"

condition: "{{ trigger.payload_json['action'] != '' }}"

variables:

  # Utility: for in script variables
  device: !input device
  device_name: !input device_name
  move_speed: !input move_speed
  
  both_also_triggers_individual_buttons: !input both_also_triggers_individual_buttons
  
  # Is this trigger less than the quick release time from the last one
  quick_release_timeout: !input quick_release_timeout
  trigger_elapsed: "{{ trigger.payload_json['elapsed'] }}"
  quick: "{{ trigger_elapsed <= quick_release_timeout }}"

  # What action is this
  action_id: "{{ trigger.payload_json['action'] }}"
  action_id_parts: "{{ action_id.split('_', 1) }}"
  action_name: "{{ action_id_parts[0] }}"
  press: "{{ action_name == 'press' }}"
  release: "{{ action_name == 'release' }}"
  quick_release: "{{ release and quick }}"
  long_release: "{{ release and not quick }}"

  # What button is this
  button_id: "{{ action_id_parts[1] }}"
  both: "{{ button_id in ['1_and_3','2_and_4'] }}"
  left: "{{ button_id in [1,2]  }}"
  right: "{{ button_id in [3,4]  }}"
  top: "{{ button_id in [1,3,'1_and_3'] }}"
  bottom: "{{ button_id in [2,4,'2_and_4'] }}"
  also: "{{ both and both_also_triggers_individual_buttons }}"
  button_x: "{{ 'top' if top else 'bottom' }}"
  button_y: "{{ 'left' if left}}{{ 'right' if right }}{{ 'both' if both }}"
  button: "{{ button_x ~ '_' ~ button_y }}"

action:
  
  # Emit an event for debugging or other automations to latch on to
  - event: foh-mqtt
    event_data:
      device_name: "{{ device_name }}"
      act: "{{ act }}"
      button: "{{ button }}"
      # trigger: "{{ trigger }}"

  - parallel:

    - if:
        - condition: template
          value_template: "{{ both }}"
      then:
        - variables:
            target_move: !input both_target_move
            target_move_list: >
              {% set data = namespace(list=[]) %}
              {% for key, value in target_move.items() %}
                {% if value is string %}
                  {% set data.list = data.list + [value] %}
                {% else %}
                  {% set data.list = data.list + value %}
                {% endif %}
              {% endfor %}
              {{ data.list }}
            move: "{{ target_move != {} }}"
            target_light: !input both_target_light
            light: "{{ target_light != {} }}"
            target_switch: !input both_target_switch
            switch: "{{ target_switch != {} }}"
        
        - parallel:

          - if:
            - condition: template
              value_template: "{{ move }}"
            then:
              - choose:
                - conditions: "{{ press }}"
                  sequence:
                    - repeat:
                        for_each: "{{ target_move_list }}"
                        sequence:
                          - service: mqtt.publish
                            data:
                              payload: "{\"brightness_move_onoff\": {{ '-' if bottom }}{{ move_speed}} }"
                              topic: "zigbee2mqtt/{{ state_attr(repeat.item, 'friendly_name') }}/set"
                - conditions: "{{ long_release }}"
                  sequence:
                    - repeat:
                        for_each: "{{ target_move_list }}"
                        sequence:
                          - service: mqtt.publish
                            data:
                              payload: "{\"brightness_move\": \"stop\"}"
                              topic: "zigbee2mqtt/{{ state_attr(repeat.item, 'friendly_name') }}/set"

          - if:
            - condition: template
              value_template: "{{ light }}"
            then:
              - choose:
                - conditions: "{{ light and press and top }}"
                  sequence:
                    - service: light.turn_on
                      target: !input both_target_light
                - conditions: "{{ light and press and bottom }}"
                  sequence:
                    - service: light.turn_off
                      target: !input both_target_light
          
          - if:
            - condition: template
              value_template: "{{ switch }}"
            then:
              - choose:
                - conditions: "{{ switch and press and top }}"
                  sequence:
                    - service: switch.turn_on
                      target: !input both_target_switch
                - conditions: "{{ switch and press and bottom }}"
                  sequence:
                    - service: switch.turn_off
                      target: !input both_target_switch

          - choose:
            - conditions: "{{ top and press }}"
              sequence: !input both_top_press
            - conditions: "{{ top and press }}"
              sequence: !input both_top_press
            - conditions: "{{ top and quick_release }}"
              sequence: !input both_top_quick_release
            - conditions: "{{ top and long_release }}"
              sequence: !input both_top_long_release
            - conditions: "{{ bottom and press }}"
              sequence: !input both_bottom_press
            - conditions: "{{ bottom and quick_release }}"
              sequence: !input both_bottom_quick_release
            - conditions: "{{ bottom and long_release }}"
              sequence: !input both_bottom_long_release

    - if:
        - condition: template
          value_template: "{{ left or also }}"
      then:
        - variables:
            target_move: !input left_target_move
            target_move_list: >
              {% set data = namespace(list=[]) %}
              {% for key, value in target_move.items() %}
                {% if value is string %}
                  {% set data.list = data.list + [value] %}
                {% else %}
                  {% set data.list = data.list + value %}
                {% endif %}
              {% endfor %}
              {{ data.list }}
            move: "{{ target_move != {} }}"
            target_light: !input left_target_light
            light: "{{ target_light != {} }}"
            target_switch: !input left_target_switch
            switch: "{{ target_switch != {} }}"
        
        - parallel:
        
          - if:
            - condition: template
              value_template: "{{ move }}"
            then:
              - choose:
                - conditions: "{{ press }}"
                  sequence:
                    - repeat:
                        for_each: "{{ target_move_list }}"
                        sequence:
                          - service: mqtt.publish
                            data:
                              payload: "{\"brightness_move_onoff\": {{ '-' if bottom }}{{ move_speed}} }"
                              topic: "zigbee2mqtt/{{ state_attr(repeat.item, 'friendly_name') }}/set"
                - conditions: "{{ long_release }}"
                  sequence:
                    - repeat:
                        for_each: "{{ target_move_list }}"
                        sequence:
                          - service: mqtt.publish
                            data:
                              payload: "{\"brightness_move\": \"stop\"}"
                              topic: "zigbee2mqtt/{{ state_attr(repeat.item, 'friendly_name') }}/set"

          - if:
            - condition: template
              value_template: "{{ light }}"
            then:
              - choose:
                - conditions: "{{ light and press and top }}"
                  sequence:
                    - service: light.turn_on
                      target: !input left_target_light
                - conditions: "{{ light and press and bottom }}"
                  sequence:
                    - service: light.turn_off
                      target: !input left_target_light
          
          - if:
            - condition: template
              value_template: "{{ switch }}"
            then:
              - choose:
                - conditions: "{{ switch and press and top }}"
                  sequence:
                    - service: switch.turn_on
                      target: !input left_target_switch
                - conditions: "{{ switch and press and bottom }}"
                  sequence:
                    - service: switch.turn_off
                      target: !input left_target_switch

          - choose:
            - conditions: "{{ top and press }}"
              sequence: !input left_top_press
            - conditions: "{{ top and press }}"
              sequence: !input left_top_press
            - conditions: "{{ top and quick_release }}"
              sequence: !input left_top_quick_release
            - conditions: "{{ top and long_release }}"
              sequence: !input left_top_long_release
            - conditions: "{{ bottom and press }}"
              sequence: !input left_bottom_press
            - conditions: "{{ bottom and quick_release }}"
              sequence: !input left_bottom_quick_release
            - conditions: "{{ bottom and long_release }}"
              sequence: !input left_bottom_long_release
   
    - if:
        - condition: template
          value_template: "{{ right or also }}"
      then:
        - variables:
            target_move: !input right_target_move
            target_move_list: >
              {% set data = namespace(list=[]) %}
              {% for key, value in target_move.items() %}
                {% if value is string %}
                  {% set data.list = data.list + [value] %}
                {% else %}
                  {% set data.list = data.list + value %}
                {% endif %}
              {% endfor %}
              {{ data.list }}
            move: "{{ target_move != {} }}"
            target_light: !input right_target_light
            light: "{{ target_light != {} }}"
            target_switch: !input right_target_switch
            switch: "{{ target_switch != {} }}"
        
        - parallel:
        
          - if:
            - condition: template
              value_template: "{{ move }}"
            then:
              - choose:
                - conditions: "{{ press }}"
                  sequence:
                    - repeat:
                        for_each: "{{ target_move_list }}"
                        sequence:
                          - service: mqtt.publish
                            data:
                              payload: "{\"brightness_move_onoff\": {{ '-' if bottom }}{{ move_speed}} }"
                              topic: "zigbee2mqtt/{{ state_attr(repeat.item, 'friendly_name') }}/set"
                - conditions: "{{ long_release }}"
                  sequence:
                    - repeat:
                        for_each: "{{ target_move_list }}"
                        sequence:
                          - service: mqtt.publish
                            data:
                              payload: "{\"brightness_move\": \"stop\"}"
                              topic: "zigbee2mqtt/{{ state_attr(repeat.item, 'friendly_name') }}/set"

          - if:
            - condition: template
              value_template: "{{ light }}"
            then:
              - choose:
                - conditions: "{{ light and press and top }}"
                  sequence:
                    - service: light.turn_on
                      target: !input right_target_light
                - conditions: "{{ light and press and bottom }}"
                  sequence:
                    - service: light.turn_off
                      target: !input right_target_light
          
          - if:
            - condition: template
              value_template: "{{ switch }}"
            then:
              - choose:
                - conditions: "{{ switch and press and top }}"
                  sequence:
                    - service: switch.turn_on
                      target: !input right_target_switch
                - conditions: "{{ switch and press and bottom }}"
                  sequence:
                    - service: switch.turn_off
                      target: !input right_target_switch

          - choose:
            - conditions: "{{ top and press }}"
              sequence: !input right_top_press
            - conditions: "{{ top and press }}"
              sequence: !input right_top_press
            - conditions: "{{ top and quick_release }}"
              sequence: !input right_top_quick_release
            - conditions: "{{ top and long_release }}"
              sequence: !input right_top_long_release
            - conditions: "{{ bottom and press }}"
              sequence: !input right_bottom_press
            - conditions: "{{ bottom and quick_release }}"
              sequence: !input right_bottom_quick_release
            - conditions: "{{ bottom and long_release }}"
              sequence: !input right_bottom_long_release 

2 Likes

Great work @bvhme! I spent lots of of hours in the past days to get the Scenic FoH switch to work and your blueprint did the trick. :+1:t2:
Question: I’m able to configure the switch to turn on and off a light (actually two lights). How can I configure dimming with long presses?
I’m fairly new in HA so forgive me if I’m asking too obvious questions.

Hey @AgileCowboy,

I use the Brightness Move that Zigbee2MQTT exposes for that. Just put your entity in the ‘target MQTT move’.

What will happen is when pressed it will send the message to start dimming and if quickly released it will just keep going, but when released after being held it wil stop the dimming.

Thanks again @bvhme, at first “Linker target MQTT move” and “Rechter target MQTT move” didn’t work at all. I removed the FoH EnOcean PTM 215Z from Zigbee2MQTT and HA Devices tab. After a restart of HA I reconnected the Senic FoH switch and configured the basic on/off options.
Once that worked I configured the “move” buttons which at first did not work but after selecting the desired entity instead of the device that also worked. Victory at last!

1 Like

Hey, can someone tell me which devices can forward the PTM 215Z Zigbee signal? I tried Ikea Tradfi and Osram Smart Plugs but doesn’t work and unfortunately my HA Skyconnect is too far away from the switch. Thanks for your help!

Philips Hue lamps. Not sure if the plug would also work.

Hi @bvhme
I’m all new to HA and trying to get my FoH switches to work. I Was implementing the blueprint in the top of this post. After reading your comment and saw you explanation i found it very interesting and wanted to try it out. But like mentioned I’m all green to this and its a lot to comprehend. Is there any chance i can find your blueprint as import?

Also I’m unsure what you mean by

I’m sorry to ask questions you may find logic :slight_smile:

Thanks a million in advance!

Hi there. I’m all green to HA. Thanks for this code. Made my day that the dimming could be so smooth.
I works like a charm if I do single bulb, but I cant get it to work with groups. I’ve tried to create a group of light in configuration.yaml and it didn’t work.

Can you please tell me how to do several bulb’s like a group or zone?

Do i need to create a group inside Ziggbee2MQTT or do I have to list several bulbs in this code with multiple entities or maybe an third option i didn’t think about?

Could you share your automation config? I can’t get it to work.

I think working with z2m groups is best practice and probably will solve your issue.

Go to the top of this topic and fetch the blueprint or push “import blueprint”

After you done that go to “Automation & scenes” then “Blueprint” tap.

Tap the “Controller - EnOcean PTM 215Z (Friends of Hue) switch”

Go to the top right corner and push the three dots “…”

Select “edit in YAML”

Enter this code and correct it with your own entities:

description: ""
alias: Auto - Alrum Kontakt #NAME OF YOUR AUTOMATION
use_blueprint:
  path: vandalon/z2m EnOcean PTM 215Z (Friends of Hue) switch.yaml
  input:
    controller: Kontakt Alrum # NAME OF YOUR SWITCH
    button_1_pressed:
      - service: light.turn_on
        data: {}
        target:
          entity_id: light.alrum_spot_13 # NAME OF YOUR ENTITY
    button_1_held:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Alrum Spot 13/set # FRIENDLY NAME OF YOUR LIGHT INSERTED BETWEEN / /
          payload: "{\"brightness_move_onoff\": 51}"
          qos: 0
          retain: false
    button_1_released:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Alrum Spot 13/set # FRIENDLY NAME OF YOUR LIGHT INSERTED BETWEEN / /
          payload: "{\"brightness_move\": \"stop\"}"
          qos: 0
          retain: false
    button_2_pressed:
      - service: light.turn_off
        data: {}
        target:
          entity_id: light.alrum_spot_13  # NAME OF YOUR ENTITY
    button_2_held:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Alrum Spot 13/set # FRIENDLY NAME OF YOUR LIGHT INSERTED BETWEEN / /
          payload: "{\"brightness_move_onoff\": -51}"
          qos: 0
          retain: false
    button_2_released:
      - service: mqtt.publish
        data:
          topic: zigbee2mqtt/Alrum Spot 13/set # FRIENDLY NAME OF YOUR LIGHT INSERTED BETWEEN / /
          payload: "{\"brightness_move\": \"stop\"}"
          qos: 0
          retain: false

Then hit “SAVE” If it ask for name just give the same as you named it in the code under alias.

Thanks. I thought you were using the blueprint @bvhme posted.

But your code helps a lot. My first finding is that HA has a hard time to distinguish a press and a hold from eachother. Will do some further testing.