Aqara Button delay not working anymore with MQTT

Hi,

I have a problem with my Aqara Button. After switching from Conbee to Zigbee2MQTT thats the last piece that is not working as before.

The Button does work, but the delay is ignored and the switch never turns off. The log also says that trigger.event.data.subtype is wrong, but whats the right way to do it?

With Conbee this worked:

  trigger:
  - platform: event
    event_type: deconz_event
    event_data:
      id: button
      event: 1002
  - platform: event
    event_type: deconz_event
    event_data:
      id: button
      event: 1004
  action:
  - service: script.button
  - delay: "{{ '00:01:30' if trigger.event.data.event == 1002 else '00:03:00'}}"

For MQTT this is not working:

- id: 'Button'
  alias: Button
  mode: restart
  trigger:
  - domain: mqtt
    device_id: a75e42e18b2e7779796722f2ddce6909
    type: action
    subtype: single
    trigger: device
  - domain: mqtt
    device_id: a75e42e18b2e7779796722f2ddce6909
    type: action
    subtype: double
    trigger: device
  action:
  - service: script.button
  - delay: "{{ '00:01:30' if trigger.event.data.subtype == single else '00:03:00'}}"
  - service: switch.turn_off
    entity_id: switch.switch_3

Any Ideas? :slight_smile:

You changed trigger types. When you were using an event trigger, trigger.event was defined. But now you’re using an MQTT trigger, which doesn’t give you trigger.event. Here’s the documentation of what’s in the trigger variable for MQTT triggers.

The right thing to use depends in part on the MQTT payload you’re getting… I suspect you probably want something like trigger.payload_json.get('action'), assuming that you would see single as the value and that it’s keyed as action in the subtype (like for this Aqara button).

I have tried it with
- delay: "{{ '00:00:15' if trigger.payload_json.get('action') == single else '00:00:05'}}"
but it does not work, log says:
UndefinedError: 'dict object' has no attribute 'payload_json'

I have also tried
- delay: "{{ '00:00:15' if trigger.payload.action == single else '00:00:05'}}"
but with that the if statement is ignored.

The Aqara Button you mentioned is the one that I use.

That is not an mqtt trigger, it is a device trigger.

That should work, if you use an mqtt trigger

I don’t have aqara buttons, but it should be something like

  trigger:
  - trigger: mqtt
    topic: zigbee2mqtt/ikeapirboven
  condition:
  - condition: and
    conditions:
    - condition: template
      value_template: '{{ trigger.payload_json.occupancy == true }}'

Good catch.

Getting UndefinedError: 'dict object' has no attribute 'payload_json'
with
- delay: "{{ '00:00:15' if trigger.payload_json.action == single else '00:00:05'}}"

Because you are using a device trigger

Wild guess

- id: 'Button'
  alias: Button
  mode: restart
  trigger:
  - trigger: mqtt
    topic: zigbee2mqtt/your button  
action:
  - service: script.button
  - delay: "{{ '00:01:30' if trigger.payload_json.action == single else '00:03:00'}}"
  - service: switch.turn_off
    entity_id: switch.switch_3

Check with mqtt explorer what exactly you get when you press the button and post it here.
(both topic and received json) and we can help you more

Since you said your new automation was triggering fine, but balking once you got to the delay statement, here’s a jankier way to do it, but should work.

Still, if you want to use Zigbee2MQTT for automations, you really should learn how to use the MQTT trigger, which involves figuring out what topic your devices are posting to (and it’s really not hard to figure out).

Note that it’s not just the template in the delay that’s changed; there are also id lines now in each trigger definition.

- id: 'Button'
  alias: Button
  mode: restart
  trigger:
  - domain: mqtt
    device_id: a75e42e18b2e7779796722f2ddce6909
    type: action
    subtype: single
    trigger: device
    id: single
  - domain: mqtt
    device_id: a75e42e18b2e7779796722f2ddce6909
    type: action
    subtype: double
    trigger: device
    id: double
  action:
  - service: script.button
  - delay: "{{ '00:01:30' if trigger.id == 'single' else '00:03:00'}}"
  - service: switch.turn_off
    entity_id: switch.switch_3

I got it working :partying_face:

The jankier version is also running fine, but since I have come so far, I also wanted to have it running with the MQTT Trigger. The Topic part was new for me though. Did not even know where to find that^^ With the Explorer I realised it was always there in the Zigbee2MQTT Device Info :smiley: .
But even with the topic it was not running and that was the mean part.
Because
if trigger.payload_json.action == single did not work but
if trigger.payload_json.action == 'single' is running fine

Now everythinks works as it should, thanks alot to you both :slight_smile:

I had another Issue but could solve it, so just for your and everyone else information:

The topic must be topic: zigbee2mqtt/Button/action and the delay has to be with if trigger.payload like that

  trigger:
  - trigger: mqtt
    topic: zigbee2mqtt/Button/action
  action:
  - service: script.button
  - delay: "{{ '00:01:30' if trigger.payload == 'single' else '00:03:00'}}"

At first my topic was without /action and that caused an execution of the automation after every restart of HA.^^

This is a slightly different approach – the action subtopic repeats what you would get in trigger.payload_json.get('action'), and that’s all: so it doesn’t use JSON (it doesn’t need to). And because the message isn’t valid JSON, you probably don’t get anything in trigger.payload_json which is why you’re using the raw payload.

Chances are that the zigbee2mqtt/Button topic is configured for retention, which means that the broker keeps the most recently sent message on that topic, and automatically sends it out when a new client subscribes (which is what HA does when it starts up). I don’t completely recall right now where to find that configuration.

The reason I point this out is that the action subtopic is narrow: it only tells you when the button is pressed, and what type of interaction it was (single or double, for example). But the JSON payload has other keys that might be of interest, like battery and device_temperature (and other kinds of devices might have other information too). So although it sounds like this approach works for your purposes, and there’s nothing wrong with it, I wanted to point out the limitations.

It is somewhat annoying that when retention is on, MQTT-trigger automations can trigger on an HA restart. I am not aware of a way to distinguish a retained message from a new message using the MQTT trigger, although a workaround is to configure Z2M to include a timestamp in the message and then use Jinja to figure out whether the message is older than some nominal time, like a few seconds–but that’s obviously not optimal.

1 Like