145 lines
4.6 KiB
Markdown
145 lines
4.6 KiB
Markdown
# SPC Integration Notes
|
|
|
|
## Purpose
|
|
|
|
This document describes the Storm Prediction Center convective outlook usage
|
|
implemented by `weatherfeeder`. It is for developers and operators maintaining
|
|
SPC source configuration, provider helpers, 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 |
|
|
| --- | --- | --- | --- |
|
|
| `spc_convective_outlook` | `outlook` | `raw.spc.convective_outlook.v1` | `weather.outlook.v2` |
|
|
|
|
## Config Requirements
|
|
|
|
The driver requires:
|
|
|
|
- `latitude`
|
|
- `longitude`
|
|
- `user_agent`
|
|
|
|
Optional params are:
|
|
|
|
- `location_id`
|
|
- `location_name`
|
|
- `geojson_urls`
|
|
- `discussion_urls`
|
|
- `rss_url`
|
|
- `http_timeout`
|
|
- `http_response_body_limit_bytes`
|
|
|
|
RSS is not fetched unless `rss_url` is configured. URL override maps are intended
|
|
for tests and upstream URL changes; the default driver configuration owns the
|
|
current Day 1-3 SPC product URLs.
|
|
|
|
## Upstream Products Used
|
|
|
|
The source fetches nine required GeoJSON products every poll:
|
|
|
|
- Day 1 categorical, tornado, hail, and wind
|
|
- Day 2 categorical, tornado, hail, and wind
|
|
- Day 3 categorical
|
|
|
|
It also fetches three required print pages:
|
|
|
|
- Day 1 convective outlook print page
|
|
- Day 2 convective outlook print page
|
|
- Day 3 convective outlook print page
|
|
|
|
GeoJSON products are authoritative for outlook polygons, valid windows, issue
|
|
times, labels, and severity rank. Print pages are authoritative for run-level
|
|
day discussion headline, summary, and discussion text.
|
|
|
|
## Accept Headers
|
|
|
|
GeoJSON requests use:
|
|
|
|
```text
|
|
application/geo+json, application/json
|
|
```
|
|
|
|
Print-page requests use:
|
|
|
|
```text
|
|
text/html, application/xhtml+xml
|
|
```
|
|
|
|
RSS requests, when configured, use:
|
|
|
|
```text
|
|
application/rss+xml, application/xml, text/xml
|
|
```
|
|
|
|
## Polling And Raw Events
|
|
|
|
The source polls all required GeoJSON and print-page products as one bundle. If
|
|
any required request fails or returns a non-2xx response, the poll returns an
|
|
error and emits no partial event.
|
|
|
|
The raw payload contains fetched bodies plus configured location metadata and
|
|
per-product metadata. The source parses only the timestamp metadata needed for
|
|
event effective time selection; canonical mapping belongs to the normalizer.
|
|
|
|
The source emits no event when a complete fetched bundle is unchanged from the
|
|
previous successful poll. It does this with a source-local hash of the fetched
|
|
document bodies.
|
|
|
|
## Time Handling
|
|
|
|
Raw source `effective_at` prefers:
|
|
|
|
1. the latest valid GeoJSON `ISSUE_ISO`;
|
|
2. the latest print-page `Updated:` timestamp;
|
|
3. RSS `lastBuildDate` when RSS was fetched and parseable;
|
|
4. fetch time.
|
|
|
|
The normalizer sets canonical `asOf` and normalized event `effective_at` from
|
|
the latest valid GeoJSON issue time across the complete raw bundle, including
|
|
empty no-risk placeholders, with fallback to print-page update time and then the
|
|
incoming event envelope.
|
|
|
|
## Mapping Notes
|
|
|
|
The raw source fetches and envelopes the complete SPC bundle. The normalizer
|
|
decodes every configured GeoJSON product, skips empty no-risk
|
|
`GeometryCollection` placeholders, and emits canonical outlooks only when the
|
|
configured point is inside or on the boundary of a real feature. Products are
|
|
ordered by day, then categorical, tornado, hail, and wind. Retained feature order
|
|
is preserved within each product.
|
|
|
|
The normalizer computes `containsLocation` with the configured latitude and
|
|
longitude against compact GeoJSON `Polygon` or `MultiPolygon` geometry.
|
|
Coordinates use GeoJSON order, `[longitude, latitude]`, and boundary points
|
|
count as contained.
|
|
|
|
Canonical outlook runs are emitted even when no polygons apply locally. In that
|
|
case the payload contains empty `outlooks` and `discussions` arrays.
|
|
|
|
Print-page prose is represented as run-level day discussions. Discussions are
|
|
included only for days represented by at least one retained outlook. Multiple
|
|
retained outlook types for the same day share one discussion entry.
|
|
|
|
For downstream current-state and historical supersession guidance, see the
|
|
[event wire contract](events.md#spc-outlook-supersession).
|
|
|
|
## Failure Behavior
|
|
|
|
Constructor validation failures stop daemon startup. Polling failures are
|
|
returned to the scheduler and emit no event for that poll.
|
|
|
|
Normalization fails when required GeoJSON timestamps, labels, geometry, or
|
|
configured coordinates are missing or invalid. Print-page extraction failures
|
|
also fail normalization because print pages are required inputs.
|
|
|
|
## Tests To Inspect
|
|
|
|
- `internal/providers/spc/*_test.go`
|
|
- `internal/sources/spc/*_test.go`
|
|
- `internal/normalizers/spc/*_test.go`
|
|
- fixtures under `internal/providers/spc/testdata`
|