I’ve had about 10 of these in my house for at least a year, where I had them connected through a Hue bridge to control some Hue lights, which was all integrated via the Hue integration. Now I can ditch the hub, and have all my Hue stuff directly in Z2M
However, there is one thing I’m missing, when compared to the way they worked via the Hue bridge. Is it possible to stop the lights from turning off, when dimming all the way down (or should I say, below) 0% brightness?
Hi, thanks a lot for your work!
I´m struggling with my PTM 215Z. The Button is integrated, but there are noch actions (see below). The Bluepint isn´t working, too. Is that normal, that there are no information regading the actions?
Might be because you have not enabled elabsed time.
Cut/paste from OP
Make sure you enable Elapsed in the z2m advanced settings. This is used to prevent a release after a short press to restart the automation prematurely.
Hey @khvej8 as I wrote to you in a direct message, Elapsed is enabled in z2m. I am very satisfied with the blueprint because the automations run as desired and without errors. This warning message only exists after a complete system restart. I think it’s because if Home Assistant is completely restarted and reloads the automations while z2m or MQTT are not yet ready, the error message occurs.
I’ve created a separate topic about this here. I wish @vandalon would take a look at this and maybe could help:
I’m not sure I understand. I set a controller field in both my automations (as you can see in the code blocks that I posted).
What is the basetropic field? I can see no reference to such a field in this thread or any home assistant documentation.
You say that I need to set these fields in the blueprint. Does that mean I have to edit the blueprint file or the automations?
Testing out the blueprint and I have major issues. I put switch on a light on release 1 und switch off that light on release 3. It generally works but I sometimes have to press 3 times until something happens. It is really unreliable. I thought it was the switch itself that it does not transmit. However I tested by creating two normal automations one switch on and the other one switch off. With those it works every time without issue.
So it must be a problem in the blueprint. Any idea what is causing it?
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
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 (), used it to compare but additionally compare to the payload as well. Once compare would be enough
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
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.