Zigbee2MQTT 2.0 - deprecation of actions

3 minute read

I’ve seen a few people struggle with the deprecation of _click and _action entities for Home Assistant.

These have been replaced with new (for Zigbee2MQTT) event entities, which behave differently enough to be confusing at first.

Summary

  • event entities have a state that is the time they last fired, so you have to use the State trigger for them, selecting To (optional) as Any state (ignoring attribute changes)
  • You then have to parse the new state object with templates to identify what happened
  • Not all devices behave exactly the same, you’ll need to use developer tools to look at the attributes of your event entity to see what you need.

You could use device triggers, but they only work in the UI, and suffer from so many limitations that I can’t recommend them.

Attention! You have to enable the event entities in the Z2M settings:

homeassistant:
  enabled: true
  experimental_event_entities: false

Worked example

I had an automation for the office dial to pause/play the music when the dial was clicked. I’ve simplified it for this example:

id: 'office_dial_action'
alias: 'Office dial action'
triggers:
  - platform: state
    entity_id: sensor.office_dial_moes_action
    to: 'toggle'
actions:
  - if:
      - condition: state
        entity_id: media_player.office
        state: 'playing'
    then:
      - action: media_player.media_pause
        data:
          entity_id: media_player.office
    else:
      - action: media_player.media_play
        data:
          entity_id: media_player.office

Now it looks like this:

id: 'office_dial_action'
alias: 'Office dial action'
triggers:
  - trigger: state
    entity_id: event.office_dial_moes_action
    to: ~
conditions:
  - condition: template
    value_template: >-
      {{ trigger.to_state.attributes.event_type == 'toggle' }}
actions:
  - if:
      - condition: state
        entity_id: media_player.office
        state: 'playing'
    then:
      - action: media_player.media_pause
        data:
          entity_id: media_player.office
    else:
      - action: media_player.media_play
        data:
          entity_id: media_player.office

That’s not very different, and the actions are exactly the same, so how did I get there?

Step by step

  1. First thing I did was open my devices page and find the device.
  2. Then I found the event entity, in the Events box - in this case everything I need to know is actually shown there. It tells me that when I click the dial the Action is toggle.
  3. For other devices you may need more than just the action, and that’s where developer tools comes in. Go there and filter down to the event entity.
  4. In the Attributes column you’ll see (at least) two relevant attributes. These are event_type and event_types - the first being the last event, and the other being a list of possible values. My mmWave sensor also has another relevant attribute - region - that identifies the detection region the event took place in.

The main change here is to the trigger, and then adding a template condition to filter out the event I’m interested in.

Details

triggers:
  - platform: state
    entity_id: sensor.office_dial_moes_action
    to: 'toggle'
        # move this value to a new template condition, replacing the value with null (no quotes)

becomes

triggers:
  - trigger: state
    entity_id: event.office_dial_moes_action
    to: ~
        # null and ~ (and NULL) are functionally identical - I just happen to prefer ~
conditions:
  - condition: template
    value_template: >-
      {{ trigger.to_state.attributes.event_type == 'toggle' }}

For those that prefer to do it in the UI:

state trigger on the event entity

template condition on the new state object

For almost everything I had they followed this format and approach:

  1. Swap the entity in the trigger from sensor.*_action to the event. entity
  2. Change the to: to be on any state change
  3. Add a template condition checking that the event type (of the new state) is the state value you had before

The exceptions were one automation where either I had a typo or there was some tidy-up done in Zigbee2MQTT that changed - to _ as used by everything else, and one where additional attributes were involved.

Other examples

Some things took a little more effort, like the template sensor for the office mmWave sensor, though some actually got simplified. For instance my volume control automation became shorter (and could actually be made shorter again).

Conclusion - Don’t Panic!

Yes, the switch away from the old entities seems daunting, particularly if you’ve never touched templates before.

Thankfully the details of the change are, mostly, really simple. The steps in details are typically all that simple automations need - moving the value from the to to the template.

PS: Illuminance lux

For those of you worried about the removal of the lux sensors - it’s actually the raw value of the illuminance that’s gone away, the lux value remains, it’s just that the illuminance sensor is now the old illuminance_lux sensor. Yes, it’s confusing, but as long as you didn’t want the raw value you’ve not lost anything.