Getting ghost notifications on Android phone from all Zigbee devices using Zigbee2Mqtt

It seems about every 45 min or so, all day long, everyday, that I will get a notification from home assistant android notifications that a door sensor will report closed erroneously. It will never report open erroneously just closed. This happens every day. I have noticed that if I restart Home Assistant I will get these same messages. So I assume that perhaps zigbee2mqtt may be restarting? I know it’s not my VM that is restarting for sure. I don’t know enough about how zigbee2mqtt works to start troubleshooting. I was wondering if someone could offer some suggestions about where to start looking? Thanks in advance. Also HA is always showing the door status correctly in Lovelace dashboard.

Can you share your automation that is sending notifications to your phone? Nothing does that OOTB so you must have an automation making those.

1 Like

Yes definitely.

- id: notify steven phone Door Change
  alias: notify Steven phone Door Change
  initial_state: true
  trigger:
  - entity_id:
    - binary_sensor.garage_tilt_sensor
    - binary_sensor.family_room_slider_contact
    - binary_sensor.garage_side_door_contact
    - binary_sensor.garage_back_door_contact
    platform: state
  action:
  - data_template:
      title: Home Assistant
      message: '{{ trigger.to_state.attributes.friendly_name }} was {% if trigger.to_state.state
        == ''on'' %} Open {% else %} Closed {% endif %}'
    service: notify.mobile_app_vnote20

So I believe the problem here is your trigger. You have to remember that every change in the entity (including a change in only an attribute) counts as a state change. And when you do this you listen for any and all state changes in the listed entities:

  trigger:
  - entity_id:
    - binary_sensor.garage_tilt_sensor
    - binary_sensor.family_room_slider_contact
    - binary_sensor.garage_side_door_contact
    - binary_sensor.garage_back_door_contact
    platform: state

If you only want to listen for a change in the actual state and don’t care about state changes that only involve an attribute then you should do this:

  trigger:
  - entity_id:
    - binary_sensor.garage_tilt_sensor
    - binary_sensor.family_room_slider_contact
    - binary_sensor.garage_side_door_contact
    - binary_sensor.garage_back_door_contact
    platform: state
    to:

You can see this in the third example here. Although in the latest versions I generally take this one step further and do this:

  trigger:
  - entity_id:
    - binary_sensor.garage_tilt_sensor
    - binary_sensor.family_room_slider_contact
    - binary_sensor.garage_side_door_contact
    - binary_sensor.garage_back_door_contact
    platform: state
    not_to: ['unknown', 'unavailable']
    not_from: ['unknown', 'unavailable']

This not only ignores state changes where only an attribute changed, it also ignores state changes I generally don’t care about (like when something goes unavailable temporarily or when something goes from unknown to its real state at startup or after a config change). If you use set availability for any of those sensors then perhaps you do want to track unavailable. But unknown is probably only going to happen at startup or on a config reload.

3 Likes

Bonus hint - Since you mentioned you’re getting started on Zigbee2MQTT I’m going to guess that you are using the defaults here. Which likely means if you look at any of the entities created by Z2M in developer tools → states you’ll notice that every entity has a ton of attributes.

By default Z2M duplicates data a lot. For each value reported by devices you integrate you get an entity in HA and each entity of that device gets an attribute with the same value. I would guess that is what is causing all the attribute changes and therefore the ghost notifications. It’s also ridiculously inefficient on the DB.

Fortunately the fix is easy - set legacy_entity_attributes to false in Z2M’s settings. And while you’re at it you should set legacy_triggers to false before you get too far underway and accidentally start using legacy features that will go away some day.

3 Likes

You post was a real eye opener. I feel like I literally just leveled up in HA. I can’t thank you enough for that explanation. Made perfect sense and happy to report the ghost notifications have stopped. I really appreciate you taking the time to teach. Thank you again!

1 Like

@CentralCommand I didn’t have the legacy entities and triggers disabled. How do I determine if I was using them in HA? I turned those settings off and want to make sure I didn’t break anything in my HA setup.

Legacy entities is both simultaneously obvious and hard to explain :joy:

Basically pick a device in HA created by z2m and look at its entities. Then go to the states tab in developer tools and open one of those entities. Do you see a bunch of attributes with the same names and values as those entities in the device page? If so those are legacy.

Changing legacy_entity_attributes to false makes those go away so the data reported from your zigbee devices is stored once in HA as the state of an entity. And not replicated many times as an attribute of every entity of the device.

Legacy triggers is a bit easier to explain. When it’s true you get click and action sensors in HA for your zigbee devices with buttons. Those sensors have state unknown like 99.9% of the time and briefly become some valid state when you press a button to let you know what button was pressed.

When legacy triggers is false you don’t get those sensors. Instead HA discovers device triggers. So in automations if you want to trigger off a button press you pick device, select the device from the drop-down menu and then select the trigger to use from the list of what was discovered.

1 Like