Skip to content

The Unified Namespace (UNS)

Every signal, no matter which OT protocol it started on, ends up on the broker under one consistent MQTT topic convention — the Unified Namespace. This is what lets a Modbus register, an OPC UA tag and a plain-MQTT sensor-node reading all land in the historian the same way, validated against the same signal registry.

A plain-JSON sample publishes to:

rw/v1/<site>/<area>/<line>/<cell>/<asset>/<signal>

matching the asset tree a site file (deploy/demo/site.yaml is the worked example) defines under areas/lines/cells/assets/signals. Short-window aggregates publish alongside the raw topic under rw/v1/<site>/$agg/1s/<area>/<line>/<cell>/<asset>/<signal>, so the UI can read a cheap rolling aggregate without re-deriving it from raw samples.

Sparkplug B payloads use the standard spBv1.0/# topic space instead of plain JSON, for devices or integrations that already speak Sparkplug.

  • One validation point. rw-ingest subscribes to both topic spaces as a shared subscription (so multiple ingest replicas can split the load) and checks every sample against the signal registry before it is written — a signal path that was never registered for that site is rejected rather than silently stored.
  • Protocol independence downstream. Everything after the broker — detectors, vision, the app, Ask — only ever reads from the historian by (site, signal). None of it needs to know whether a value originally came from Modbus, OPC UA or an MQTT sensor node.
  • One place to look. An engineer debugging a missing signal can subscribe to the broker directly and see the same topic the historian is validating against, instead of needing per-protocol tooling.

rw-edge builds the final topic segment from each device tag’s configured signal_path, which must match a signal id already present in the site’s registry — see Adapters for how a tag is configured per protocol, and Sensors & recipes for how that signal id is chosen in the first place.