feat(state_511_atis): Castle Rock 511 adapter — Idaho incidents/closures/road work (v0.9.2)

Second CENTRAL_TRAFFIC adapter. Production code; central-supervisor + central-gui
restart (new adapter class + ADAPTER_GROUPS). No new stream -> no archive restart;
migration 026 adds the adapter row only. Ships disabled.

Two-endpoint join per layer: GET /map/mapIcons/<Layer> (markers: itemId + coords)
joined on id with POST /List/GetData/<Layer> (DataTables detail: roadwayName,
description, county, severity). The marker feed has coords but no text; the List
feed has text but no coords.

Layers -> event_types (wzdx category/subject precedent): Incidents->incident,
Closures->closure, Construction (type "Roadwork")->work_zone. category is
"<event_type>.state_511_atis"; subject central.traffic.<event_type>.<state>.
Severity 3 if isFullClosure else 1. Cadence 300s. Dedup inherited from the
v0.9.1 SourceAdapter mixin. enrichment_locations canonical (latitude,longitude)
from the marker join; county/state come upstream.

Templatized per state via settings {"states":[{code,base_url}]} but ships
Idaho-only: cross-state spot-checks refuted the shared-URL hypothesis (Oregon
TripCheck is HTML, Wyoming wyoroad 404 -- neither is Castle Rock). Add states as
settings rows once each host is verified.

Also fixes a latent test bug: test_consumer_doc per-adapter heading regex was
[a-z_]+ (no digits); state_511_atis is the first adapter name with digits, so
widened to [a-z0-9_]+.

Full suite: 759 passed, 1 skipped (central and unprivileged zvx, 3x each).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Johnson 2026-05-25 22:01:11 +00:00
commit 30e25bf475
15 changed files with 493 additions and 2 deletions

View file

@ -1476,6 +1476,47 @@ already running can disable those overlap categories via `EONETSettings.category
}
```
### state_511_atis — State 511 incidents / closures / road work (Castle Rock ATIS)
State-DOT 511 traffic events from the Castle Rock ATIS platform. Each layer is a
two-endpoint join: `GET /map/mapIcons/<Layer>` (markers: `itemId` + `location`
`[lat,lon]`) joined on id with `POST /List/GetData/<Layer>` (DataTables detail:
road name, description, county, severity). Verified for Idaho only.
- **Stream:** `CENTRAL_TRAFFIC`
- **Layers / event_types:** Incidents -> `incident`, Closures -> `closure`,
Construction (`type":"Roadwork"`) -> `work_zone`. (Cameras are telemetry and
ship as a separate adapter later.)
- **Subject pattern:** `central.traffic.<event_type>.<state>` (e.g.
`central.traffic.incident.id`); `<state>` is the lowercased config `code`.
- **GUI event_type:** from `category = "<event_type>.state_511_atis"` (first
dotted segment). `incident` and `closure` are new event_types (query-derived;
no hardcoded enum); `work_zone` is shared with wzdx.
- **Cadence default:** 300s (5 min).
- **Dedup key shape:** composite `<state_code>:<layer>:<id>`
(e.g. `ID:Incidents:33579`); reused as the inner `Event.id`.
- **Event.data fields:**
| key | type | nullable | description |
|---|---|---|---|
| `roadway_name` | str | yes | Road name, e.g. `US-95` |
| `description` | str | yes | Operator-readable narrative |
| `event_sub_type` | str | yes | e.g. `roadwayBlocked`, `longTermRoadConstruction` |
| `direction` | str | yes | `Both` / `North` / `Unknown` … |
| `location_description` | str | yes | Cross-street / landmark, e.g. `Five Mile Creek \| US-20` |
| `county` / `state` | str | yes | Upstream-supplied; populate the Location column |
| `start_date` / `last_updated` | str | yes | US-format local strings (no TZ; parsed naive->UTC, approximate) |
| `is_full_closure` | bool | yes | Closures only; drives severity |
| `layer` / `state_code` | str | no | Source layer + 2-letter state code (subject routing) |
| `latitude` / `longitude` | float | yes | From the marker join (enrichment input) |
- **Severity:** `is_full_closure == true` -> 3, else 1 (the upstream `severity`
string is "None" on most records; not mapped in v1).
- **Decipherable as-is:** mostly. Road + location + description + county/state are
user-ready; the geocoder fills `city` from the joined coordinates.
- **Removal semantics:** none in v1. Events age out of the upstream feed; the
14-day dedup sweep expires stale ids.
### wzdx — FHWA Work Zone Data Exchange (state-DOT work zones)
Active road work zones discovered from the federal WZDx Feed Registry and each