fix(document): Refresh runtime route docs

ecowitt_support
SchiZzA 2026-07-26 00:01:15 +02:00
parent 1bb8864426
commit 2827eac158
No known key found for this signature in database
4 changed files with 17 additions and 18 deletions

View File

@ -3,16 +3,15 @@
Architecture overview Architecture overview
--------------------- ---------------------
This integration is *push-based*: the weather station calls our HTTP endpoint and we This integration is *push-based*: the weather station calls our HTTP endpoint and we
receive a query payload. We do not poll the station. receive an HTTP payload. We do not poll the station.
Key building blocks: Key building blocks:
- `WeatherDataUpdateCoordinator` acts as an in-memory "data bus" for the latest payload. - `WeatherDataUpdateCoordinator` acts as an in-memory "data bus" for the latest payload.
On each webhook request we call `async_set_updated_data(...)` and all `CoordinatorEntity` On each webhook request we call `async_set_updated_data(...)` and all `CoordinatorEntity`
sensors get notified and update their states. sensors get notified and update their states.
- `hass.data[DOMAIN][entry_id]` is a per-entry *dict* that stores runtime state - `entry.runtime_data` stores per-entry runtime state (coordinator instance, options
(coordinator instance, options snapshot, and sensor platform callbacks). Keeping this snapshot, and sensor platform callbacks). Shared aiohttp route registrations stay
structure consistent is critical; mixing different value types under the same key can under `hass.data[DOMAIN]["routes"]` because they must survive a config-entry reload.
break listener wiring and make the UI appear "frozen".
Auto-discovery Auto-discovery
-------------- --------------
@ -99,9 +98,9 @@ def register_path(
) -> bool: ) -> bool:
"""Register webhook paths. """Register webhook paths.
We register both possible endpoints and use an internal dispatcher (`Routes`) to We register the supported station endpoints and use an internal dispatcher
enable exactly one of them. This lets us toggle WSLink mode without re-registering (`Routes`) to enable only the configured ingress path. This lets us toggle
routes on the aiohttp router. protocols without re-registering routes on the aiohttp router.
""" """
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})

View File

@ -71,8 +71,8 @@ def _configured_protocol(config: SWSConfigEntry) -> str:
"""Return the primary configured protocol (wu / wslink / ecowitt). """Return the primary configured protocol (wu / wslink / ecowitt).
The legacy PWS/WSLink endpoint takes precedence when enabled; otherwise an The legacy PWS/WSLink endpoint takes precedence when enabled; otherwise an
Ecowitt-only setup reports "ecowitt". (Legacy and Ecowitt can be enabled at the Ecowitt-only setup reports "ecowitt". If an old or externally edited config
same time; this just labels the primary protocol for the summary.) has both flags enabled, legacy still wins because that is the effective route.
""" """
if checked_or(config.options.get(LEGACY_ENABLED), bool, True): if checked_or(config.options.get(LEGACY_ENABLED), bool, True):
return "wslink" if checked_or(config.options.get(WSLINK), bool, False) else "wu" return "wslink" if checked_or(config.options.get(WSLINK), bool, False) else "wu"
@ -235,8 +235,8 @@ class HealthCoordinator(DataUpdateCoordinator):
reason = ingress.get("reason") reason = ingress.get("reason")
# A WU vs WSLink mismatch means the station is misconfigured for the legacy # A WU vs WSLink mismatch means the station is misconfigured for the legacy
# endpoint. Ecowitt coexists with the legacy endpoint, so it never counts as a # endpoint. Ecowitt has its own route and is considered valid only when an
# mismatch - it is a valid protocol whenever a payload arrives on its route. # accepted Ecowitt payload arrives there.
legacy_mismatch = ( legacy_mismatch = (
last_protocol in _LEGACY_PROTOCOLS last_protocol in _LEGACY_PROTOCOLS
and configured_protocol in _LEGACY_PROTOCOLS and configured_protocol in _LEGACY_PROTOCOLS

View File

@ -3,10 +3,10 @@
Why this dispatcher exists Why this dispatcher exists
-------------------------- --------------------------
Home Assistant registers aiohttp routes on startup. Re-registering or removing routes at runtime Home Assistant registers aiohttp routes on startup. Re-registering or removing routes at runtime
is awkward and error-prone (and can raise if routes already exist). This integration supports two is awkward and error-prone (and can raise if routes already exist). This integration supports
different push endpoints (legacy WU-style vs WSLink). To allow switching between them without multiple station push endpoints. To allow switching between them without touching the aiohttp
touching the aiohttp router, we register both routes once and use this in-process dispatcher to router, we register routes once and use this in-process dispatcher to decide which one is
decide which one is currently enabled. currently enabled.
Important note: Important note:
- Each route stores a *bound method* handler (e.g. `coordinator.received_data`). That means the - Each route stores a *bound method* handler (e.g. `coordinator.received_data`). That means the

View File

@ -5,7 +5,7 @@ These tests rely on `pytest-homeassistant-custom-component` to provide:
- `MockConfigEntry` helper for config entries - `MockConfigEntry` helper for config entries
They validate that the integration can set up a config entry and that the They validate that the integration can set up a config entry and that the
coordinator is created and stored in `hass.data`. coordinator is stored on `entry.runtime_data`.
Note: Note:
This integration registers aiohttp routes via `hass.http.app.router`. In this This integration registers aiohttp routes via `hass.http.app.router`. In this
@ -46,7 +46,7 @@ def config_entry() -> MockConfigEntry:
async def test_async_setup_entry_creates_runtime_state( async def test_async_setup_entry_creates_runtime_state(
hass, config_entry: MockConfigEntry, monkeypatch hass, config_entry: MockConfigEntry, monkeypatch
): ):
"""Setting up a config entry should succeed and populate hass.data.""" """Setting up a config entry should succeed and populate runtime state."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
# `async_setup_entry` calls `register_path`, which needs `hass.http`. # `async_setup_entry` calls `register_path`, which needs `hass.http`.