★ New · feat/feeds + feat/stream

Subscribe to live feeds. Stream to ArcGIS.

Two complementary capabilities for storm ops and daily field awareness. Feed subscriptions poll OGC SensorThings, SOS, GTFS-realtime, and Moving Features sources — weather stations, grid sensors, live vehicle positions — into a dedicated DuckDB for SQL analytics on the map. The Esri-conformant StreamServer exposes that same moving data — plus MQTT feeds (including Meshtastic), TAK, and GNSS crew tracks — to ArcGIS Pro and the JS SDK as a native WebSocket StreamLayer.

OGC SensorThingsSOS / O&M 2.0GTFS-static & -rt Moving FeaturesEsri StreamServerWebSocketDuckDB history
Feed subscriptions

Five feed kinds, one DuckDB

Each feed type has its own adapter and writes rows into a dedicated feeds.duckdb registered under dbId = "feeds" — so feed tables flow through the existing OGC API Features / MVT / FeatureServer facades with no facade changes.

  • SensorThings — REST/JSON, Things → Datastreams → Observations.
  • SOS — SOAP/XML GetObservation, O&M 2.0.
  • GTFS-static + GTFS-realtime — zip → read_csv_auto with ST_MakeLine shapes; protobuf FeedMessage for live vehicle positions.
  • Moving Features — MF-JSON / MF-CSV → points + derived LINESTRING trajectory view.
  • Background polling with per-feed PeriodicTimer, retention trimming, and DPAPI-encrypted feeds.json profiles.
POST /api/feeds
// subscribe to a SensorThings endpoint
{
  "kind": "SensorThings",
  "url": "https://example/frost/v1.0",
  "intervalSeconds": 30,
  "retentionHours": 168
}

// rows land in feeds.sensorthings_observations
// → served at /api/spatial/feeds/collections/…
● polling · Polly-instrumented
In-App Screenshot

Real-Time Feeds Subscription Setup

VoltGrid desktop — Add Real-Time Feed modal dialog shown in default empty state
Add Real-Time Feed subscription modal dialog shown in default empty state ready for endpoint URL, type selection, and polling parameters
Esri-conformant StreamServer

A real ArcGIS StreamLayer source

High-performance native WebSockets that speak the ArcGIS SDK's own JSON protocol directly. Paste the catalog URL into ArcGIS Pro or a JS SDK StreamLayer and it just connects.

🔌

No negotiate handshake

Speaks the Esri JSON wire contract directly — camelCase via [JsonPropertyName], polymorphic messageType frames.

📡

Per-subscriber filters

Subscribers push {messageType:"filter"} to update their where + geometry slice of the stream.

🗄️

DuckDB-backed history

Parameterized-safe writes on a background thread so the hot path never blocks; historical query via /query.

🔄

Bidirectional ingest

Accepts either Esri {attributes,geometry} or GeoJSON FeatureCollection on /ingest.

💓

15s keep-alive

RFC 6455 ping frames keep subscribers alive through proxies and idle networks.

📊

Layer registry

Persisted to stream_layers.json with auto field discovery from the DuckDB table.

The API at a glance

Two endpoint families

FeatureEndpointNotes
FeedsGET / POST /api/feedsList / create a subscription
FeedsPOST /api/feeds/{id}/pause · /resume · /pollLifecycle control
FeedsGET /api/spatial/feeds/collections/{c}/itemsOGC API Features over feed tables
StreamGET /api/stream/{layerId}/StreamServerCatalog JSON with the ArcGIS StreamLayer URL
StreamGET /api/stream/{layerId}/subscribeThe WebSocket the SDK opens
StreamPOST /api/stream/{layerId}/ingestExternal push (Esri or GeoJSON)
StreamGET /api/stream/{layerId}/query?startMs=&endMs=Historical playback

Real-time feeds support standard OGC protocols, WebSocket JSON streaming, and canonical GTFS-realtime protobuf specifications.

Live data in. ArcGIS StreamLayer out.

From weather and grid sensors to live vehicle feeds, MQTT mesh packets, and TAK crew tracks — subscribe, store, and stream into the Esri clients your utility already runs. When the storm rolls in, the ops floor sees every truck move. Pairs with GRID State on the operational side.