Mqtt discovery unreliable

I’m using mqtt dscovery very short time. I always prefer fixed settings. Now I gave it a go to it because of default settings of zigbee2mqtt.
I have a zigbee switch connected through zigbee2mqtt. The switch is configured but disconnected from power supply (it’s not powered on). So it’s not available in zigbee network therefore should be unavailable. And indeed it is how z2m reports it to mqtt

Here is how it looks like in mqtt:
homeassistant/switch/0x00158d000449dccc/switch/config

{
  "availability": [
    {
      "topic": "zigbee2mqtt/bridge/state"
    },
    {
      "topic": "zigbee2mqtt/zb_switch1/availability"
    }
  ],
  "command_topic": "zigbee2mqtt/zb_switch1/set",
  "device": {
    "identifiers": [
      "zigbee2mqtt_0x00158d000449dccc"
    ],
    "manufacturer": "Nue / 3A",
    "model": "Smart in-wall switch (HGZB-01A)",
    "name": "zb_switch1",
    "sw_version": "Zigbee2MQTT 1.16.1"
  },
  "json_attributes_topic": "zigbee2mqtt/zb_switch1",
  "name": "zb_switch1_switch",
  "payload_off": "OFF",
  "payload_on": "ON",
  "state_topic": "zigbee2mqtt/zb_switch1",
  "unique_id": "0x00158d000449dccc_switch_zigbee2mqtt",
  "value_template": "{{ value_json.state }}"
}

Availability is set to offline:
obrazek

But for some reason, HA still things it’s available and switched on:
obrazek

History book:

The times likely corresponds with Z2M restarts. It turns unavailable and after few seconds turns on. But where the HA picks state and availability from, if the data in MQTT shows that device is unavailable. There is no even data about state=on.

So, this device is reporting 2 availability topics. One for the bridge state and one for the switch state. My guess is this would be a logical ‘and’ where both of these have to be ‘online’ for this device, though it could be an ‘or’ in which case one of them has to be true? I’m not sure, MQTT Switch just says ‘a list of topics’. What is your zigbee2mqtt/bridge/state say?

It could be a few things.

First, zigbee2mqtt “should” send cached updates to home assistant if home assistant disconnects/reconnects from the MQTT server (i.e. reboot).

By default (on home assistant 0.113+), home assistant should send its availibity to /homeassistant/status topic.

Zigbee2MQTT is expecting Home Assistant to send it’s birth/will messages to homeassistant/status . Be sure to add this to your configuration.yaml if you want Zigbee2MQTT to resend the cached values when Home Assistant restarts`

in zigbee2mqtt configuration.yaml:
# Optional: Home Assistant status topic (default: shown below) homeassistant_status_topic: 'homeassistant/status'

Make sure this topic exists in mqtt at the values you specified (or default). If they do, then home assistant should get the cached values when it restarts (kind of like a special retain), and would receive the normal updates if zigbee2mqtt restarts.

Next might be the QoS settings in zigbee2mqtt.

If you have an unreliable network, the default QoS for these messages is set to 0 which means ‘send once, good luck’. A value of 1 will increase network overhead, but requires clients to ACK that they received updates.


Here’s something you can test. Try to get it in this state (doesn’t sound hard). Then in MQTTExplorer or something, try to publish to the zigbee2mqtt/zb_switch1/availability topic manually. Push ‘online’ and ‘offline’ and see if home assistant responds to the updates.

Try with the other availabilty topics as well (zigbee2mqtt/bridge/state and /homeassistant/status). See which of those fixes the state.

From there, you can deduce which setting to tweak.

I’m still not sure on the dual availability topic though. That one seems slightly odd.

Yeah… I didn’t found it in docs though.
And as you said It would make sense applying AND logic on that.

First, zigbee2mqtt “should” send cached updates to home assistant if home assistant disconnects/reconnects from the MQTT server (i.e. reboot).

Hmm. I really don’t know how it works, but it would brake decoupling principle of the system. IMO the point of using mqtt is to make sender z2m independent from a listener(s). So I would expect that Z2M communicates only with MQTT, while HA only with MQTT. It should be enough. They must not now about eachother. And because data are here in mqtt, I can see no reason for other triggers or explicit activities informing about restarts. For sure Z2M puts proper data to mqtt.

Anyway thank you for response. Later, when back from work I will be back to your answer and try to make experiments you are suggesting.

Yes. Your other option is to set those devices to retain. That way it is the responsibility of the broker to notify new clients of the information should they join the network later.

It does break the decoupling…but is a custom solution integrated into zigbee2mqtt for home assistant. If you wanted a similar functionality, you would instead set the retain flag.

The downside being…you would never lose nodes from your network unless you configured zigbee2mqtt to remove them manually since they are now retained at the broker.