Files
weatherfeeder/docs/integrations/openmeteo.md

102 lines
3.6 KiB
Markdown

# Open-Meteo Integration Notes
## Purpose
This document describes the Open-Meteo API usage currently implemented by
`weatherfeeder`. It is for developers and operators maintaining Open-Meteo
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 Drivers
| Driver | Kind | Raw schema | Canonical schema |
| --- | --- | --- | --- |
| `openmeteo_observation` | `observation` | `raw.openmeteo.current.v1` | `weather.observation.v1` |
| `openmeteo_forecast` | `forecast` | `raw.openmeteo.hourly.forecast.v1` | `weather.forecast.v1` |
## Config Requirements
Both drivers require 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.
## Upstream Shapes Used
`openmeteo_observation` expects a JSON response with top-level location/timezone
metadata and a `current` object. The normalizer uses:
- `latitude`, `longitude`, `timezone`, `utc_offset_seconds`;
- `current.time`;
- current temperature, apparent temperature, relative humidity, weather code,
wind speed/direction/gusts, pressure, and `is_day`.
`openmeteo_forecast` expects top-level location/timezone metadata and an
array-oriented `hourly` object. The normalizer uses:
- `hourly.time`;
- hourly temperature, apparent temperature, dew point, relative humidity,
precipitation probability, precipitation amount, snowfall, weather code,
pressure, wind speed/direction/gusts, `is_day`, cloud cover, visibility, and
UV index.
Open-Meteo field presence is allowed to vary. Missing optional arrays produce
nil canonical fields for the affected periods.
## Accept Header
Open-Meteo sources request:
```text
application/json
```
## Time Handling
Open-Meteo timestamps often omit an explicit offset. The provider helper parses
times by using the returned `timezone` or `utc_offset_seconds` when needed.
Observation source events set `effective_at` from `current.time` when it can be
parsed. Hourly forecast source events prefer `current.time`, then the first
non-empty `hourly.time` entry.
The hourly forecast normalizer sets canonical `issuedAt` from the incoming event
`emitted_at` when present, otherwise from the first hourly period start.
Normalized forecast `effective_at` matches `issuedAt`.
## Mapping Notes
Open-Meteo is not a station feed. Weatherfeeder synthesizes canonical
station/location IDs from latitude and longitude when both are available.
Open-Meteo weather codes are WMO codes and are treated as authoritative.
Canonical text is derived from the WMO code and day/night hint.
Wind speed and gust fields are treated as kilometers per hour. Pressure values
are treated as hPa and converted to Pa. Snowfall values are treated as
centimeters and converted to millimeters.
Hourly forecast period end time is the next period start. The last period uses
the previous interval length, or one hour when there is no previous interval.
## Failure Behavior
Constructor validation failures stop daemon startup. Polling failures are
returned to the scheduler. Metadata decoding failures in sources still allow raw
payload emission when the HTTP response itself succeeded.
Normalization fails when required time data is missing or invalid, such as an
empty `hourly.time` array for hourly forecasts.
## Tests To Inspect
- `internal/sources/openmeteo/source_test.go`
- `internal/normalizers/openmeteo/*_test.go`
- `internal/providers/openmeteo/*_test.go`