V1.7.0-6
HA 2026.6 compatibility, FCM crash-loop fix, registration classifier hardening
A targeted compatibility release on top of V1.7.0-5. The two headline
fixes resolve the OOM crash loop that appeared with Home Assistant Core
2026.6.0 (#176) and the WebSocket back-pressure / "Client unable to keep
up with pending messages" pattern reported in #151. Coverage and CI work
landed alongside the fixes to keep the integration honest about its
quality-scale tier during the ramp-up.
Fixes #176 — memory leak / OOM crash loop since HA 2026.6.0
Fixes #151 — integration overloads HA with pending events
🩺 FCM Listener Stability (the #176 fix)
- Per-entry short-run crash cap in the listener supervisor. If the
push client crashes ten times in a row in under thirty seconds after
actually reachingSTARTED, the supervisor stops restarting that
entry, raises a non-fixable Repairs issue with reload guidance, and
preserves the visible fatal state across recovery paths until a healthy
run is observed. Recovery is automatic on the next healthy run
(cap-latch released, Repairs issue cleared). - Pre-
STARTEDfailures excluded. A transient Google / MCS outage,
unreachable endpoint, or login retry burst no longer counts against
the cap, so a normal network blip does not disable push. - Poison-message handling. A single undecodable queued notification
(binascii.Error: Incorrect padding) is now skipped with a
selective ACK and a rate-limited warning instead of crashing the
listener and re-hitting the same message on every restart. The
ValueError("Credentials missing FCM key material")marker is
re-raised so legitimate auth failures still propagate. - Python 3.14 base64 strict-mode hardening.
base64.b64decodepaths
in the FCM helpers tolerate the new strict default without falling
into the crash loop pattern.
🔁 Registration Retry Classifier (the #151 contributing path)
- Numeric HTTP status as single source of truth in
gcm_register's
retry loop, replacing the previous substring-match classifier. - Last-wins semantics on the cached fatal status: a transient 5xx
after an earlier 401 / 404 no longer escalates through the
auth-failure recovery path and no longer invalidates FCM tokens
unnecessarily. Only the final exhausted response decides recovery
routing. - Structured
Error=body branch fixed so an HTTP-fatal status in a
structured error response still raisesFcmRegisterHTTPError(status)
instead of falling through toNone. - Wire-contract regression tests pin the classifier behaviour
against future drift.
🌊 Coordinator Back-Pressure (the #151 primary path)
- No more entity refresh storm on stat increments. Stat counters
(accuracy_sanitized,fused_sources,crowd_sourced_reports,
background_reports) are mutated in place and picked up on the next
real coordinator tick or push update, instead of fanning out a full
async_update_listeners()on every increment. On installations with
several devices and active FCM push, the 4096-message WebSocket queue
no longer fills within seconds. - No change for entity refresh rate on device tracker / location
sensors — those still update throughpush_updated().
🧹 HA 2026.x Compatibility & Repairs Hardening
- Deprecation cleanup for HA 2026.x: drops redundant
_attr_source_type, declaresPARALLEL_UPDATESon every platform,
declaresConfigEntry[RuntimeData]for strict typing, and names the
fallback reload tasks for debuggability. auth_expiredRepairs notification now passes the
{entry_title}placeholder it references in all eleven translation
files, and is consistent with its four sibling issues by being
non-fixable (is_fixable=False); the previously offered repair flow
did not exist.- Translation symmetry CI linter (AST-based, stdlib-only) walks
everyasync_create_issue()/async_create_repair_issue()call,
resolvestranslation_placeholders=dicts (with intra-procedural
constant propagation), and reports MISSING / UNUSED placeholders,
MISSING_TRANSLATION keys, and DEAD_KEY entries againststrings.json.
Wired into both.pre-commit-config.yamland the GitHub Actions
translationsjob. Three dormant translation drifts cleaned up.
🧪 Test Infrastructure & Coverage Sprint
- Phase 1–4 coverage ramp-up lands branch-coverage tests for the
pure helpers and simple mixin methods acrosscoordinator/helpers,
coordinator/registry,coordinator/identity,coordinator/polling,
coordinator/main,coordinator/locate, the__init__module, the
config_flow, and theapisurface. CI coverage floor stepped from
60 % → 63 % → 64 % → 66 % in lockstep with the merged phases. - Quality-scale tier temporarily declared as
bronzeduring the
coverage ramp-up; the platinum-tier strict-typing assertions
(ConfigEntry[RuntimeData]) and the strict-typing gate stay in place. - Canonical test fixtures and async-test contract (
tests/AGENTS.md)
consolidated; newRegistryStub/_DevRegStub/_EntRegStub
helpers; placeholder-symmetry linter wired as a gate. - First-party GitHub Actions bumped to Node-24 across the workflows.
📖 Documentation
- Bermuda BLE integration guide added at
docs/BERMUDA_INTEGRATION.mdwith a README pointer, including the
explicit callout that the FMDN-Finder Google-side upload remains
experimental and currently blocked (DroidGuard attestation
unavailable,FMDN_UPLOAD_ENABLED = False).
🐛 Closed Issues
- Fixes #176 — Memory leak / OOM crash loop since HA Core 2026.6.0.
- Fixes #151 — Integration overloads HA with pending events.
🙏 Acknowledgements
- @jleinenbach — drove the FCM crash-loop hardening (PRs #1084 /
#1085 / #1086), the registration classifier rewrite (PRs #1087 /
#1088), the HA 2026.x deprecation cleanup, the Repairs / translation
symmetry work (PR #1069), the platinum-drift fixes (PR #1071), the
coverage sprint, and the upstream forward-port (PR #178). - Everyone who reported the OOM crash on #176 and the pending-message
storm on #151 — the symptom descriptions made the root-cause analysis
much faster.
🧬 Bermuda Companion Fork
For local BLE presence detection with the EID resolver / FMDN Finder
listener, continue to use the matching Bermuda fork release shipped
with V1.7.0-5:
https://github.com/jleinenbach/bermuda/releases/tag/v0.6.8-GoogleFindMy-HA-5
Compatibility
- Target: Home Assistant Core 2026.6.x (and the 2026.6.0 → 2026.6.1
regression that surfaced #176 is resolved). - No config schema changes; existing entries continue to work without
re-auth.
Full Changelog: V1.7.0-5...V1.7.0-6