Skip to content

battery_last_reported freezes after HA restart for devices with constant battery value -> false "not reported" alarms #5123

Description

@rbressers

Checklist

  • I have restarted Home Assistant after the HACS or manual install.
  • I have read the FAQ's.
  • I have enabled debug logging for my installation.
  • I have filled out the issue template to the best of my ability.
  • This issue only contains 1 issue (if you have multiple issues, open one issue for each issue).
  • This issue is not a duplicate issue of any previous issues.

Battery Notes Version

3.6.3

Describe the issue

battery_last_reported freezes permanently at the HA restart timestamp for
devices whose reported battery percentage never changes (e.g. always
battery: 100). After days_last_reported days, the daily
check_battery_last_reported automation fires a false "Battery Not
Reported"
notification, even though the device is alive and actively
publishing.

Verified on a production install with 16 affected battery-powered devices:

  • sensor.motion_sensor_garden_battery: state frozen for 90 hours (exact
    HA restart moment), while the sibling entity from the same MQTT
    device/topic
    (sensor.motion_sensor_garden_illuminance) updated 0.1
    hours ago. Zigbee2MQTT logs show 1732 publishes in 24h with the
    battery field present
    .
  • check_battery_last_reported (with days_last_reported: 2) reported
    all 16 devices as "not reported"; 15/16 were demonstrably alive and
    publishing.

Root cause (two parts)

  1. Startup stamp — _ensure_last_reported (coordinator.py) sets
    last_reported = utcnow() for every device without a stored value, at
    every HA start. This suggests a fresh report that never happened.
  2. No events for unchanged values — HA's MQTT integration does not
    write a new state when the payload is identical. battery: 100 stays
    100 on every publish → no state_changed and no
    state_reported event ever fires again → both listeners
    (async_track_state_change_event + async_track_state_report_event,
    sensor.py L667-680 / L715-730) never run again → last_reported stays
    frozen at the restart timestamp indefinitely.

Note: this is not fixable inside async_state_reported_listener (e.g.
re-stamping after the 1-hour throttle on same value) — for MQTT-backed
entities the event never arrives in the first place because of state
de-duplication. The 1-hour throttle (STATE_WRITE_INTERVAL_SECONDS) is
irrelevant here; the listener is simply never invoked.

Reproduction steps

  1. Have a battery device that reports an identical percentage every
    report cycle (very common: many Zigbee sensors keep reporting
    battery: 100 until the battery actually degrades)
  2. Restart Home Assistant → _ensure_last_reported stamps
    last_reported = now for all devices
  3. Let the device keep reporting the same value (nothing changes on the
    HA side: no state writes, no events)
  4. Wait more than days_last_reported days
  5. Run battery_notes.check_battery_last_reported (daily automation):
    the device is falsely reported as "not reported", while it is alive
    and publishing (provable in MQTT logs and via fresh sibling entities)

Observed false alarm (15 of 16 devices were false positives)

  • Motion Sensor Garden: 1732 MQTT publishes/24h with battery field,
    battery sensor state frozen 90h
  • Motion Sensor Kitchen: 652 publishes/24h, same
  • Environment/leak sensors: 14-56 publishes/24h, same pattern
  • The only genuinely dead device (replaced hardware, 0 publishes in 7+
    days) was correctly reported — the check itself works, the clock just
    freezes for constant-value devices

Suggested fix direction

Treat device liveness separately from battery value changes. In
_async_battery_last_reported (services.py), before raising the event:
if any non-battery-notes entity of the same device (or the
source_entity_id for entity-based coordinators) had a state write within
the threshold window, the device is alive and reporting — refresh
last_reported instead of raising a false alarm. Truly dead devices (all
entities frozen) are still reported. No storage schema changes, no new
events, no recorder impact.

Happy to submit a PR implementing this (with the same-value/throttle
listener case handled too for integrations that do re-write identical
states).

System Health details

field value
version core-2026.9.1
installation_type Docker (homeassistant/home-assistant:latest)
os Linux (Docker host)
timezone Europe/Amsterdam

Debug logs

Debug logging was enabled during the investigation. The relevant
observation is not log noise but the absence of it: for affected devices
Entity id %s has been reported. (sensor.py) never appears after the
restart, because no state events arrive for the unchanged battery value —
while MQTT publishing of the same battery value continues every few
seconds (verified on the broker).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions