Merged SCHEMA.md into API.md and made some tweaks to ensure consistency with the underlying domain model.
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
This commit is contained in:
103
API.md
103
API.md
@@ -47,36 +47,22 @@ Each payload is described below using the JSON field names as the contract.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Shared conventions
|
## Shared Conventions
|
||||||
|
|
||||||
### Optional fields
|
- Timestamps are JSON strings in RFC3339Nano format.
|
||||||
|
- Optional fields are omitted when unknown (`omitempty` behavior).
|
||||||
Most non-identity measurements are optional. Optional fields are omitted when unknown (i.e., not present).
|
- Numeric measurements are normalized to metric units:
|
||||||
|
- `*C` = Celsius
|
||||||
### Units
|
- `*Kmh` = kilometers/hour
|
||||||
|
- `*Pa` = Pascals
|
||||||
Canonical payloads are normalized to metric units:
|
- `*Meters` = meters
|
||||||
|
- `*Mm` = millimeters
|
||||||
- Temperature: `*C` (Celsius)
|
- `*Percent` = percent (0-100)
|
||||||
- Wind speed/gust: `*Kmh` (kilometers/hour)
|
- `conditionCode` is a WMO weather interpretation code (`int`).
|
||||||
- Pressure: `*Pa` (Pascals)
|
- Unknown/unmappable is `-1`.
|
||||||
- Visibility / distance / elevation: `*Meters` (meters)
|
- Downstream consumers should treat unknown codes as “unknown conditions” rather than failing decoding.
|
||||||
- Precipitation amount / snowfall depth: `*Mm` (millimeters)
|
- For readability and stability, weatherfeeder rounds floating-point values in canonical payloads to
|
||||||
- Humidity / cloud cover / PoP: `*Percent` (0–100)
|
**4 digits after the decimal** during normalization.
|
||||||
|
|
||||||
### Float rounding
|
|
||||||
|
|
||||||
For readability and stability, weatherfeeder rounds floating-point values in canonical payloads to
|
|
||||||
**2 digits after the decimal** during normalization finalization.
|
|
||||||
|
|
||||||
### WMO condition codes
|
|
||||||
|
|
||||||
`conditionCode` uses the WMO weather interpretation code vocabulary.
|
|
||||||
|
|
||||||
- Type: integer
|
|
||||||
- Unknown/unmappable: `-1`
|
|
||||||
|
|
||||||
Downstream consumers should treat unknown codes as “unknown conditions” rather than failing decoding.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -88,31 +74,31 @@ A `WeatherObservation` represents a point-in-time observation for a station/loca
|
|||||||
|
|
||||||
### Fields
|
### Fields
|
||||||
|
|
||||||
| Field | Type | Required | Units / Notes |
|
| Field | Type | Required | Notes |
|
||||||
|---|---:|:---:|---|
|
|---|---:|:---:|---|
|
||||||
| `stationId` | string | no | Provider station/location identifier |
|
| `stationId` | string | no | Provider station/location identifier |
|
||||||
| `stationName` | string | no | Human name, if available |
|
| `stationName` | string | no | Human station name |
|
||||||
| `timestamp` | string (timestamp) | yes | Observation time |
|
| `timestamp` | timestamp string | yes | Observation timestamp |
|
||||||
| `conditionCode` | int | yes | WMO code (`-1` for unknown) |
|
| `conditionCode` | int | yes | WMO code (`-1` unknown) |
|
||||||
| `conditionText` | string | no | Canonical short text (often derived from WMO code) |
|
| `conditionText` | string | no | Canonical short condition text |
|
||||||
| `isDay` | bool | no | Day/night hint when available |
|
| `isDay` | bool | no | Day/night hint |
|
||||||
| `providerRawDescription` | string | no | Provider-specific “evidence” text |
|
| `providerRawDescription` | string | no | Provider-specific evidence text |
|
||||||
| `textDescription` | string | no | Legacy/transitional human text |
|
| `textDescription` | string | no | Legacy/transitional text description |
|
||||||
| `iconUrl` | string | no | Legacy/transitional icon URL |
|
| `iconUrl` | string | no | Legacy/transitional icon URL |
|
||||||
| `temperatureC` | number | no | °C |
|
| `temperatureC` | number | no | Celsius |
|
||||||
| `dewpointC` | number | no | °C |
|
| `dewpointC` | number | no | Celsius |
|
||||||
| `windDirectionDegrees` | number | no | Degrees (meteorological) |
|
| `windDirectionDegrees` | number | no | Degrees |
|
||||||
| `windSpeedKmh` | number | no | km/h |
|
| `windSpeedKmh` | number | no | km/h |
|
||||||
| `windGustKmh` | number | no | km/h |
|
| `windGustKmh` | number | no | km/h |
|
||||||
| `barometricPressurePa` | number | no | Pa |
|
| `barometricPressurePa` | number | no | Pascals |
|
||||||
| `seaLevelPressurePa` | number | no | Pa |
|
| `seaLevelPressurePa` | number | no | Pascals |
|
||||||
| `visibilityMeters` | number | no | meters |
|
| `visibilityMeters` | number | no | Meters |
|
||||||
| `relativeHumidityPercent` | number | no | percent (0–100) |
|
| `relativeHumidityPercent` | number | no | Percent |
|
||||||
| `apparentTemperatureC` | number | no | °C |
|
| `apparentTemperatureC` | number | no | Celsius |
|
||||||
| `elevationMeters` | number | no | meters |
|
| `elevationMeters` | number | no | Meters |
|
||||||
| `rawMessage` | string | no | Provider raw message (e.g. METAR), if available |
|
| `rawMessage` | string | no | Provider raw message (for example METAR) |
|
||||||
| `presentWeather` | array | no | Provider-specific structured fragments |
|
| `presentWeather` | array | no | Provider-specific structured weather fragments |
|
||||||
| `cloudLayers` | array | no | Cloud layers (base + amount) |
|
| `cloudLayers` | array | no | Cloud layer details |
|
||||||
|
|
||||||
### Nested: `cloudLayers[]`
|
### Nested: `cloudLayers[]`
|
||||||
|
|
||||||
@@ -156,7 +142,7 @@ A `WeatherForecastRun` is a single issued forecast snapshot for a location and a
|
|||||||
| `locationName` | string | no | Human name, if available |
|
| `locationName` | string | no | Human name, if available |
|
||||||
| `issuedAt` | string (timestamp) | yes | When this run was generated/issued |
|
| `issuedAt` | string (timestamp) | yes | When this run was generated/issued |
|
||||||
| `updatedAt` | string (timestamp) | no | Optional later update time |
|
| `updatedAt` | string (timestamp) | no | Optional later update time |
|
||||||
| `product` | string | yes | `"hourly"`, `"narrative"`, or `"daily"` |
|
| `product` | string | yes | One of `hourly`, `narrative`, `daily` |
|
||||||
| `latitude` | number | no | Degrees |
|
| `latitude` | number | no | Degrees |
|
||||||
| `longitude` | number | no | Degrees |
|
| `longitude` | number | no | Degrees |
|
||||||
| `elevationMeters` | number | no | meters |
|
| `elevationMeters` | number | no | meters |
|
||||||
@@ -220,14 +206,15 @@ A run may contain zero, one, or many alerts.
|
|||||||
| Field | Type | Required | Notes |
|
| Field | Type | Required | Notes |
|
||||||
|---|---:|:---:|---|
|
|---|---:|:---:|---|
|
||||||
| `id` | string | yes | Provider-stable identifier (often a URL/URI) |
|
| `id` | string | yes | Provider-stable identifier (often a URL/URI) |
|
||||||
| `event` | string | no | Classification |
|
| `event` | string | no | Classification/event label |
|
||||||
| `headline` | string | no | Short headline |
|
| `headline` | string | no | Alert headline |
|
||||||
| `severity` | string | no | e.g. Extreme/Severe/Moderate/Minor/Unknown |
|
| `severity` | string | no | Example: Extreme/Severe/Moderate/Minor/Unknown |
|
||||||
| `urgency` | string | no | e.g. Immediate/Expected/Future/Past/Unknown |
|
| `urgency` | string | no | Example: Immediate/Expected/Future/Past/Unknown |
|
||||||
| `certainty` | string | no | e.g. Observed/Likely/Possible/Unlikely/Unknown |
|
| `certainty` | string | no | Example: Observed/Likely/Possible/Unlikely/Unknown |
|
||||||
| `status` | string | no | e.g. Actual/Exercise/Test/System/Unknown |
|
| `status` | string | no | Example: Actual/Exercise/Test/System/Unknown |
|
||||||
| `messageType` | string | no | e.g. Alert/Update/Cancel |
|
| `messageType` | string | no | Example: Alert/Update/Cancel |
|
||||||
| `category` | string | no | e.g. Met/Geo/Safety/... |
|
| `category` | string | no | Example: Met/Geo/Safety/Rescue/Fire/Health/Env/Transport/Infra/CBRNE/Other |
|
||||||
|
| `response` | string | no | Example: Shelter/Evacuate/Prepare/Execute/Avoid/Monitor/Assess/AllClear/None |
|
||||||
| `response` | string | no | e.g. Shelter/Evacuate/Prepare/... |
|
| `response` | string | no | e.g. Shelter/Evacuate/Prepare/... |
|
||||||
| `description` | string | no | Narrative |
|
| `description` | string | no | Narrative |
|
||||||
| `instruction` | string | no | What to do |
|
| `instruction` | string | no | What to do |
|
||||||
|
|||||||
166
SCHEMA.md
166
SCHEMA.md
@@ -1,166 +0,0 @@
|
|||||||
# weatherfeeder Canonical Schemas
|
|
||||||
|
|
||||||
This document expressly defines the JSON payload schemas emitted by weatherfeeder for:
|
|
||||||
|
|
||||||
- `weather.observation.v1`
|
|
||||||
- `weather.forecast.v1`
|
|
||||||
- `weather.alert.v1`
|
|
||||||
|
|
||||||
These schemas are defined by the `internal/model` structs and their JSON tags.
|
|
||||||
|
|
||||||
## Shared Conventions
|
|
||||||
|
|
||||||
- Timestamps are JSON strings in RFC3339Nano format.
|
|
||||||
- Optional fields are omitted when unknown (`omitempty` behavior).
|
|
||||||
- Numeric measurements are normalized to metric units:
|
|
||||||
- `*C` = Celsius
|
|
||||||
- `*Kmh` = kilometers/hour
|
|
||||||
- `*Pa` = Pascals
|
|
||||||
- `*Meters` = meters
|
|
||||||
- `*Mm` = millimeters
|
|
||||||
- `*Percent` = percent (0-100)
|
|
||||||
- `conditionCode` is a WMO weather interpretation code (`int`).
|
|
||||||
- Unknown/unmappable is `-1`.
|
|
||||||
|
|
||||||
## `weather.observation.v1`
|
|
||||||
|
|
||||||
Payload type: `model.WeatherObservation`
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `stationId` | string | no | Provider station/location identifier |
|
|
||||||
| `stationName` | string | no | Human station name |
|
|
||||||
| `timestamp` | timestamp string | yes | Observation timestamp |
|
|
||||||
| `conditionCode` | int | yes | WMO code (`-1` unknown) |
|
|
||||||
| `conditionText` | string | no | Canonical short condition text |
|
|
||||||
| `isDay` | bool | no | Day/night hint |
|
|
||||||
| `providerRawDescription` | string | no | Provider-specific evidence text |
|
|
||||||
| `textDescription` | string | no | Legacy/transitional text description |
|
|
||||||
| `iconUrl` | string | no | Legacy/transitional icon URL |
|
|
||||||
| `temperatureC` | number | no | Celsius |
|
|
||||||
| `dewpointC` | number | no | Celsius |
|
|
||||||
| `windDirectionDegrees` | number | no | Degrees |
|
|
||||||
| `windSpeedKmh` | number | no | km/h |
|
|
||||||
| `windGustKmh` | number | no | km/h |
|
|
||||||
| `barometricPressurePa` | number | no | Pascals |
|
|
||||||
| `seaLevelPressurePa` | number | no | Pascals |
|
|
||||||
| `visibilityMeters` | number | no | Meters |
|
|
||||||
| `relativeHumidityPercent` | number | no | Percent |
|
|
||||||
| `apparentTemperatureC` | number | no | Celsius |
|
|
||||||
| `elevationMeters` | number | no | Meters |
|
|
||||||
| `rawMessage` | string | no | Provider raw message (for example METAR) |
|
|
||||||
| `presentWeather` | array | no | Provider-specific structured weather fragments |
|
|
||||||
| `cloudLayers` | array | no | Cloud layer details |
|
|
||||||
|
|
||||||
### `cloudLayers[]` (`model.CloudLayer`)
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `baseMeters` | number | no | Cloud base altitude in meters |
|
|
||||||
| `amount` | string | no | Provider amount code/text |
|
|
||||||
|
|
||||||
### `presentWeather[]` (`model.PresentWeather`)
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `raw` | object | no | Provider-specific object |
|
|
||||||
|
|
||||||
## `weather.forecast.v1`
|
|
||||||
|
|
||||||
Payload type: `model.WeatherForecastRun`
|
|
||||||
|
|
||||||
`product` values are:
|
|
||||||
|
|
||||||
- `"hourly"`
|
|
||||||
- `"narrative"`
|
|
||||||
- `"daily"`
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `locationId` | string | no | Provider location identifier |
|
|
||||||
| `locationName` | string | no | Human location name |
|
|
||||||
| `issuedAt` | timestamp string | yes | Forecast run issue/generated time |
|
|
||||||
| `updatedAt` | timestamp string | no | Optional later update time |
|
|
||||||
| `product` | string | yes | One of `hourly`, `narrative`, `daily` |
|
|
||||||
| `latitude` | number | no | Degrees |
|
|
||||||
| `longitude` | number | no | Degrees |
|
|
||||||
| `elevationMeters` | number | no | Meters |
|
|
||||||
| `periods` | array | yes | Forecast periods, intended chronological order |
|
|
||||||
|
|
||||||
### `periods[]` (`model.WeatherForecastPeriod`)
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `startTime` | timestamp string | yes | Start of validity window |
|
|
||||||
| `endTime` | timestamp string | yes | End of validity window |
|
|
||||||
| `name` | string | no | Human label (for example "Tonight") |
|
|
||||||
| `isDay` | bool | no | Day/night hint |
|
|
||||||
| `conditionCode` | int | yes | WMO code (`-1` unknown) |
|
|
||||||
| `conditionText` | string | no | Canonical short condition text |
|
|
||||||
| `providerRawDescription` | string | no | Provider-specific evidence text |
|
|
||||||
| `textDescription` | string | no | Short narrative text |
|
|
||||||
| `detailedText` | string | no | Longer narrative text |
|
|
||||||
| `iconUrl` | string | no | Legacy/transitional icon URL |
|
|
||||||
| `temperatureC` | number | no | Celsius |
|
|
||||||
| `temperatureCMin` | number | no | Celsius (aggregated periods) |
|
|
||||||
| `temperatureCMax` | number | no | Celsius (aggregated periods) |
|
|
||||||
| `dewpointC` | number | no | Celsius |
|
|
||||||
| `relativeHumidityPercent` | number | no | Percent |
|
|
||||||
| `windDirectionDegrees` | number | no | Degrees |
|
|
||||||
| `windSpeedKmh` | number | no | km/h |
|
|
||||||
| `windGustKmh` | number | no | km/h |
|
|
||||||
| `barometricPressurePa` | number | no | Pascals |
|
|
||||||
| `visibilityMeters` | number | no | Meters |
|
|
||||||
| `apparentTemperatureC` | number | no | Celsius |
|
|
||||||
| `cloudCoverPercent` | number | no | Percent |
|
|
||||||
| `probabilityOfPrecipitationPercent` | number | no | Percent |
|
|
||||||
| `precipitationAmountMm` | number | no | Liquid-equivalent millimeters |
|
|
||||||
| `snowfallDepthMm` | number | no | Millimeters |
|
|
||||||
| `uvIndex` | number | no | Unitless UV index |
|
|
||||||
|
|
||||||
## `weather.alert.v1`
|
|
||||||
|
|
||||||
Payload type: `model.WeatherAlertRun`
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `locationId` | string | no | Provider location identifier |
|
|
||||||
| `locationName` | string | no | Human location name |
|
|
||||||
| `asOf` | timestamp string | yes | Snapshot timestamp |
|
|
||||||
| `latitude` | number | no | Degrees |
|
|
||||||
| `longitude` | number | no | Degrees |
|
|
||||||
| `alerts` | array | yes | Active alerts in the snapshot |
|
|
||||||
|
|
||||||
### `alerts[]` (`model.WeatherAlert`)
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `id` | string | yes | Provider-stable ID, often URL/URI |
|
|
||||||
| `event` | string | no | Classification/event label |
|
|
||||||
| `headline` | string | no | Alert headline |
|
|
||||||
| `severity` | string | no | Example: Extreme/Severe/Moderate/Minor/Unknown |
|
|
||||||
| `urgency` | string | no | Example: Immediate/Expected/Future/Past/Unknown |
|
|
||||||
| `certainty` | string | no | Example: Observed/Likely/Possible/Unlikely/Unknown |
|
|
||||||
| `status` | string | no | Example: Actual/Exercise/Test/System/Unknown |
|
|
||||||
| `messageType` | string | no | Example: Alert/Update/Cancel |
|
|
||||||
| `category` | string | no | Example: Met/Geo/Safety/Rescue/Fire/Health/Env/Transport/Infra/CBRNE/Other |
|
|
||||||
| `response` | string | no | Example: Shelter/Evacuate/Prepare/Execute/Avoid/Monitor/Assess/AllClear/None |
|
|
||||||
| `description` | string | no | Narrative description |
|
|
||||||
| `instruction` | string | no | Recommended actions |
|
|
||||||
| `sent` | timestamp string | no | Provider-dependent |
|
|
||||||
| `effective` | timestamp string | no | Provider-dependent |
|
|
||||||
| `onset` | timestamp string | no | Provider-dependent |
|
|
||||||
| `expires` | timestamp string | no | Provider-dependent |
|
|
||||||
| `areaDescription` | string | no | Provider area text |
|
|
||||||
| `senderName` | string | no | Alert sender/source name |
|
|
||||||
| `references` | array | no | Related alerts |
|
|
||||||
|
|
||||||
### `references[]` (`model.AlertReference`)
|
|
||||||
|
|
||||||
| Field | Type | Required | Notes |
|
|
||||||
|---|---:|:---:|---|
|
|
||||||
| `id` | string | no | Related alert ID/URI |
|
|
||||||
| `identifier` | string | no | Provider identifier when distinct |
|
|
||||||
| `sender` | string | no | Sender |
|
|
||||||
| `sent` | timestamp string | no | Timestamp |
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user