One pipeline, two front doors
BACnet gateways publish readings over MQTT to AWS IoT Core. Historians and other systems POST readings to a webhook, which normalises them and republishes onto the same topic. From there a single ingestion function stores to DynamoDB and the S3 archive and publishes to AppSync subscriptions. There is no second writer, so a metric behaves the same whichever door it came through.
The webhook contract
The body is JSON with a platform, a source, the payload and adapter options. Authentication is an HMAC-SHA256 signature over the raw body in the x-indagate-signature header, not a bearer token; the endpoint fails closed with no secret configured and answers 401 to a bad signature without saying which part was wrong.
| Platform | Shape |
|---|---|
| OSIsoft PI Web API, Honeywell Uniformance | REST/JSON |
| Wonderware, Siemens WinCC, Emerson DeltaV | SQL row sets |
| openHistorian and the GPA stack | Measurement records with quality flags |
| Project Haystack | hisRead grids (JSON encoding) |
| Anything else | generic, with a field mapping naming the device, time, value, measure, unit and quality fields |
Timestamps are detected across ISO-8601, epoch seconds and milliseconds, .NET ticks and ODBC datetimes. Batches are capped at 5,000 readings with a hint to page; one bad reading does not discard the rest.
The adapters and the signing are implemented and tested. The public endpoint is being provisioned; until it is, integrations are exercised against a locally run handler. Transport to a vendor historian, such as authenticating to PI Web API, needs a real endpoint and in most cases a licence, and is arranged per deployment.