v1.9.0-rc1
Pre-release
Pre-release
🌼 Pollen Levels v1.9.0-rc1
🧪 Release Candidate 1 for the 1.9.0 line.
Focus: newruntime_datapattern with a shared API client, dedicated coordinator module, richer setup/options flows, hardened per-day mode & numeric handling, and removal of HTTP Referer configuration for a simpler, safer setup.
🚀 Highlights
-
🧠 New runtime data pattern with shared API clients
- Runtime state now lives in
config_entry.runtime_data, using a singleGooglePollenApiClientper entry. - Sensors, diagnostics, and the
pollenlevels.force_updateservice all read coordinators from this runtime data, so each location reuses a single API client. - Unload clears
runtime_datato drop stale references and keep teardown tidy. Existing entities and identifiers remain unchanged.
- Runtime state now lives in
-
🧩 Dedicated coordinator module
- The
PollenDataUpdateCoordinatorclass and its helpers have been moved out ofsensor.pyinto a dedicatedcoordinator.pymodule. - This improves modularity and separation of concerns: sensors focus on entities, while the coordinator handles runtime orchestration.
- The
-
🗺️📆 Modernized setup & options (selectors + per-day mode)
- Initial setup now lets you choose forecast day count and per-day sensor mode with dropdown selectors shared with the options flow, keeping validation consistent.
- The options flow now uses selectors and normalizes numeric fields to integers, preserving existing rules and defaults.
- Per-day sensor mode is normalized, migrated into entry options, and respected even when options explicitly store
None, preventing unintended resets to"none".
-
🌐 Safer HTTP/auth handling (no more HTTP Referer config)
- HTTP 401 is treated like 403, surfacing
invalid_authduring setup and runtime instead of generic connection errors. - Setup shows 401/403 API messages via safe form placeholders, without exposing secrets.
- Runtime HTTP 403 now surfaces detailed messages without forcing re-auth, keeping setup vs. update behavior aligned.
- The previously introduced HTTP Referer (website restriction) option has been removed to simplify configuration, as referrer-based restrictions are not suitable for server-side integrations. Existing entries are migrated to drop legacy
http_referervalues.
- HTTP 401 is treated like 403, surfacing
-
⏱️ Stable numeric behavior (interval & forecast days)
- Update interval and forecast-day values are clamped to supported ranges, with update interval explicitly documented and enforced in the 1–24 hour range.
- Malformed or non-finite stored values are handled defensively in setup/options and sensor setup, preserving valid defaults and avoiding crashes.
-
🧪 Cleaner logs, better tests & diagnostics
- Debug logging is reduced by summarizing coordinator refreshes and sensor creation instead of logging full payloads.
- Translation coverage tests now include section titles and service metadata keys to keep locales aligned with
en.json. - The codebase has been reformatted with Black and Ruff for consistent imports and style.
pollenlevels.force_updatenow has a proper service name/description and awaits refreshes safely.
🔧 Detailed changes
Changed
- Moved runtime state to config entry
runtime_datawith a sharedGooglePollenApiClientper entry while keeping existing sensor behaviour and identifiers unchanged. - Updated sensors, diagnostics, and the
pollenlevels.force_updateservice to read coordinators from runtime data so each entry reuses a single API client for Google Pollen requests. - Treated HTTP 401 responses like 403 to surface
invalid_authduring setup validation and runtime calls instead of generic connection errors. - Restored API key validation during setup to raise
ConfigEntryAuthFailedwhen the key is missing instead of retrying endlessly. - Centralized config entry title normalization during setup so the cleaned device titles are reused across all sensors.
- Simplified metadata sensors by relying on inherited
unique_idanddevice_infoproperties instead of redefining them. - Updated the
force_updateservice to queue coordinator refreshes viaasync_request_refreshand added service coverage for entries lacking runtime data. - Cleared config entry
runtime_dataafter unload to drop stale coordinator references and keep teardown tidy. - Enabled forecast day count and per-day sensor mode selection during initial setup using dropdown selectors shared with the options flow to keep validation consistent.
- Enhanced setup validation to surface HTTP 401/403 API messages safely via the form error placeholders without exposing secrets.
- Updated the options flow to use selectors while normalizing numeric fields to integers and keeping existing validation rules and defaults intact.
- Runtime HTTP 403 responses now surface detailed messages without triggering reauthentication, keeping setup and update behavior aligned.
- Deduplicated HTTP error message extraction into a shared helper used by config validation and the runtime client to keep diagnostics consistent.
- Updated the options flow regression test to expect the new
invalid_forecast_dayserror code for out-of-range values. - Consolidated numeric options validation in the options flow through a shared helper to reduce duplication for interval and forecast day checks.
- Centralized the pollen client retry count into a shared
MAX_RETRIESconstant to simplify future tuning without touching request logic. - Tightened error extraction typing to expect
aiohttp.ClientResponsewhile guarding the import so environments without aiohttp can still run tests. - Reduced debug log volume by summarizing coordinator refreshes and sensor creation details instead of logging full payloads.
- Reformatted the codebase with Black and Ruff to keep imports and styling consistent with repository standards.
- Expanded translation coverage tests to include section titles and service metadata keys, ensuring locales stay aligned with
en.json. - Coordinator module extraction: moved the
PollenDataUpdateCoordinatorclass and its associated helper functions fromsensor.pyto a new, dedicatedcoordinator.pymodule, significantly improving modularity and separation of concerns. - Removed optional HTTP Referer (website restriction) support to simplify configuration, as it is not suitable for server-side integrations (existing entries are migrated to remove legacy
http_referervalues). - Documented the 1–24 update interval range in the README options list.
Fixed
- Avoid pre-filling the API key field when the form is re-displayed after validation errors.
- Added a fallback error message when unexpected client exceptions are raised to avoid empty
UpdateFailederrors in the UI. - Fixed options flow to preserve the stored per-day sensor mode when no override is set in entry options, preventing unintended resets to
"none". - Sanitized update interval defaults in setup and options forms to clamp malformed stored values within supported bounds.
- Rejected update interval submissions above 24 hours to match selector limits.
- Sanitized setup and options defaults for forecast days and per-day sensor mode selectors to keep UI defaults within supported choices.
- Normalized invalid stored per-day sensor mode values in the options flow to avoid persisting unsupported selector choices.
- Simplified the per-day sensor mode fallback during options submission to reuse the normalized current mode and prevent regressions.
- Migrated per-day sensor mode to entry options when stored in entry data to prevent option resets after upgrades.
- Centralized per-day sensor mode normalization to avoid duplicate validation logic across migration and options handling.
- Normalized invalid stored per-day sensor mode values already stored in entry options during migration to keep options consistent.
- Versioned config entries to ensure the per-day sensor mode migration runs once and is not repeated on every restart.
- Ensured unversioned entries run the per-day sensor mode migration and that option presence is respected even when the stored value is
None. - Moved the optional API key section directly below the API key field in the setup flow for improved visibility.
- Hardened HTTP client timeout handling and normalized non-string per-day sensor mode values defensively.
- Added entry context to migration failure logs for easier debugging.
- Removed a mutable default from the API key options schema to avoid shared state across config flow instances.
- Normalized whitespace-only per-day sensor mode values and preserved fallback to entry data when options explicitly store
None. - Removed redundant timeout handling in the HTTP client error path.
- Fixed the
force_updateservice to await coordinator refresh coroutines safely without passingNoneintoasyncio.gather. - Hardened parsing of update interval and forecast days to tolerate malformed stored values while keeping defaults intact.
- Hardened numeric parsing to handle non-finite values without crashing setup.
- Clamped update interval and forecast days in setup to supported ranges.
- Limited update interval to a maximum of 24 hours in setup and options.
- Clamped forecast day handling in sensor setup to the supported 1–5 range for consistent cleanup decisions.
- Avoided treating empty
indexInfoobjects as valid forecast indices. - Added
force_updateservice name/description for better UI discoverability. - Ensured migrations clean up legacy keys even when entries are already at the target version.
- Always removed per-day sensor mode from entry data during migration to avoid duplicated settings.
- Corrected Chinese setup description punctuation in
zh-Hansandzh-Hant.
If you test v1.9.0-rc1, please focus on:
- Behavior of runtime_data across reloads/unloads and how
pollenlevels.force_updatebehaves with multiple entries. - Setup/options flows (forecast days, per-day mode, and the 1–24h update interval range).
- Auth and HTTP error messaging, especially around 401/403 responses and missing/invalid API keys.
Feedback here will directly shape the final 1.9.0 stable release. 💬
What's Changed
- Handle missing source in device info by @eXPerience83 in #48
- Add files via upload by @eXPerience83 in #51
- Fix registry stubs for cleanup tests by @eXPerience83 in #54
- Codex/GitHub mention extract coordinator module and reduce debug by @eXPerience83 in #55
- Migrate per-day sensor mode to entry options and preserve in OptionsFlow (1.9.0-alpha4) by @eXPerience83 in #58
- fix(config_flow): sanitize update_interval selector defaults by @eXPerience83 in #59
- Align translation key ordering with en.json by @eXPerience83 in #60
- fix(migration): harden cleanup and normalize stored forecast mode values by @eXPerience83 in #61
Full Changelog: v1.8.6...v1.9.0-rc1