Battery level not updating in HA with Z-wave JS

I had a similar issue and went down the refresh_value route.

I created an automation triggered by any door opening (my batteries are door sensors) and then for action I got the device for the triggering entity and then refreshed each entity for the device. Not ideal, but it seemed to work

  - repeat:
      count: '{{ device_entities(device_id(trigger.entity_id)) | count }}'
      - service: zwave_js.refresh_value
          entity_id: '{{ device_entities(device_id(trigger.entity_id))[repeat.index
            -1] }}'
          refresh_all_values: true

Thought I’d share if anyone is interested.


I have three battery powered smoke detectors which I’ve only hac for about a moth, and untill I saw this thread I thought the battery levels should update by itself, but now I know better.

I have this automation:

description: ''
  - platform: time
    at: '00:00:00'
condition: []
  - service: zwave_js.refresh_value
      entity_id: sensor.smoke_alarm_sensor_battery_level
  - service: zwave_js.refresh_value
      entity_id: sensor.smoke_alarm_sensor_battery_level_2
  - service: zwave_js.refresh_value
      entity_id: sensor.smoke_alarm_sensor_battery_level_3
mode: single

And when I check the the zwave log, which I’ve set to log level verbose, it looks like this. I gues sthat means it’s working as it should:

2022-04-08T07:44:40.122Z CNTRLR « [Node 003] received wakeup notification
2022-04-08T07:44:40.124Z CNTRLR   [Node 003] The node is now awake.
2022-04-08T07:44:40.156Z SERIAL » 0x01150013030e9f032b00aca13d33b33768fb3529250668                    (23 bytes)
2022-04-08T07:44:40.158Z DRIVER » [Node 003] [REQ] [SendData]
                                  │ transmit options: 0x25
                                  │ callback id:      6
                                    │ sequence number: 43
2022-04-08T07:44:40.161Z SERIAL « [ACK]                                                                   (0x06)
2022-04-08T07:44:40.167Z SERIAL « 0x0104011301e8                                                       (6 bytes)
2022-04-08T07:44:40.169Z SERIAL » [ACK]                                                                   (0x06)
2022-04-08T07:44:40.170Z DRIVER « [RES] [SendData]
                                    was sent: true
2022-04-08T07:44:40.185Z SERIAL « 0x0107001306000002ef                                                 (9 bytes)
2022-04-08T07:44:40.186Z SERIAL » [ACK]                                                                   (0x06)
2022-04-08T07:44:40.188Z DRIVER « [REQ] [SendData]
                                    callback id:     6
                                    transmit status: OK
2022-04-08T07:44:40.213Z SERIAL « 0x0115000400030f9f03a900acac14ee46a25155d16ca8d8                    (23 bytes)
2022-04-08T07:44:40.222Z CNTRLR   [Node 003] [~] [Battery] level: 100 => 100                        [Endpoint 0]
2022-04-08T07:44:40.225Z CNTRLR   [Node 003] [~] [Battery] isLow: false => false                    [Endpoint 0]
2022-04-08T07:44:40.227Z SERIAL » [ACK]                                                                   (0x06)
2022-04-08T07:44:40.231Z DRIVER « [Node 003] [REQ] [ApplicationCommand]
                                    │ sequence number: 169
                                        level:  100
                                        is low: false
2022-04-08T07:44:41.242Z CNTRLR » [Node 003] Sending node back to sleep...
1 Like

I’m not sure this is working for me. Would appreciate any insight anyone could share. Running HA v2022.4.2 and zwavejs2mqtt v6.7.0.

Though the Integrations menu in HA, I set the Z-Wave JS logs to “silly”. When I call the following service through Developer Tools → Services

service: zwave_js.refresh_value
  entity_id: sensor.laundrydoor_sensor_battery_level

I only see the following in the logs:

Subscribed to Z-Wave JS Log Messages…
Log Level changed to: Silly
2022-04-11T15:20:49.665Z SERIAL « 0x010b0004000b032001ffaa008c                                        (13 bytes)
2022-04-11T15:20:49.674Z SERIAL » [ACK]                                                                   (0x06)
2022-04-11T15:20:49.678Z DRIVER « [Node 011] [REQ] [ApplicationCommand]
                                      target value: 255
2022-04-11T15:20:49.683Z CNTRLR   [Node 011] treating BasicCC::Set as a report
2022-04-11T15:20:49.685Z CNTRLR   [Node 011] [~] [Basic] currentValue: 0 => 255                     [Endpoint 0]
2022-04-11T15:20:49.717Z SERIAL « 0x01130004000b0b7105000000ff0616000000aa00d9                        (21 bytes)
2022-04-11T15:20:49.720Z CNTRLR   [Node 011] [~] [Notification] notificationMode: "push" [Endpoint 0] [internal]
                                   => "push"
2022-04-11T15:20:49.722Z SERIAL » [ACK]                                                                   (0x06)
2022-04-11T15:20:49.725Z DRIVER « [Node 011] [REQ] [ApplicationCommand]
                                      notification type:   Access Control
                                      notification status: 255
                                      notification state:  Window/door is open
2022-04-11T15:20:49.729Z CNTRLR   [Node 011] [~] [Notification] Access Control[Door state]: 23 => 2 [Endpoint 0]

2022-04-11T15:20:56.917Z SERIAL « 0x010b0004000b03200100a80071                                        (13 bytes)
2022-04-11T15:20:56.919Z SERIAL » [ACK]                                                                   (0x06)
2022-04-11T15:20:56.921Z DRIVER « [Node 011] [REQ] [ApplicationCommand]
                                      target value: 0
2022-04-11T15:20:56.924Z CNTRLR   [Node 011] treating BasicCC::Set as a report
2022-04-11T15:20:56.926Z CNTRLR   [Node 011] [~] [Basic] currentValue: 255 => 0                     [Endpoint 0]
2022-04-11T15:20:56.969Z SERIAL « 0x01130004000b0b7105000000ff0617000000a800da                        (21 bytes)
2022-04-11T15:20:56.971Z CNTRLR   [Node 011] [~] [Notification] notificationMode: "push" [Endpoint 0] [internal]
                                   => "push"
2022-04-11T15:20:56.972Z SERIAL » [ACK]                                                                   (0x06)
2022-04-11T15:20:56.974Z DRIVER « [Node 011] [REQ] [ApplicationCommand]
                                      notification type:   Access Control
                                      notification status: 255
                                      notification state:  Window/door is closed
2022-04-11T15:20:56.978Z CNTRLR   [Node 011] [~] [Notification] Access Control[Door state]: 22 => 2 [Endpoint 0]

This was me calling the service, then opening and closing the door. As far as I can tell, there is no battery refresh happening. Am I wrong in this? Any insights?


Opening and closing a door will not wakeup the node. Check your manual for the instructions.

Thank you. I was able to manually wake up each node and have now set their “wakeupinterval” to 7200. Hopefully this will work now.

I can get the list of entity IDs that represent Z-Wave JS battery entities but I’m not sure how best to call zwave_js.refresh_value on them

{% set ns = namespace(zw_devices=[], battery_entities=[], result=[]) %}
{% set ns.battery_entities = states.sensor | selectattr('attributes.device_class', 'eq', 'battery') | list %}
{%- for device_id in ns.battery_entities | map(attribute='entity_id') | map('device_id') | unique | reject('eq', none) %}
  {%- if (device_attr(device_id, 'identifiers') | list | selectattr('0', 'eq', 'zwave_js') | first ) %}
    {%- set ns.zw_devices = ns.zw_devices + [device_id] %}
  {%- endif %}
{%- endfor %}
{%- for entity_id in ns.battery_entities | map(attribute='entity_id') %}
  {%- if device_id(entity_id) in ns.zw_devices %}
    {%- set ns.result = ns.result + [entity_id] %}
  {%- endif %}
{%- endfor %}
{{ ns.result }}

Based on this pattern:

okay, so - what the blazes is going on with my sensors?
I’ve got these ZP3111 (zooz 4-in-1, monoprice rebranded) sensors. several of them show “0%” battery.

I did a force update, and they responded with 0%, which was weird because they are functional - they correctly reported awake status, motion, temp, etc. I replaced the battery and now it responds as 100% battery but does not update the value in Home Assistant.

I can manually modify it in developer tools, but then I can force it to re-read, and it gets reset back to zero, despite being able to see the values at 100% in the logs.

2022-05-02T20:36:40.610Z SERIAL « 0x0109000400040380036412                                            (11 bytes)
2022-05-02T20:36:40.612Z CNTRLR   [Node 004] [~] [Battery] level: 100 => 100                        [Endpoint 0]
2022-05-02T20:36:40.614Z CNTRLR   [Node 004] [~] [Battery] isLow: false => false                    [Endpoint 0]
2022-05-02T20:36:40.616Z SERIAL » [ACK]                                                                   (0x06)
2022-05-02T20:36:40.618Z DRIVER « [Node 004] [REQ] [ApplicationCommand]
                                      level:  100
                                      is low: false

I’ve double-checked the device ID, and I’ve given it almost 24 hours to update.
What gives?

I have the same problem with the same device.

i have also a issue with the fibaro motion sensor , reading the correct battery level
2 of them are always 100% , till the automations are not working correctly the battery is empty
And 1 of them is really stepping down from 100 to 80 and 70 but if it is really a correct value

i thought it is the firmware of the motion sensors. but that is not the issue .
Is this really working ?
Z-Wave JS: Refresh value(s) of a Z-Wave entity

i tried the automation from “gberg”
looks like only one sensor is responding it had lowered to 66%
the others ones are still 100%

when the sensors are awake , i see in the logging that the battery status is send
One is 66%, and the two others are 100% . (always)

strange is the bug than at the fibaro sensor itself , and not at zwave JS??

I’ve crerated an automation in Node Red to refresh the battery levels:

Here’s the code:

[{"id":"f02f9b9db785b34a","type":"api-call-service","z":"92da3f90.2062d","name":"refresh battery level","server":"5c29d263.09d2ac","version":5,"debugenabled":false,"domain":"zwave_js","service":"refresh_value","areaId":[],"deviceId":[],"entityId":["{{payload.entity_id}}"],"data":"{\"refresh_all_values\":\"true\"}","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":630,"y":4400,"wires":[[]]},{"id":"2d64fe73353ee48c","type":"ha-get-entities","z":"92da3f90.2062d","name":"Get all battery entities","server":"5c29d263.09d2ac","version":0,"rules":[{"property":"attributes.device_class","logic":"is","value":"battery","valueType":"str"},{"property":"state","logic":"lte","value":"100","valueType":"num"},{"property":"attributes.friendly_name","logic":"is_not","value":"Ups Battery Charge","valueType":"str"},{"property":"attributes.friendly_name","logic":"is_not","value":"mobile Battery Level","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":420,"y":4400,"wires":[["f02f9b9db785b34a"]]},{"id":"e922e823e77ff3ed","type":"inject","z":"92da3f90.2062d","name":"01:00","props":[{"p":"payload"}],"repeat":"","crontab":"00 01 * * *","once":false,"onceDelay":"60","topic":"","payload":"","payloadType":"date","x":250,"y":4400,"wires":[["2d64fe73353ee48c"]]},{"id":"5c29d263.09d2ac","type":"server","name":"Home Assistant","version":2,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30}]

Trouble is that it doesn’t seem to work, all are still reporting as 100%:

1 Like

For me 1 sensor is working correctly for battery level , but the other 2 are always 100%


i use an automation , 1 a day ““Z-Wave JS: Refresh value(s) of a Z-Wave entity”” for each zwave sensor


I cannot add much here, apart from stating i have the same problems.
I added the update scripts as described above, but I am not sure how I should verify if they have actually been executed or run.
My setup:

  • z-wave js
  • zawave js addon
  • Z‐Stick Gen5 USB Controller

So, for some it seems to work ( since they give a value other than ‘0’ or ‘100’), but I am not sure of they are actually updating.

  • Some devices are fine, others stay at 100%
  • note that it is both one Heiman Smoke detector HS1SA-Z, as well as one Fibaro smoke sensor that shows 100%
  • I am also suspicious of the 97 % value of another Heiman HS1SA-Z, since I bought all of these devices more than 2 year s ago…

What I think is interesting/strange is that some devices work, and others don’t. I assume this somehow has to do with the way the messages are queued while waiting for the devices to come up, in combination with the status of the z-wave network.



Thanks! I did this and then manually ran it and fairly soon my motion sensor went from 0% to 100% which had been irritating me given i’d put a new battery in it.

Same problem. Added an automation that calls refresh_value every night, but the following devices always show 100% battery level:

  • Vision Security Tilt Sensor ZG8101
  • Ecolink DWZWAVE25 Open/Close Sensor
  • Ecolink motion sensor

Same problem, “refresh_value” doesn’t resolve with sensors:

  • FGMS001
  • PD03Z
  • SP814
  • PSP05
  • PST02A

Here’s a template that reports when the device sends the battery level, this way you can differentiate between the device not reporting and the device sending. It’s likely that some devices just have a poor electronics for sensing battery level…

  - trigger:
      - platform: zwave_js.value_updated
          - sensor.garage_door_1_battery_level
        command_class: 128
        property: level
      - name: "garage_door_1_battery_last_updated"
        state: "{{ now() }} "

      - sensor.garage_door_1_battery_last_updated

I have seen all the discussion on this but am still unable to get the battery level updated unless I remove the battery from the device. In this particular case, it’s an Ecolink PIR motion sensor.
I created the recommended automation to using zwave_js.refresh_value. I would have expected to be able to wake up the device by walking in front of it and then this would cause the battery level to be updated (after the automation runs) This doesn’t seem to work. I also added a call to this service in the automation that is activated when this motion sensor goes off. This also doesn’t update the battery level.
I’m stumped.

Your expectation is incorrect, it doesn’t work that way. A “wake up” event is distinct from the device detecting motion or reporting something else. When the device wakes up, it’s in a high power mode listening for commands, and this occurs either on a (usually) programmable interval (i.e. the wake up interval setting) or when you physically perform some action on the device, like pushing the inclusion button. The entity refresh will only occur during this “wake up”, not when reporting.