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.

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