Add Z-Wave battery low event entity#170111
Conversation
Adds handling for the new BatteryNotification type from
zwave-js-server-python, so that Battery CC battery low notifications
fire the existing zwave_js_notification bus event with the event_type
("battery low") and urgency level included.
Adds a diagnostic event entity per battery-powered node that fires when the device sends a Battery CC battery low notification. The event_type reflects the urgency reported by the device (soon vs. now, mapped from BatteryReplacementStatus), and the raw urgency value is exposed as a state attribute.
zwave-js only ever emits a Battery CC `notification` event with urgency of `Soon` or `Now` (the upstream handler falls back to `Soon` if the device omits `rechargeOrReplace`), so guarding against `NO` was dead code. Drop the check and its test.
Annotate the `client` fixture parameter as `MagicMock` to match the project convention for typing test parameters.
The entity is dispatched from async_on_node_ready, which also runs on reinterviews. Without listening for the remove_entity_on_interview_started signal, a reinterview either tries to add a duplicate unique ID (when Battery CC is still present) or leaves a stale entity behind (when Battery CC is no longer reported). Mirror the firmware update entity by subscribing to the interview-started removal signal so the entity is rebuilt cleanly each interview.
|
Hey there @home-assistant/z-wave, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Pull request overview
This PR extends the Z-Wave JS integration with a new diagnostic event entity that fires when a node reports a Battery CC “battery low” notification, and it also forwards those Battery CC notifications onto the existing zwave_js_notification bus event for automations.
Changes:
- Add
ZWaveBatteryLowEventEntity(per non-controller node with Battery CC) and wire it up via dispatcher-based node entity creation/removal signals. - Forward
BatteryNotificationthroughasync_on_notificationand include a newATTR_URGENCYfield in the firedzwave_js_notificationevent payload. - Add base translations and new tests covering entity creation, triggering for both urgency levels, ignoring non-battery notifications, and entity removal on reinterview.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tests/components/zwave_js/test_event.py |
Adds coverage for the new per-node “Battery low” event entity behavior and lifecycle. |
homeassistant/components/zwave_js/strings.json |
Adds translated name and event_type state text for the new event entity. |
homeassistant/components/zwave_js/event.py |
Implements the new ZWaveBatteryLowEventEntity and dispatcher hook to add it per eligible node. |
homeassistant/components/zwave_js/const.py |
Introduces ATTR_URGENCY constant for the new notification payload/attributes. |
homeassistant/components/zwave_js/__init__.py |
Dispatches creation of the battery-low event entity on node-ready and forwards BatteryNotification via zwave_js_notification. |
Mirror test_power_level_notification with a Battery CC case to cover the new BatteryNotification branch in async_on_notification, asserting that command_class_name, event_type, and urgency are forwarded on the zwave_js_notification bus event.
| if not node.is_controller_node and any( | ||
| cc.id == CommandClass.BATTERY.value for cc in node.command_classes | ||
| ): | ||
| async_dispatcher_send( | ||
| self.hass, | ||
| f"{DOMAIN}_{self.config_entry.entry_id}_add_battery_low_event_entity", | ||
| node, | ||
| ) |
There was a problem hiding this comment.
I suggest we do a refactor first, in a separate PR, and introduce a node discovery feature with node discovery schemas, a node discovery handler that forwards the discovery info to the correct platform, and a node base entity class that has the common features that node based entities share.
Most of the current node based entities (ping button, controller status sensor, node status sensor, statistics sensor, firmware update) seem to have almost the same base features.
| if isinstance(notification, BatteryNotification): | ||
| event_data.update( | ||
| { | ||
| ATTR_COMMAND_CLASS_NAME: "Battery", | ||
| ATTR_EVENT_TYPE: notification.event_type, | ||
| ATTR_URGENCY: notification.urgency, | ||
| } | ||
| ) |
There was a problem hiding this comment.
This can be a separate PR, I think.
DRAFT + untested; Read the paragraph below.
Proposed change
This adds a new "Battery low" event entity for every Z-Wave node with the Battery CC. It triggers when a "Battery low" notification is sent. Unfortunately, I don't think this can currently be implemented in a clean way using the existing discovery schemas, as these notifications are not value-based, so the approach is similar to the node-based firmware update entities.
I'd really appreciate any suggestions or feedback here, or whether this approach is generally ok.
AI summary
Adds an event entity to the Z-Wave integration that fires when a node sends a Battery CC "battery low" notification, and forwards the same notification to the existing
zwave_js_notificationbus event so it can be used in automation triggers.Background:
isLowvalue, Z-Wave JS now emits a node-levelnotificationevent witheventType: "battery low"and anurgencyfield (Soon/Now).BatteryNotificationmodel and aBatteryReplacementStatusenum so HA can consume this directly.This PR builds on those upstream changes:
ZWaveBatteryLowEventEntity, a diagnostic event entity created per non-controller node that supports the Battery CC. Wired up via the same dispatcher signal pattern used for other node-level entities (ZWaveFirmwareUpdateEntity,ZWaveNodePingButton,ZWaveNodeStatusSensor, …).event_typesaresoonandnow, matching the urgency levels actually emitted upstream.event_typeset to the urgency name andurgency(the integer value) exposed as a state attribute.BatteryNotificationthrough the existingasync_on_notificationhandler so thezwave_js_notificationbus event also fires for Battery CC, withcommand_class_name: "Battery",event_type("battery low") andurgency. NewATTR_URGENCYconstant.zwave_js_notificationbus event.Notes:
(CommandClass.BATTERY, "isLow")binary sensor mapping is kept for now, as older Z-Wave JS versions exposeisLow.Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: