Start with a daily list of selected batteries

For a Home Assistant low battery notification, use a daily time trigger and build the message from the readings you want to monitor. Start with ordinary door, motion and temperature sensors. Include both percentage readings and separate low-battery indicators, and report missing data without calling it a flat battery.

A trigger is what starts an automation. A threshold-crossing trigger reacts when a reading enters the low range; it does not send another reminder every morning just because the reading stays low. The numeric-state documentation explains that distinction. A scheduled check suits a recurring maintenance list.

The example below uses built-in Home Assistant features. It creates one message in Home Assistant’s Notifications panel, updates that same message on later checks, and removes it when the selected readings no longer need attention. It checks the last reported values; it does not ask every device to take a fresh measurement.

Researched from current Home Assistant and project documentation on September 11, 2026. The YAML and message template were checked with simulated readings. This configuration was not run in Home Assistant or on physical devices. The cover is an AI-generated illustration of battery maintenance.

1. Identify the right battery readings

An entity is one reading or control in Home Assistant. A single door sensor may have a door-open entity, a battery-percentage entity, and a battery-low entity. You want the battery entities, not the door-open reading.

Open Settings → Tools → States and find one of your devices. Older versions put this under Developer tools → States. Read the state and attributes. A device_class identifies what a reading means; the word “battery” in its name alone is not enough.

On a small screen, swipe the table sideways to read every column.

What you findWhat it meansUse it this way
sensor.…, class battery, unit %A remaining-charge percentage.Compare with a chosen limit; this example includes 20% and lower.
binary_sensor.…, class batteryon means low; off means normal.Use the device’s low indicator without inventing a percentage.
unknown or unavailableHome Assistant has no usable current reading.Show “Check readings”; investigate the device or its connection.
Voltage, charging state, or a text-only readingA different kind of information.Keep it out of this percentage/low-indicator recipe.

These meanings come from the Sensor and Binary sensor references. A charging indicator has class battery_charging; it is not a low-battery warning.

2. Give those entities one label

A label groups selected items across rooms. Create one named Battery watch under Settings → Areas, labels & zones → Labels. Then open Settings → Devices & services → Entities, select the battery entities, and apply that label. The label instructions show the selection controls.

Apply the label directly to the battery entities. Labeling their device or room does not include them in label_entities(), the function used here. That distinction is explicit in the function reference.

For your first check, select one percentage sensor and one low-battery indicator if you have both types. If one physical battery has both readings, choose one to avoid duplicate entries. Include both only if you deliberately want to see disagreements. Give devices clear names and assign rooms so the reminder identifies where to look.

Under Settings → Tools → Template (older versions: Developer tools → Template), paste this to verify the selection:

{{ label_entities('Battery watch') | sort }}

The result should list your chosen entity IDs. An empty list means nothing is being watched. When you add a device later, label its battery entity too.

3. Create the daily check

Go to Settings → Automations & scenes → Create automation → Create new automation. Open the three-dot menu, choose Edit in YAML, and replace the new automation’s contents with this configuration. YAML is the text version of the automation editor; keep the indentation when copying.

Keep threshold: 20 as an illustrative starting point, or change it to suit your devices. It is not a manufacturer-approved replacement limit for every battery. The time is 10 am in Home Assistant’s configured time zone.

alias: Daily battery maintenance list
description: Check selected battery readings at 10 am
triggers:
  - trigger: time
    at: "10:00:00"
conditions: []
actions:
  - variables:
      threshold: 20
      watched: "{{ label_entities('Battery watch') | sort }}"
  - variables:
      report: |-
        {% set ns = namespace(low=[], check=[]) %}
        {% for e in watched %}
          {% set value = states(e) %}
          {% set name = device_name(e) or state_attr(e, 'friendly_name') or e %}
          {% set area = area_name(e) %}
          {% set name = name ~ (' in ' ~ area if area else '') %}
          {% set kind = state_attr(e, 'device_class') %}
          {% if value in ['unknown', 'unavailable'] %}
            {% set ns.check = ns.check + [name ~ ': ' ~ value] %}
          {% elif e.startswith('sensor.') and kind == 'battery'
              and state_attr(e, 'unit_of_measurement') == '%'
              and is_number(value) and 0 <= value | float <= 100 %}
            {% if value | float <= threshold %}
              {% set ns.low = ns.low + [name ~ ' (' ~ value ~ '%)'] %}
            {% endif %}
          {% elif e.startswith('binary_sensor.') and kind == 'battery'
              and value in ['on', 'off'] %}
            {% if value == 'on' %}
              {% set ns.low = ns.low + [name ~ ' (battery low)'] %}
            {% endif %}
          {% else %}
            {% set ns.check = ns.check + [name ~ ': unsupported reading'] %}
          {% endif %}
        {% endfor %}
        {% if watched | count == 0 %}
          No battery entities selected. Check the Battery watch label.
        {% else %}
          {% if ns.low %}
        Low batteries: {{ ns.low | join('; ') }}.
          {% endif %}
          {% if ns.check %}
        Check readings: {{ ns.check | join('; ') }}.
          {% endif %}
        {% endif %}
  - choose:
      - conditions: "{{ report | trim | length > 0 }}"
        sequence:
          - action: persistent_notification.create
            data:
              notification_id: daily_battery_maintenance
              title: Battery maintenance
              message: "{{ report | trim }}"
    default:
      - action: persistent_notification.dismiss
        data:
          notification_id: daily_battery_maintenance
mode: single

The first part collects labeled entities. The template then builds separate “Low batteries” and “Check readings” lists. Valid zero-percent readings are included; missing values are never converted to zero. Unsupported values produce a check message so a mislabeled charging or voltage sensor cannot silently disappear.

The final actions use one fixed notification_id. Home Assistant’s Create notification action updates that message instead of stacking copies. The Dismiss notification action clears only this reminder when the next check finds nothing to report. It does not clear other notifications.

4. Check the result against this worked example

These are illustrative inputs and expected results from the recipe, not measured device readings. Assume the label includes the first five rows and the limit is 20%.

On a small screen, swipe the table sideways to read every column.

Selected reading at 10 amExpected resultNext step
Hall temperature sensor: 20%Low batteries: included at the limit.Check its battery instructions and arrange replacement.
Desk button: 0%Low batteries: included.Check promptly; zero is not discarded as an empty value.
Patio sensor battery-low indicator: onLow batteries: “battery low.”Follow the device’s warning; there is no percentage to compare.
Shed sensor: unavailableCheck readings: unavailable.Check connection and device operation before blaming its battery.
Bedroom sensor: 76%No entry.The reported level passes this check; operation is not proven.
Phone: 12%, without the labelNot monitored.Label it only if you want it on the same maintenance list.

At 10 am tomorrow, the first three readings appear again if unchanged. If you dismiss the message without fixing them, the next scheduled run recreates it. After replacing batteries, wait for updated readings, then run the automation to refresh the list. Clearing the notification by hand does not reset a device’s battery value.

Test without changing real sensor states: save the automation and select Run actions. If your numeric batteries are all above the limit, temporarily set threshold to 100 and run it again. All valid labeled percentage readings should appear. Restore your chosen limit immediately and rerun. This test does not make a normal binary indicator low.

Finally, set the time a few minutes ahead and let the automation start by itself, then restore 10 am. A manual run checks the actions; it does not prove the scheduled trigger. If Home Assistant is off at the scheduled time, run it manually after startup or wait for the next day. This example does not catch up automatically.

5. Add a phone notification if you want one

The base example shows a message inside Home Assistant; it does not make your phone buzz. Once that message is correct, install and connect the Home Assistant Companion App, allow notifications, and find your phone’s notification action under Settings → Tools → Actions.

Add this immediately after persistent_notification.create in the same sequence, at the same indentation as that action. Replace notify.mobile_app_your_phone with your actual action name:

- action: notify.mobile_app_your_phone
  data:
    title: Battery maintenance
    message: "{{ report | trim }}"

It sends only when the report is nonempty. A manual run can send another phone message. The persistent notification’s automatic clearing does not remove an already-delivered phone notification. Use the Companion notification guide for phone setup and delivery details.

The list is calculated on your Home Assistant server. Its input readings may still depend on a vendor cloud, and normal phone push can use internet services. Keep sensitive device names out of lock-screen previews. If the internal message works but phone push does not, follow our notification delivery troubleshooting guide.

When the list looks wrong

On a small screen, swipe the table sideways to read every column.

SymptomCheck first
“No battery entities selected”Check the exact label name and apply it on the Entities tab, not just to devices or rooms.
“Unsupported reading”Check the domain, device class, unit and value. This recipe accepts percentages from 0 to 100 and battery binary indicators.
The same device appears twiceCheck whether both percentage and low-battery entities were labeled. Keep the indicator you intend to follow, or keep both deliberately.
A dead sensor still shows a good percentageThis recipe cannot recognize a stale but valid number. Check the device’s main reading and its integration’s availability/reporting behavior.
No scheduled messageOpen the automation’s trace—the record of its last run. An empty report should clear the message; no run points to its time, enabled state or server uptime.

For the last case, our automation trigger, condition and action checklist separates a missed run from a failed action.

Other practical questions

Can I do this entirely in the visual editor?

For a simple immediate alert, use Battery low for a binary indicator, or Battery level crossed threshold for a percentage sensor, then add a notification action. The combined daily list here uses a template to format multiple devices and separate missing readings.

Do I need Battery Notes?

No. This recipe uses built-in features. Battery Notes is an optional custom integration when you also want battery types, replacement history, individual thresholds or reporting-age checks. Those features need configuration; installing it does not prove every device is still working.

Can I rely on this for locks or smoke alarms?

Use it only as an extra maintenance reminder. Keep the device’s own low-battery warnings, manufacturer maintenance schedule and routine checks. A daily check can miss a sudden failure, and a quiet list says only that the selected reported values passed the recipe’s checks.

For a household handoff, write down who checks the message and where the correct replacement batteries are stored. Tara’s home automation kit with coordinated local routines brings that kind of maintenance planning into the wider setup.