Document provider integration contracts

This commit is contained in:
2026-06-10 20:25:13 +00:00
parent 47176520bb
commit ec115ba152
4 changed files with 324 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
# OpenWeather Integration Notes
## Purpose
This document describes the OpenWeather current-weather usage implemented by
`weatherfeeder`. It is for developers and operators maintaining OpenWeather
source URLs, normalizers, fixtures, and tests.
General config syntax belongs in [configuration](../config.md). Emitted JSON
events are documented in [event wire contract](events.md).
## Implemented Driver
| Driver | Kind | Raw schema | Canonical schema |
| --- | --- | --- | --- |
| `openweather_observation` | `observation` | `raw.openweather.current.v1` | `weather.observation.v1` |
Only current-weather observation polling is registered for OpenWeather.
## Config Requirements
The driver requires HTTP source params:
- `url`
- `user_agent`
The shared HTTP helper also accepts `conditional`, `http_timeout`, and
`http_response_body_limit_bytes`. Conditional requests are enabled by default;
an upstream `304 Not Modified` response emits no event for that poll.
The configured URL must include:
```text
units=metric
```
Startup fails if `units` is omitted or set to another value. Keep OpenWeather
API keys out of committed configs. Use local config management or deployment
secrets for the `appid` query parameter.
## Upstream Shape Used
The source emits the full current-weather JSON payload as a raw event. The
normalizer uses:
- `coord.lat`, `coord.lon`;
- primary `weather[0]` condition ID, description, and icon;
- `main.temp`, `main.feels_like`, `main.pressure`, `main.humidity`, and
optional `main.sea_level`;
- `visibility`;
- `wind.speed`, `wind.deg`, and `wind.gust`;
- `dt`;
- `sys.sunrise` and `sys.sunset`;
- `id` and `name`.
## Accept Header
OpenWeather sources request:
```text
application/json
```
## Time Handling
Source events set `effective_at` from `dt` when it is present and positive.
The normalizer also uses `dt` as the canonical observation timestamp and
normalized effective time.
## Mapping Notes
Metric units are required so canonical unit conversion is deterministic:
- `main.temp` and `main.feels_like` are treated as Celsius;
- `wind.speed` and `wind.gust` are treated as meters per second and converted to
kilometers per hour;
- pressure values are treated as hPa and converted to Pa.
The primary condition is `weather[0]`. OpenWeather condition IDs are mapped into
the canonical WMO code vocabulary. The human text description is preserved from
the provider description.
Day/night is inferred from the OpenWeather icon suffix when available, otherwise
from sunrise and sunset bounds.
The station ID uses the OpenWeather city ID when present. If no city ID is
present, weatherfeeder synthesizes an ID from coordinates. The station name uses
the provider `name`, falling back to `OpenWeatherMap` when blank.
## Failure Behavior
Constructor validation failures stop daemon startup. Polling also re-checks the
metric-unit requirement before fetching. HTTP failures are returned to the
scheduler. Metadata decoding failures in the source still allow raw payload
emission when the HTTP response itself succeeded.
## Tests To Inspect
- `internal/sources/openweather/source_test.go`
- `internal/normalizers/openweather/*_test.go`
- `internal/providers/openweather/*_test.go`