The new Zigbee2MQTT 2.0 introduces the new event based actions for things with buttons. And at the same time deprecates the old way of using action sensors.
However, it seems the Zigbee2MQTT devs have pulled back on the plan to remove the legacy sensor based method, so for now users can start to play with the events but it may be best to keep things as they are and re-enable things as they are by turning on Home Assistant legacy actions sensors from the Zigbee2MQTT UI (Settings)
You can still use device triggers which most of us hate with a passion because it uses some ugly long devive IDs that no human can associate with anything and will change is you replace a device. Ugly ugly.
The new way is pretty cool. It was introduced as beta in the December release but with Zigbee2MQTT 2.0 it was supposed to be official, but the developers admit that it is still work in progress.
The new actions that are created start with event entities. Prefix event. These change state when buttons are pressed and attributes of the event sensor defines what changed. Each type of remote or switch does it differently but the principle is the same.
Let us take an example with a Philips Hue 4 button dimmer switch. The example implements both short and long press and up/down dimming the Zigbee2MQTT optimal way. In this example the light.bedroom is a group defined in Zigbee2MQTT and the background lights are some additional lights that can be turned on and off by long press.
alias: Bedroom Dimmer
triggers:
- trigger: state
entity_id: event.bedroom_switch_action
not_from: unavailable
#Do not put any To or From or Attribute lines in trigger.
#If you do, you cannot push same button twice. Very important
actions:
- choose:
- conditions:
- "{{trigger.to_state.attributes.button == 'on'}}"
- "{{trigger.to_state.attributes.event_type == 'press'}}"
sequence:
- data:
entity_id:
- light.bedroom
brightness_pct: 50
action: light.turn_on
- conditions:
- "{{trigger.to_state.attributes.button == 'on'}}"
- "{{trigger.to_state.attributes.event_type == 'hold'}}"
sequence:
- data:
entity_id:
- light.bedroom
- light.bedroom_desk
- light.background
brightness_pct: 100
action: light.turn_on
- conditions:
- "{{trigger.to_state.attributes.button == 'up'}}"
- "{{trigger.to_state.attributes.event_type == 'hold'}}"
sequence:
- action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Bedroom/set
payload: "{\"brightness_move\": 50 }"
- conditions:
- "{{trigger.to_state.attributes.button == 'down'}}"
- "{{trigger.to_state.attributes.event_type == 'hold'}}"
sequence:
- action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Bedroom/set
payload: "{\"brightness_move\": -50 }"
- conditions:
- "{{trigger.to_state.attributes.button in ('up', 'down')}}"
- "{{trigger.to_state.attributes.event_type == 'hold_release'}}"
sequence:
- action: mqtt.publish
metadata: {}
data:
topic: zigbee2mqtt/Bedroom/set
payload: "{\"brightness_move\": 0 }"
- conditions:
- "{{trigger.to_state.attributes.button == 'off'}}"
- "{{trigger.to_state.attributes.event_type == 'press'}}"
sequence:
- data:
entity_id:
- light.bedroom
action: light.turn_off
- conditions:
- condition: template
value_template: "{{trigger.to_state.attributes.button == 'off'}}"
- condition: template
value_template: "{{trigger.to_state.attributes.event_type == 'hold'}}"
sequence:
- data:
entity_id:
- light.bedroom
- light.bedroom_desk
- light.background
action: light.turn_off
initial_state: "on"
mode: queued
max_exceeded: silent
Here is an example using an IKEA 2 button switch
alias: Office Blinds Switch
triggers:
- trigger: state
entity_id: event.office_blinds_switch_action
not_from: unavailable
#Do not put any To or From or Attribute lines in trigger.
#If you do, you cannot push same button twice. Very important
actions:
- choose:
- conditions:
- "{{trigger.to_state.attributes.event_type == 'brightness_move_up'}}"
sequence:
- data:
topic: office-blinds/set
payload: "50"
action: mqtt.publish
- conditions:
- "{{trigger.to_state.attributes.event_type == 'brightness_move_down'}}"
sequence:
- data:
topic: office-blinds/set
payload: "0"
action: mqtt.publish
- conditions:
- "{{trigger.to_state.attributes.event_type == 'on'}}"
sequence:
- data:
topic: office-blinds/step
payload: "10"
action: mqtt.publish
- conditions:
- condition: template
value_template: "{{trigger.to_state.attributes.event_type == 'off'}}"
sequence:
- data:
topic: office-blinds/step
payload: "-10"
action: mqtt.publish
initial_state: "on"
mode: queued
max_exceeded: silent
To find the attributes, go to HA Developer Tools ā States
Find the event entity for the switch/remote. You can see in the attributes in the right column
This is my Philips 4 button dimmer
event_types: press, press_release, hold, hold_release
event_type: press_release
button: off
icon: mdi:gesture-double-tap
friendly_name: Bedroom Switch Action
The event_types lists the possible event_types. The event_type shows the last received event. And the button shows which button was pressed.
Not all devices have a button attribute. They only use the event_type. I even have a remote where all buttons make an event_type uniqie to each button. Except for long press where the event_type becomes hold and you have to use the button attribute to see which button is held. That is one bad example I have seen this confusing way. Normally it is either event_type of a combination of event_type and button.
I think it is pretty well made. Much better than the deconz_event with mysterious 4 digit numbers I came from.
I hope this is a help.
Important updates from discussion below
It seems the new event feature is not enabled in 2.0 by default. At least not for upgraders. Make sure that in the Zigbee2MQTT configuration.yaml (not HA and not addon config) you set Zigbee2MQTT setting
Home Assistant experimental event entitiesā to on
If you want the old behavior you also enable āHome Assistant legacy triggersā
Do not try to put any from or to or attribute for the trigger. This is important! The events will not trigger unless the value changes from something else to the value given in ātoā or āattributeā. The result is that same button on a remote only works once until another button is pressed or you long press. Only trigger on the event entity itself.
Edit 2. Simplified the examples using the not_from: unavailable instead of the condition. Thanks for that elegant solution @seblu