Home Assistant projects
All projects

Battery Monitor

Integration + card · Home & energy
v1.20.0 · Nov 11, 2026 HA 2024.12.0+ Archived

Archived. Battery Monitor is now part of System Hub: its repository is no longer updated. Install System Hub instead, which takes over its settings (how to migrate).

Watches every battery of your home and tells you twice a day which ones are low.

No more alert for a battery that dips for an hour, no more dead sensor found a week later: a battery is reported once it has stayed below the threshold for a while, with a card listing them by room.

Highlights

  • Automatic discovery of every battery
  • Threshold and duration before notifying
  • Unavailable batteries reported too
  • Two notifications a day, at times you choose
  • Replacement forecast from each battery's drain, kept across restarts, with a Next replacement sensor
  • Battery type from Battery Notes in the notifications and the CSV export
  • Lovelace card with a full screen view by room, type or replacement date, and a CSV export
  • Mini card with only the batteries needing attention, with a detail button showing the full card
  • Sidebar panel for administrators with the card, every setting and the Notify now and Export CSV actions
  • Low and replaced battery events for automations
  • Spare batteries counted by type, with what to buy for the batteries low or due
  • Diagnostics with the notify actions redacted

Cards

battery-monitor-cardbattery-monitor-mini-card
type: custom:battery-monitor-card

Install

  1. 1Open the repository in the Marketplace with the Add to Marketplace button above, or addgithub.com/juju35/ha-battery-monitor as a custom repository (category Integration).
  2. 2Download it from the Marketplace.
  3. 3Restart Home Assistant and add the integration from Settings → Devices & services.

Documentation

From the README

Features

Features

  • Automatic discovery of every battery: sensor (level in %) and binary_sensor (low / normal) with the battery device class, one per device
  • Threshold (20 % by default) and duration (24 hours by default): a battery is notified once it has stayed below the threshold for that long, even across restarts
  • Unavailable batteries reported too: a device whose battery is unavailable or unknown for the duration (often a dead battery) is notified like a low one
  • Two notifications a day, at times you choose (09:00 and 19:00 by default), listing the low batteries with their room and level
  • Persistent notification, replaced each time and cleared when no battery is low any more, and the notify actions of your choice (mobile app…)
  • Ignored batteries and integrations: phones and tablets of the mobile app are left out by default
  • Lovelace card bundled with the integration, added automatically to the dashboard resources (nothing to add by hand): icon, name, room, battery type, level and how long the battery has been low; only the batteries needing attention are tinted: orange while low, red when unavailable or once notified (blinking once notified)
  • Full screen view from the card: every battery grouped by room, by battery type (CR2032, AA…) or by replacement date (forecast from the measured drain), with what to buy for the ones to replace, the next replacement and a CSV export; battery types read from Battery Notes or set in the card editor
  • Replacement forecast: the drain of each level battery is measured once a day on its recorded history (last 30 days, since the last replacement), and kept across restarts (the history is read again only once the last measure is a day old); the card shows ≈ 12 d left when the threshold is less than two months away, and the Next replacement sensor gives the date the first battery reaches it
  • Events for your automations: battery_monitor_low when a battery goes below the threshold, battery_monitor_replaced when a new battery is detected
  • Mini card: the status and only the batteries needing attention, with a button that shows the full card
  • Sidebar panel (administrators), in three tabs: the batteries by room, type or replacement date with a summary and a search, every setting, the actions
  • Low batteries sensor with every monitored battery in its attributes, Last notification and Next replacement sensors, Notify now button, battery_monitor.notify and battery_monitor.export (CSV) actions
  • Spare batteries: count the spares you keep by type (battery_monitor.set_stock); each replacement detected takes its batteries out, and the Spare batteries sensor and the notification say what to buy for the batteries low or due within 30 days
  • UI setup, no YAML; English, French, German, Spanish, Italian, Dutch, European Portuguese, Polish, Romanian, Danish, Swedish, Bulgarian, Russian, Ukrainian, Hungarian, Slovak, Czech, Slovenian, Latvian, Greek and Serbian (Cyrillic and Latin)

Prerequisites

Prerequisites

  • Home Assistant 2024.12 or newer
  • Devices that report their battery (Zigbee, Z-Wave, Bluetooth, Matter…), with the battery device class

Configuration

Configuration

Settings → Devices & services → Add integration → Battery Monitor. Everything can be changed later with Configure, or from the sidebar panel.

Option Default Description
Low battery threshold 20 % A battery is low below this level
Low for at least 24 h Hours a battery must have stayed below the threshold before it is notified (0: at the next notification)
Morning notification 09:00 First of the two daily notifications
Evening notification 19:00 Second of the two daily notifications
Notify actions — Also send the notifications with these actions (notify.mobile_app_…); a persistent notification is always created
Ignored batteries — Batteries never monitored
Ignored integrations mobile_app Integrations whose batteries are never monitored

Notifications#

At each notification time, the batteries that have been below the threshold for the duration are listed, the lowest first:

3 low batteries
• Front door (Entrance): 8 % · CR2032
• Kitchen leak sensor (Kitchen): 17 % · 2× AAA
• Smoke detector (Hallway): low

As soon as one of them is unavailable, the title becomes N batteries to check and its line says unavailable. The battery type ends the line when Battery Notes knows it (the battery_type and battery_quantity of the battery, or its device's Battery type sensor).

When no battery is due, nothing is sent and the persistent notification is cleared.

Entities#

Entity Description
sensor.battery_monitor_low_batteries Number of batteries below the threshold. Attributes: unavailable (number of unavailable batteries), due (number needing attention for the duration), threshold, duration (h), batteries (every monitored battery: entity_id, device_id, name, area, level, icon, low, alert (low or unavailable), due, unavailable, below_since, drain_per_day (% per day measured on the history, 0 when stable, null when unknown), days_left (before the threshold, null when stable, unknown, or already low or unavailable), replace_by (that date), battery_type (from Battery Notes, 2× AA, null when unknown))
sensor.battery_monitor_last_notification Time of the last notification; attribute notified (number of batteries notified)
sensor.battery_monitor_spare_batteries Number of battery types short of spares (0: enough). Attributes: stock (spares per type counted), needed (batteries of that type low, unavailable or forecast to reach the threshold within 30 days, with their quantity: a 2× AA device needs 2), short (the types missing some, and how many). Only the types set with battery_monitor.set_stock
sensor.battery_monitor_next_replacement Date the first battery is forecast to reach the threshold; a battery already low or unavailable comes first (since when it has been). Attributes: entity_id, name, level, days_left (0 for one already low), forecast_at (last measure of the drains)
button.battery_monitor_notify_now Sends every low battery right away, whatever the duration (or No low battery)

Action battery_monitor.notify#

Sends every battery below the threshold right away, whatever the duration, or a No low battery message when none is low (the scheduled notifications only list the batteries low for the duration). For example from an automation when you leave on holiday:

action: battery_monitor.notify

Action battery_monitor.set_stock#

Sets how many spare batteries of a type you keep, by the type Battery Notes gives without the quantity (AA, AAA, CR2032…). Each replacement detected for a battery of that type (a rise of 15 points, the battery_monitor_replaced event) then takes its quantity out of the count, never below 0. Without count, the type is no longer counted. When spares are missing, the notification ends with Spare batteries to buy: 1 AA, 2 CR2032. Open to every user, like battery_monitor.notify.

action: battery_monitor.set_stock
data:
  battery_type: AA
  count: 8

Action battery_monitor.export#

Writes every monitored battery to a CSV file (entity_id, name, area, level, low, unavailable, due, below_since, drain_per_day, days_left, replace_by, battery_type (from Battery Notes)), for a spreadsheet or a report. Administrators only. path is optional: battery_monitor.csv in the configuration folder by default; a relative path is inside the configuration folder, an absolute one must be in the configuration folder or in allowlist_external_dirs. The file name must end in .csv, and hidden folders such as .storage are refused. Returns the path and the number of batteries.

action: battery_monitor.export
data:
  path: exports/batteries.csv
response_variable: result  # {"path": "/config/exports/batteries.csv", "batteries": 23}

Sidebar panel#

The integration adds a Battery Monitor entry to the sidebar, shown to administrators only (/battery-monitor), with three tabs, each with its own address (/battery-monitor, /battery-monitor/actions, /battery-monitor/settings), so a reload or a link comes back to the same tab:

  • Batteries: drawn by the panel itself, at once — a summary (batteries to check, low, unavailable, the next replacement), then every battery by room, by battery type or by replacement date, with its level, how long it has been low or unavailable and its replacement forecast; a search (name, room or type) and Hide the batteries that are fine. Tap a battery for its details. The cards are laid out in a grid on a wide screen, one under the other on a phone. The CSV export is in the Actions tab;
  • Actions: Notify now (every battery needing attention, like the button) and Export CSV, with an optional file name (battery_monitor.csv in the configuration folder by default, the same rules as the battery_monitor.export action), plus the state of the integration, its last notification and a link to its device. The cog in the toolbar opens Devices & services;
  • Settings: threshold, duration, morning and evening times, notify actions, ignored integrations and ignored batteries — the same options and limits as Configure, with the choices picked from lists (the notify actions available, the integrations that have a battery, every battery found, its room and integration next to it), and Save.

Saving reloads the integration once; a form field you have not edited follows a change made elsewhere (Configure, another administrator). Behind the panel are four admin-only WebSocket commands: battery_monitor/settings, battery_monitor/update_settings, battery_monitor/notify and battery_monitor/export. To hide the entry, long-press the sidebar title and hide Battery Monitor, like any other panel.

Events#

Battery Monitor fires two events on the Home Assistant bus, on a change only (never for a battery already low at start-up, after a reload or when first found):

Event When Data
battery_monitor_low A battery goes below the threshold (or a low-battery binary sensor turns on); a battery that goes unavailable and comes back still low does not fire it again entry_id, entity_id, device_id, name, level (null for a binary sensor), threshold
battery_monitor_replaced A battery's level rises by 15 points or more since its last reading (the same rule that restarts the replacement forecast), even with an unavailable gap while the battery was out entry_id, entity_id, device_id, name, level, previous_level

For example, a notification on your phone as soon as a battery goes low, and a logbook entry when one is replaced:

automation:
  - alias: Battery low
    triggers:
      - trigger: event
        event_type: battery_monitor_low
    actions:
      - action: notify.mobile_app_phone
        data:
          title: Low battery
          message: "{{ trigger.event.data.name }}: {{ trigger.event.data.level }} %"
  - alias: Battery replaced
    triggers:
      - trigger: event
        event_type: battery_monitor_replaced
    actions:
      - action: logbook.log
        data:
          name: "{{ trigger.event.data.name }}"
          message: "battery replaced ({{ trigger.event.data.previous_level }} % → {{ trigger.event.data.level }} %)"
          entity_id: "{{ trigger.event.data.entity_id }}"

Diagnostics#

Settings → Devices & services → Battery Monitor → ⋮ → Download diagnostics gives the options and every monitored battery (level, status, times, forecast), to attach to an issue. The notify actions, which name your phones, are redacted.

Card#

The card is added to the dashboard resources by the integration. Add it from the dashboard (Add card → Battery Monitor Card) or in YAML:

type: custom:battery-monitor-card
Option Default Description
entity Auto The Low batteries sensor; found automatically
title Batteries Card title
columns 1 Number of battery columns (1–3); a card too narrow for them shows fewer, each at least 160 px wide
only_low false Show only the batteries below the threshold or unavailable
hide_when_ok false Hide the whole card when every battery is above the threshold and available (always shown while editing the dashboard)
notify_button true Bell button in the header that sends the notification now: it turns while sending, then shows a check mark, or the reason in its tooltip when it fails; disabled while the button entity is unavailable
popup true Full screen button in the header
expanded false Lay the full screen view out in the card itself (by room, by type, by replacement date, what to replace, next replacement), as the sidebar panel does; no full screen button then
csv_button true Export CSV button in the full screen view and the expanded card
battery_models — The battery type of every device of a model Battery Notes doesn't know: Hue dimmer switch: CR2450, Radiator Thermostat W600: 2× AA
battery_types — The type of one battery, by battery entity, for one without a model or that differs from its model: sensor.remote_battery: 2× AAA
language Auto Force language: en, fr, de, es, it, nl, pt (European Portuguese), pl, ro, da, sv, bg, ru, uk, hu, sk, cs, sl, lv, el, sr (Serbian, Cyrillic) or sr-Latn (Serbian, Latin)

Tap a battery to open its details.

Mini card#

A compact card for a half-width column: the header with its status and Notify now button, and only the batteries needing attention (nothing more when every battery is fine). The detail button (top right) shows the full card, with every battery and its full screen button; a click outside the card brings the compact view back. Same options and editor as the card (Add card → Battery Monitor Mini Card):

type: custom:battery-monitor-mini-card

Full screen#

The full screen button (top right) shows every battery over the whole screen, grouped by room, by battery type or by replacement date, with To replace: how many batteries of each type to buy for the ones low or unavailable, and Next replacement: the first battery the measured drain takes to the threshold, with the date. By replacement date sorts the batteries into To replace now, Within 30 days, Within 3 months, Later and No forecast yet, each with its days left, date and drain per day. Export CSV downloads every battery (room, type, level, status, drain, days left, replacement date) to the browser. It closes with its button, Escape, a click outside, or the back button on a phone. From the keyboard, the focus goes to its close button, Tab stays inside it, and the focus returns to the full screen button once it is closed. On a phone the groups follow one another; wider, they sit side by side in balanced columns.

The battery type comes from Battery Notes when it is installed (the battery_type and battery_quantity of the battery, or its device's Battery type sensor). For the others, set it once per device model: the card editor's Battery types by model section lists the models (with their manufacturer and how many devices) whose type is not detected; pick a type (CR2032, CR2450, AA, AAA, 2× AA, 9V, built-in rechargeable…) or type your own. A battery without a model, or one that differs from its model, gets its own type in Battery types by battery, which wins over its model. 2× AA (or 2x AA, AA x2) counts two batteries; the batteries without a type are grouped under Unknown type. The order: the battery's own type, then its model's, then Battery Notes.

type: custom:battery-monitor-card
battery_models:
  Hue dimmer switch: CR2450
  MYGGBETT door/window sensor: AAA
  Radiator Thermostat W600: 2× AA
battery_types:
  sensor.remote_battery: 2× AAA

How it works

How it works

A battery is a sensor with the battery device class (its level in %) or a binary_sensor with the battery device class (on means low). When a device has both, its level sensor is used. Hidden entities, the ignored batteries and the batteries of the ignored integrations are left out.

When a battery goes below the threshold, Battery Monitor writes down the time. For a battery that is already low when it is first seen (right after installing Battery Monitor, say), that time is read from the history, up to 30 days back. It is kept while the battery is unavailable (a dead battery often makes its device unavailable) and across restarts, and forgotten once the battery is back above the threshold (replaced or recharged). A battery is notified once that time is older than the duration.

The list is updated whenever a battery changes, and every 10 minutes.

Once a day (and at start), the drain of each level battery is measured on its recorded history over the last 30 days: a least-squares slope of the level, counted from the last replacement (a rise of 15 points or more), when at least three days and three points are recorded. From that drain and the current level come the days left before the threshold and the replacement date; a stable level (less than 0.05 % a day) gives none. The days left follow the level between two measures.

Support

Support

If you find this project useful, you can support its development:

Buy Me a Coffee

1.20.0Nov 11, 2026Latest

Deprecated

  • Battery Monitor is now a module of System Hub, and this repository is archived: no more updates here. Turned on in System Hub, the module takes over the settings of Battery Monitor. While both are set up, Battery Monitor raises a repair in Settings → Repairs, as it would otherwise run twice and register its cards twice: remove Battery Monitor and its card resource once the module is on. See Migrating (juju35/ha-system-hub#49, thanks @FredM67).

1.19.0Nov 10, 2026

Improvements

  • Panel, Batteries tab: drawn by the panel itself instead of embedding the card, so it shows at the first opening. A summary (batteries to check, low, unavailable, the next replacement), every battery by room, by battery type or by replacement date with its level bar, how long it has been low or unavailable and its replacement forecast, a search (name, room or type) and Hide the batteries that are fine. The groups are laid out in a grid on a wide screen and one under the other on a phone.
  • Panel shown at once: the release keeps its languages in the panel file instead of a separate file to wait for.

1.18.4Nov 10, 2026

Fixes

  • Panel empty on its first opening (fine when coming back to it): in the release, the panel is only defined once the page's language file has loaded, and Home Assistant had already handed it the connection, the address and the layout by then; they were lost and nothing was drawn. They are now taken up when the panel is defined.

1.18.3Nov 9, 2026

Improvements

  • Panel: while the settings load, Loading…; if they can't be loaded, the error with a Retry button (tried again on its own meanwhile) instead of the page for an integration that isn't set up.

1.18.2Nov 9, 2026

Fixes

  • Panel sometimes empty when opened: a load that failed (Home Assistant still starting after a restart or an update, the connection coming back after the app resumed) left the battery list and settings empty until the page was reloaded. It is now tried again after 2 s, 5 s, 15 s, then every 30 s while the panel is shown, and again as soon as the connection is back.

1.18.1Nov 9, 2026

Maintenance

  • No code change: released again to check the installation from the Marketplace.