SAPIENT Data Fusion Node

The sapient-data-fusion-node service ingests BSI Flex 335 v2.0 SAPIENT messages from sensor nodes over TCP, fuses/tracks them, republishes the fused stream over UDP multicast, and exposes the current state (registered sensors and active tracks) over a small, self-describing read-only REST API.

Overview

  • TCP ingest listener for SAPIENT sensor nodes (length-framed protobuf).
  • UDP multicast republish of the fused/normalised stream.
  • Dedicated UDP multicast uplink channel for tasking (e.g. sensor move commands) fanned out to connected ingest sockets.
  • Read-only REST query API for current sensors/tracks, with an OpenAPI 3.0 document and a Swagger UI page served directly by the binary.

Runtime Topology

graph LR Sensor[SAPIENT Sensor Sources] -->|TCP :8080| Fusion[sapient-data-fusion-node] Fusion -->|UDP multicast :18080| Downstream[Fused Stream Subscribers] Tasking[Tasking Publisher] -->|UDP multicast :18081| Fusion Fusion -->|REST :8095| Client[REST / Swagger UI Clients]

Configuration

Loaded from a JSON config file (default /etc/gva/sapient-data-fusion-node.json), with command-line options overriding file values:

{
    "ingestHost": "0.0.0.0",
    "ingestPort": 8080,
    "restHost": "0.0.0.0",
    "restPort": 8095,
    "multicastGroup": "239.192.60.60",
    "multicastPort": 18080,
    "taskingMulticastGroup": "239.192.60.61",
    "taskingMulticastPort": 18081,
    "staleTimeoutSec": 300
}

Systemd env defaults are provided in:

  • src/qt6/sapient-data-fusion-node/debian/sapient-data-fusion-node.default

Command-Line Options

  • -c, --config <path>: JSON config file path
  • --ingest-host <host> / --ingest-port <port>
  • --rest-host <host> / --rest-port <port>
  • --multicast-group <group> / --multicast-port <port>
  • --tasking-multicast-group <group> / --tasking-multicast-port <port>
  • --stale-timeout <seconds>

REST API

All endpoints are GET-only and return application/json (except /docs, which returns HTML).

Endpoint Description
GET /health Service status and message/error counters
GET /api/sapient/sensors List all known sensor nodes
GET /api/sapient/sensors/{nodeId} Get a single sensor node by ID
GET /api/sapient/tracks List all currently fused object tracks
GET /api/sapient/tracks/{objectId} Get a single fused track by ID

OpenAPI / Swagger (self-describing API)

The REST API describes itself — no separate spec file to maintain:

Endpoint Description
GET /openapi.json Full OpenAPI 3.0.3 document (paths, parameters, response schemas) for every endpoint above
GET /docs (and GET /) Interactive Swagger UI, generated from /openapi.json

To access it, with the service running on its REST port (default 8095):

# Interactive docs in a browser
xdg-open http://127.0.0.1:8095/docs

# Raw OpenAPI document, e.g. to import into another tool
curl http://127.0.0.1:8095/openapi.json

Note

The Swagger UI page loads its JS/CSS assets (swagger-ui-dist) from a CDN, so /docs requires internet access from the browser. /openapi.json itself has no external dependency and works fully offline — it can be fed into any OpenAPI-compatible tool (Postman, Insomnia, codegen, etc.) even without internet access to the fusion node's host.

Run Locally

From build/:

./bin/sapient-data-fusion-node \
  --ingest-port 8080 \
  --rest-port 8095

Then open:

  • http://127.0.0.1:8095/docs — Swagger UI
  • http://127.0.0.1:8095/health — health check

Notes

  • sapient-web is a browser dashboard built on top of this REST API and requires sapient-data-fusion-node to be running and reachable.
  • CORS is enabled for REST responses (Access-Control-Allow-Origin: *).