Adapter Contract
JSON telemetry event schema and NATS subject conventions.
All adapters — in-process drivers or external processes in any language — publish telemetry using this contract.
When to use which adapter
| Approach | Examples | Notes |
|---|---|---|
| In-process (orchestrator) | SIMULATOR, MQTT, SIEMENS_S7, OPC_UA | Configured on the device in the console; orchestrator manages lifecycle |
| External process | MELSEC_A1E, BECKHOFF_ADS, custom | Publish to NATS from iot/ or your own service using this schema |
| Not implemented | MODBUS_TCP | Device may show NOT_IMPLEMENTED until a driver ships |
See Plants, machines, and devices for console setup.
NATS subject
datahub.telemetry.<plantCode>.<deviceCode>Example: datahub.telemetry.gebze.s7-1500-01
JetStream persists events for history; Redis holds latest values for the UNS.
Event payload
{
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"tagPath": "gebze/press-line-01/s7-1500-01/motor.current",
"plantCode": "gebze",
"machineCode": "press-line-01",
"deviceCode": "s7-1500-01",
"tagCode": "motor.current",
"value": 12.7,
"valueType": "DOUBLE",
"unit": "A",
"quality": "GOOD",
"source": "SIMULATOR",
"sourceTimestamp": "2026-07-21T12:00:00.000Z",
"metadata": {}
}Field definitions
| Field | Type | Required | Description |
|---|---|---|---|
| eventId | UUID string | Yes | Unique per event; enables idempotent delivery |
| tagPath | string | Yes | Full hierarchy path |
| plantCode | string | Yes | Plant code |
| machineCode | string | Yes | Machine code |
| deviceCode | string | Yes | Device code |
| tagCode | string | Yes | Tag code |
| value | any | Yes | Tag value (number, string, boolean) |
| valueType | string | Yes | DOUBLE, INT, BOOL, STRING, etc. |
| unit | string | No | Engineering unit (A, °C, bar, etc.) |
| quality | string | Yes | GOOD, BAD, UNCERTAIN, TIMEOUT, DISCONNECTED, CONFIG_ERROR |
| source | string | Yes | Adapter identifier (SIMULATOR, MQTT, SIEMENS_S7, etc.) |
| sourceTimestamp | ISO 8601 | Yes | Timestamp from the source device |
| metadata | object | No | Adapter-specific metadata |
Control subjects
| Subject | Purpose |
|---|---|
datahub.rule.changed | Rule-worker reloads rule cache |
datahub.device.changed | Orchestrator reconciles adapters |
External adapter (Python)
The repository includes Python templates under iot/ that connect to field devices and publish to NATS:
- Configure NATS URL to reach the stack (
nats://…from your network) - Map reads to
tagPath,value,quality, andsourceTimestamp - Publish JSON payloads to
datahub.telemetry.<plant>.<device>per tag batching policy
Use the same eventId UUID per event for idempotent ingestion.
Programs and rules consume telemetry after it lands in NATS — external adapters do not need API credentials if NATS is reachable on your deployment network.
