Battery Levels not updating via Z-Wave JS

I have migrated a Z-Wave setup from a Vera Hub to Home Assistant and although most things work far better now I still have a problem with most battery operated Z-Wave devices not reporting their battery level correctly.

Specifically I have one NAS-PD07Z (Motion Sensor), three FGSD002 (Smoke Detectors), one NAS-WS01Z (Water Leak detector), two FGMS001 (Motion Sensors), one HS1SA-Z (Smoke Detector) and one NAS-DS01Z (Door/Window Sensor).

All of these devices seem to work correctly reporting their main function(s) correctly as expected.

The three FGSD002 (Smoke Detectors) preciously reported their battery state (via my Vera hub) which varied as expected from 100% with new batteries falling as expected until I replaced the batteries

When I transferred the three FGSD002 to Home Assistant everything worked as expected, each sensor reported its battery level (35%, 10% and 100%). They have continued to report exactly these values ever since, even though I have changed their batteries!

I am aware that in order to get a report of battery level from some Z-Wave devices I need to request it using zwave_js refresh_value and wait for it to wake up. I have done this in Node-Red for each of my battery operated devices with no effect.

I am using Home Assistant Core 2023.12.4 and Z-Wave JS Version: 0.4.3.

Only one of my devices the HS1SA-Z (Smoke Detector) does correctly report its battery level starting at 100% and so far falling to 94% over a month.

I am relatively new to Home Assistant and Node-Red and any assistance would be appreciated.

Could be alot of things. Here’s what I do. First an automation to poll the battery, second a template sensor that records the time at which a battery update was received. With that sensor you can determine if the battery update is coming in.

There are 3 things that can impact it:
a) the device wake-up time - when the device wake-ups it should pick up the request to send the battery level. What are the wake-up times for your devices?
b) device is not waking up - I’ve had a device not wake-up and require factory reset
c) automation is wrong
d) a lot of devices have very poor battery sensors and ambient temperature fluctuations can cause values to go up and down.

- id: "garage_sensor poll zwave battery"
  alias: garage_sensor poll zwave battery
  description: "Automation to periodically refresh zwave battery values"
  trigger:
    - platform: time
      at: "23:00:00"
  action:
    - delay:
        minutes: "{{ range(0, 60)|random|int }}"
    - service: zwave_js.refresh_value
      data:
        entity_id: sensor.garage_sensor_battery_level
template:
  - trigger:
      - platform: zwave_js.value_updated
        entity_id:
          - sensor.garage_sensor_battery_level
        command_class: 128
        property: level
    sensor:
      - name: "garage_sensor_battery_last_updated"
        state: "{{now().strftime('%Y-%m-%d %H:%M:%S')}}"

recorder:
  include:
    entities:
      - sensor.garage_sensor_battery_last_updated

Then I put these into a dashboard

Z-Wave JS automatically refreshes battery levels if they are stale for more than 7 days. So if you do nothing, your battery values should only be stale up to a max of 7 days (plus the wake up interval, which could vary vastly). If a device makes battery reports on its own (unsolicited), then ZJS won’t issue a refresh. Only if you need a more frequent update schedule do you need to manually refresh. Of course, the more you poll a battery device, the faster you deplete the battery. This does rely on your devices waking up automatically. I have one that does not, so I have to physically wake it, but it will report when the battery is low.

In addition to the proposed template sensors, you can verify whether battery levels are being refreshed automatically by looking in the driver logs. Messages like CNTRLR » [Node 019] Battery CC values may be stale, refreshing... mean the driver is refreshing after the 7 day limit. You should see BatteryCCGet and/or BatteryCCReport messages in response to that. Or, you can check if the devices are reporting unsolicited updates (Report with no Get). In either case, you can search for messages like CNTRLR [Node 048] [~] [Battery] level: 100 => 100, which would mean a report was received.

I’ll re-iterate that Z-Wave devices tend to not be very reliable at reporting battery levels. As examples, here’s one going down, then back up:

Jan 05 07:47:29 zui[1711526]: 07:47:29.436 CNTRLR   [Node 013] [~] [Battery] level: 88 => 88                          [Endpoint 0]
Jan 05 11:48:55 zui[1711526]: 11:48:55.920 CNTRLR   [Node 013] [~] [Battery] level: 88 => 87                          [Endpoint 0]
Jan 07 10:47:35 zui[1711526]: 10:47:35.317 CNTRLR   [Node 013] [~] [Battery] level: 87 => 81                          [Endpoint 0]
Jan 12 16:42:15 zui[3123008]: 16:42:15.810 CNTRLR   [Node 013] [~] [Battery] level: 81 => 87                          [Endpoint 0]

Here’s one jumping from 20 to 0, and staying at 0 for over two weeks:

Dec 27 08:36:03 zui[1711526]: 08:36:03.483 CNTRLR   [Node 018] [~] [Battery] level: 20 => 0                           [Endpoint 0]
Dec 27 09:00:30 zui[1711526]: 09:00:30.924 CNTRLR   [Node 018] [~] [Battery] level: 0 => 0                            [Endpoint 0]
...
Jan 13 13:33:47 zui[3123008]: 13:33:47.149 CNTRLR   [Node 018] [~] [Battery] level: 0 => 0                            [Endpoint 0]

If you want to check the logs, you’ll need to enable debug logging. For this use case the easiest approach is going to be to enable log to file in the add-on configuration, and check the logs later. By default you get 7 days, which may or may not be long enough, depending on the refresh cycle

1 Like

Sorry for the delay in getting back and thank you both for your help.

In view of what “freshcoast” says I am now collecting log data without any attempt to manually refresh the battery data.

I have now collected data for 12 days without any attempt to manually refresh the battery data. During this time there seem to have been 19 “updates” of Z-Wave battery levels from my ten battery operated devices.

One device (Node ID 52 a Smoke Detector from Shenzhen Heiman Technology Co., Ltd. Model HS1SA-Z) has updated 9 times somewhat randomly between 96% and 100%.

One device (Node ID 59 a Water Sensor from Shenzhen Neo Electronics Co., Ltd. Model NAS-WS01Z has updated twice both times giving a possible 100%.

One device (Node ID 50 a Door/Window Sensor from Shenzhen Neo Electronics Co., Ltd. Model NAS-DS01Z has updated once to stay at 90% a value it has been stuck on for several months.

One device (Node ID 15 a Siren from Everspring, model SE812 has updated once to stay at 90% a value it has been at since it was included more than a year ago.

Two devices (Nodes ID 90 and 91 both Motion Sensors from Fibargroup model FGMS001 have updated once to remain stuck at a very improbable 100% (One has 3 month old batteries the other 6 month old).

Three devices (Nodes ID 33,34 and 35 all Smoke Detectors from Fibargroup model FGSD002 have updated once each and are stuck at 35%, 10% and 100% respectively and have been stuck since they were included more than a year ago, all of them have had new batteries in this time and all of them have been successfully tested with fake smoke. I replace the batteries when they stop reporting changes in temperature.

Any help in getting working battery levels would be appreciated.

2024-01-26 20:40:18.435 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":59,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":100,"prevValue":100,"propertyName":"level"}}}', extra='')

2024-01-26 21:38:53.264 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":99,"prevValue":99,"propertyName":"level"}}}', extra='')

2024-01-27 00:24:44.618 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":50,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":90,"prevValue":90,"propertyName":"level"}}}', extra='')

2024-01-31 12:20:56.709 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":96,"prevValue":97,"propertyName":"level"}}}', extra='')

2024-02-01 12:10:32.738 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":96,"prevValue":96,"propertyName":"level"}}}', extra='')

2024-02-01 17:41:15.932 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":15,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":90,"prevValue":90,"propertyName":"level"}}}', extra='')

2024-02-01 19:56:30.264 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":91,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":100,"prevValue":100,"propertyName":"level"}}}', extra='')

2024-02-01 20:22:31.483 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":90,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":100,"prevValue":100,"propertyName":"level"}}}', extra='')

2024-02-01 21:26:51.475 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":35,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":100,"prevValue":100,"propertyName":"level"}}}', extra='')

2024-02-02 03:29:34.755 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":34,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":10,"prevValue":10,"propertyName":"level"}}}', extra='')

2024-02-02 11:59:50.584 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":97,"prevValue":96,"propertyName":"level"}}}', extra='')

2024-02-02 23:35:37.218 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":59,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":100,"prevValue":100,"propertyName":"level"}}}', extra='')

2024-02-03 10:24:54.145 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":50,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":90,"prevValue":90,"propertyName":"level"}}}', extra='')

2024-02-03 11:49:40.473 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":98,"prevValue":97,"propertyName":"level"}}}', extra='')

2024-02-03 14:33:35.753 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":33,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":35,"prevValue":35,"propertyName":"level"}}}', extra='')

2024-02-04 11:39:48.622 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":99,"prevValue":98,"propertyName":"level"}}}', extra='')

2024-02-05 11:29:56.579 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":99,"prevValue":99,"propertyName":"level"}}}', extra='')

2024-02-06 11:20:08.532 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":100,"prevValue":99,"propertyName":"level"}}}', extra='')

2024-02-07 11:10:05.897 DEBUG (MainThread) [zwave_js_server] Received message:
WSMessage(type=<WSMsgType.TEXT: 1>, data='{"type":"event","event":{"source":"node","event":"value updated","nodeId":52,"args":{"commandClassName":"Battery","commandClass":128,"property":"level","endpoint":0,"newValue":99,"prevValue":100,"propertyName":"level"}}}', extra='')

In a 12 day window, at minimum you will see one update. So it sounds like all of your devices reported battery levels at least once, is that correct? If so, it sounds like things are working as intended from the software side. Does that match your observation, or do you think there’s still an issue?

If you’re unsure of that, you can look in the driver log file and see the corresponding controller and device messages.

Not sure what can be done about devices that report incorrect values. All Z-Wave JS is doing is asking for a battery level, and the device responds.

Once again thanks for commenting.

Of my 10 battery devices only one seems to be 100% “working” in that it reports a plausible and changing value.

The three most obviously not working at all are (Nodes ID 33,34 and 35). These are all Smoke Detectors from Fibargroup model FGSD002.

Each of these has updated once and each is “stuck” at the same value they had when I included them into Z-Wave on HA about a year ago that is 35%, 10% and 100% respectivly.

These three devices were previously used with my Vera Controller where they reported sensible battery levels that decayed over time and responded to battery changes.

Any progress with this?

I have the exact same experince, with Vera all battery operated Z-wave devices (for example FGSD002 and several others) worked as expected.
Seems strange that this isn’t the case with same devices in HA.
What ZW controller do you use?
I have a ZW090 Gen5 from AEON Labs.

For me this is a very basic function I expect just to work.