Using Z-Wave JS ping to detect dead battery powered nodes

Hey all,

I recently added a bunch of Z-Wave devices to HA and I’m working on some automation to monitor their states. Currently I have an automation that pings them using zwave_js.ping on a set schedule. This works pretty well for mains powered devices as their states will change to dead if they don’t respond. For battery powered devices however, their states remain in asleep even for devices that I’ve taken the batteries out of. I ran a test where I pinged an unpowered device every 24 hours for a few weeks and the node state never changed to dead.

Is there currently a way for Z-Wave JS to detect whether a battery powered node is dead vs just asleep?

Any help would be appreciated!

There’s no such thing as a dead battery node. The driver cannot tell whether a battery device is simply sleeping, or completely offline, so it will never mark them as dead. It has no heuristic to consider whether a battery device might be offline based on any kind of last communication time. I don’t think the driver maintains a “last active” node property itself (or at least it doesn’t expose one), so the applications need to do it.

Some options, maybe others can suggest something else I’ve missed:

There’s a disabled-by-default “node status” sensor who’s state is alive / sleeping / awake / dead, etc. If the node is waking up regularly, configured via the wake up interval, that sensor should toggle between alive and sleeping during the wakeup time. You could detect this state change.

If there are some sensors or notifications that change within an expected time interval, so you could detect these state changes or events. For example, my smoke alarms send a heartbeat message every 70 minutes.

You could refresh some entity, like the battery level sensor, and verify that the entity was updated within the device’s wake-up interval. The driver will queue up the Get and send it when the device wakes up, and that should trigger an update on the sensor, I believe even if the state does not change.

I think all of these HA examples would require HA to be active when the device communicates, so there’s always a possibility an event is missed if HA is offline during the wake up time. That could be handled by accepting one or more missed updates, up to a desired threshold.

zwavejs2mqtt has a "lastActive" field in the MQTT node info. This should be updated from any communication coming from the device. Create a template sensor based on the node info MQTT topic and JSON field and you can monitor the last time it communicated. Add a ping every so often to make sure there is some communication for quiet devices. Since zwavejs2mqtt is always online when the driver is up, it will never miss an update from the device. Of course, the MQTT broker will need to be online for HA to see any updates, but at least it can update from historical values.

2 Likes

Thanks for the suggestions. I went with your node status sensor idea and created a trigger sensor that triggers when the node status sensor has been in the asleep state for longer than the device’s wakeup interval. Seems to be working well so far (as long as I don’t restart HA within the interval).

Would you mind sharing the code?

- trigger:
  - platform: state
    entity_id: sensor.skylight_contact_status
    to: awake
  - platform: time_pattern
    hours: /1
  - platform: homeassistant
    event: start
  binary_sensor:
    - name: Skylight Contact Connectivity
      device_class: connectivity
      icon: mdi:heart-pulse
      state: |
        {% set device = "skylight_contact_status" %}
        {% if is_state("sensor." + device, "awake") %}
          {{ true }}
        {% elif is_state("sensor." + device, "asleep") %}
          {% set threshold = (states("input_number.z_wave_check_in_interval") | int) * 3600 %}
          {{ now().timestamp() - states.sensor[device].last_changed.timestamp() <= threshold  }}
        {% else %}
          {{ false }}
        {% endif %}

This is the trigger based binary sensor I ended up with. It runs every hour and if the node status sensor has been in the asleep state for longer than the threshold, it’ll set to off

2 Likes

I originally used a state based trigger with the “for” duration attribute but discovered that if you restart HA, the duration timer does not start on boot

I wrote a mqtt sensor template to look for devices that have not been active for a certain period and/or use a battery. Here’s the post with the template, automation, and card. ZWave-JS missing "last received" attribute? - #14 by difeta

1 Like