Skip to content

v1.9.0-rc1

Pre-release
Pre-release

Choose a tag to compare

@eXPerience83 eXPerience83 released this 24 Dec 14:37
e9b485b

🌼 Pollen Levels v1.9.0-rc1

🧪 Release Candidate 1 for the 1.9.0 line.
Focus: new runtime_data pattern 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 single GooglePollenApiClient per entry.
    • Sensors, diagnostics, and the pollenlevels.force_update service all read coordinators from this runtime data, so each location reuses a single API client.
    • Unload clears runtime_data to drop stale references and keep teardown tidy. Existing entities and identifiers remain unchanged.
  • 🧩 Dedicated coordinator module

    • The PollenDataUpdateCoordinator class and its helpers have been moved out of sensor.py into a dedicated coordinator.py module.
    • This improves modularity and separation of concerns: sensors focus on entities, while the coordinator handles runtime orchestration.
  • 🗺️📆 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_auth during 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_referer values.
  • ⏱️ 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_update now has a proper service name/description and awaits refreshes safely.

🔧 Detailed changes

Changed

  • Moved runtime state to config entry runtime_data with a shared GooglePollenApiClient per entry while keeping existing sensor behaviour and identifiers unchanged.
  • Updated sensors, diagnostics, and the pollenlevels.force_update service 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_auth during setup validation and runtime calls instead of generic connection errors.
  • Restored API key validation during setup to raise ConfigEntryAuthFailed when 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_id and device_info properties instead of redefining them.
  • Updated the force_update service to queue coordinator refreshes via async_request_refresh and added service coverage for entries lacking runtime data.
  • Cleared config entry runtime_data after 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_days error 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_RETRIES constant to simplify future tuning without touching request logic.
  • Tightened error extraction typing to expect aiohttp.ClientResponse while 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 PollenDataUpdateCoordinator class and its associated helper functions from sensor.py to a new, dedicated coordinator.py module, 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_referer values).
  • 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 UpdateFailed errors 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_update service to await coordinator refresh coroutines safely without passing None into asyncio.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 indexInfo objects as valid forecast indices.
  • Added force_update service 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-Hans and zh-Hant.

If you test v1.9.0-rc1, please focus on:

  • Behavior of runtime_data across reloads/unloads and how pollenlevels.force_update behaves 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

Full Changelog: v1.8.6...v1.9.0-rc1