v0.4.0-beta.4
Pre-release
Pre-release
Pre-release for community validation (#128 round 4 / resilience batch).
First release carrying the diagnostics platform — bug reports can now
attach an anonymized Download diagnostics file — plus five coordinator
resilience fixes hardened across two adversarial review rounds. If you
upgraded through beta.1 on a solar contract: the one-time history heal now
also shows Solar sold this period the same cycle it finishes, instead of
blanking it for a day or more.
Added
- Diagnostics platform (
diagnostics.py): the integration card now has a
Download diagnostics button producing an anonymized JSON for bug
reports — refresh token redacted; account/contract numbers replaced
everywhere (statistic IDs and unique_id included) by stableanon-…
references; SPKI pins reduced to booleans. Payload carries integration
version, timezone, coordinator state (plan type, ToU bands, solar flags,
period totals, bill-period start, last update error), the one-time solar
heal record, and per-series statistics coverage (first_date,
last_date,row_count,last_sum) — the earliest-row field is what
makes a #128-class leading hole visible at a glance. Versioned by
schema_version(seedocs/diagnostics.md); the bug-report form now asks
for the file. - Faster recovery from failed polls (#155): a poll that fails with a
transient AGL error now retries after 30 minutes instead of silently
waiting a full 24 h (which looked exactly like "the poll never ran",
#126). The 24 h cadence restores on the next success; auth failures still
hand over to the reauth flow untouched. - Bounded give-up for stalled backfill chunks (#154): a contiguous span
of permanently-erroring solar days no longer refetches the identical
chunk forever — after 3 consecutive zero-progress cycles the span is
marked as covered (with a WARNING) so the backfill moves on. Rate-limited
sweeps never count toward the give-up.
Fixed
- AGL client transport shield (#151): network errors, timeouts, and a
200 response with a non-JSON body (e.g. a bot-protection challenge page)
now surface as retryableAGLErrorinstead of crashing the whole update
cycle. Previously a deterministic transport failure on an old
heal-window day could re-fire an unbounded 30-day sweep every cycle with
the integration unavailable throughout — the heal's give-up cap never
engaged because the crash bypassed its attempt accounting. Belt-and-
braces: a heal attempt is now counted on any sweep exit, even for
exception types the client fails to wrap. A network blip during token
refresh is likewise retryable and no longer masquerades as an auth
failure. - Period solar sensors no longer go blank during the one-time heal
(#152): a heal sweep that completes cleanly now waits for the recorder to
commit the rewritten rows and then publishes Solar sold this period /
feed-in credit this period the same cycle — no more 1–3 days of
unknownafter upgrading. Incomplete sweeps (rate-limited or skipped
days) stay suppressed: a wrong number is worse than a blank one. - Broken-chain repair survives heal give-up (#153): a downward
cumulative-sum step frozen by a rate limit on the heal's final attempt is
now detected after the heal is done and repaired by one bounded repair
generation (fresh attempt budget, markedrepairso it can never loop).
Lifetime sweeps are hard-capped either way.
Security
- Dev lockfile refreshed, clearing 19 of 24 open Dependabot alerts (aiohttp
3.13.5 → 3.14.1, cryptography 47.0.0 → 48.0.1, homeassistant 2026.5.1 →
2026.7.0, zeroconf 0.148.0 → 0.150.0, uv 0.11.8 → 0.11.25). The committed
uv.lockhad gone stale against thehomeassistant>=2026.7.0floor.
No user impact either way:manifest.jsonships zero Python
requirements — users get all of these libraries from their Home Assistant
core install, never from this integration. The remaining 5 alerts (PyJWT ≤
2.12.1) are pinned exactly by HA core and sit in code paths this repo never
imports (token-expiry decoding is a hand-rolled base64 of the JWT payload);
dismissed with reasons, will clear when HA bumps PyJWT upstream. aiohttpdev floor raised to>=3.14.1(HA 2026.7.0 relaxed its exact
pin), superseding Dependabot #106.