Document provider integration contracts
This commit is contained in:
101
docs/integrations/openweather.md
Normal file
101
docs/integrations/openweather.md
Normal 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`
|
||||
Reference in New Issue
Block a user