v1.12.0 - Token caching
What changed
The integration now caches the AEL session token across coordinator polls instead of re-running the full 5-step authentication every hour. Steady-state load drops from 8 requests/poll (5 auth + 3 fetch) to 3 requests/poll (just the data fetches). The full auth handshake is only re-run when the cached token actually stops working.
Why it matters
- Less load on the SOMEI/Veolia portal — friendlier behaviour shared with all integration users
- Faster polls (no need to walk through 5 sequential HTTP round-trips first)
- Same reliability: a 401/403 from any fetch transparently triggers re-authentication and one retry
Behavioural details
authenticate()is now idempotent — short-circuits when an AEL token is already cached. The coordinator's existing call pattern (authenticate(); fetch()) becomes free after the first cycle.- 401/403 responses on fetches now raise the new
EauxDeMarseilleSessionExpiredError(subclass ofEauxDeMarseilleApiError, so existing catch clauses still work). - The high-level client funnels both
fetch()andfetch_monthly_range()through a small recovery wrapper:- Authenticates first if no token is cached.
- On
EauxDeMarseilleSessionExpiredError, invalidates the cache, re-authenticates, retries the action exactly once. - Any other exception (auth failure, transport, generic 4xx, 5xx after retries) propagates unchanged.
- Bounded recovery: a second 401 surfaces normally to the coordinator →
ConfigEntryAuthFailed→ reauth flow. No infinite loop.
Verified
- Full local validation (ruff, mypy strict, pytest 36 passed — 6 new tests for session recovery)
- All 5 CI jobs green
- Live smoke test on a Raspberry Pi against SEM (Ventabren contract)
Test coverage added
test_authenticate_is_idempotenttest_fetch_skips_redundant_authtest_fetch_recovers_from_401test_403_also_triggers_recoverytest_repeated_session_expiry_propagatestest_other_4xx_does_not_trigger_reauth— confirms a 404 does NOT trigger re-auth (would mask real bugs)
Closes #12.