Skip to content
Proxus 2.0.0 Proxus 2.0: the largest release in Proxus history Release notes

How-to guide · for Developers, Engineers

MQTT and the UNS topics

Subscribe to live tag values on the MQTT broker built into every edge gateway, with the Unified Namespace topic layout, the JSON payloads and Sparkplug B.

At the end of this guide, an MQTT client of yours receives every tag value of a gateway's devices as it is read, on topics that follow the plant's Unified Namespace.

Before you start

You need:

  • The address of the edge gateway whose devices you want. Each gateway runs its own broker and publishes only its own devices. The hub's gateway, SYSTEM, publishes the devices assigned to it.
  • The gateway's MasterToken, from the [MQTTBroker] section of that gateway's configuration file. If it is empty when the gateway starts, the gateway creates one and writes it into the file.
  • Network access to the broker port: 8883 for TLS, or 1883 without TLS (MQTTBrokerPort).
  • For TLS: the platform CA, from Security > Certificate Store with Download CA.
  • Any MQTT 3.1.1 or 5 client: MQTT Explorer, mosquitto_sub, or a library such as Python paho-mqtt.

Step 1: Connect

SettingValue
Hostthe gateway's address
Port8883 with TLS, or 1883 (or MQTTBrokerPort) without TLS
User namethe gateway's MasterToken
Passwordempty
TLSon port 8883: verify the broker against the platform CA. See Connect with TLS.

The broker accepts a connection when the user name is the MasterToken, when it is the Token of a device on that gateway (shown on the device page), or when AllowAnonymous = true. Any other connection is refused with Not authorized.

Connect with TLS

The broker accepts TLS on port 8883 with the gateway's own certificate, which the hub issues from the Certificate Store. The port opens once the hub has issued the certificate.

  1. In Security > Certificate Store, select Download CA. The file holds the CA certificates (PEM), no private key.
  2. In your client, set port 8883 and use that file as the trusted CA. Connect to a host name or address that the gateway's certificate covers, because the name must match.
Terminal
mosquitto_sub -h <gateway-host> -p 8883 --cafile proxus-ca.pem -u "<MasterToken>" -t 'v1/#' -v

In the Python example below, call client.tls_set(ca_certs="proxus-ca.pem") and use port 8883.

Port 1883 stays open for devices without TLS. To accept TLS only, set [MQTTBroker] PlainEnabled = false. When the gateway's certificate is renewed, the broker restarts for a few seconds and clients connect again.

Step 2: Subscribe

Subscribe to v1/# for everything, or to a part of the tree. For example:

SubscriptionReceives
v1/#every topic of the gateway
v1/Meridian/Lyon_Foods_Plant/#everything of one site
v1/+/+/+/+/+/LYS_PACKER_04/telemetry/+each tag of one device, when its place has all five levels
uns_reader.py
import os
import paho.mqtt.client as mqtt

BROKER = "localhost"
PORT = 1883
TOKEN = os.environ["PROXUS_MQTT_TOKEN"]  # the gateway's MasterToken


def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    client.subscribe("v1/#")


def on_message(client, userdata, msg):
    print(msg.topic, msg.retain, msg.payload.decode())


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="uns-reader")
client.username_pw_set(TOKEN)
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, PORT)
client.loop_forever()

Run it with PROXUS_MQTT_TOKEN=<token> python3 uns_reader.py.

The topic layout

v1/<Enterprise>/<Site>/<Area>/<Line or cell>/<Equipment>/<Device>/<category>/<name>
  • v1 is the namespace version.
  • The place levels come from the device. A level that is empty is left out, so the topic is shorter. A device with only a site and an area publishes under v1/Lyon_Foods_Plant/Packaging/LYS_PACKER_04/...; a device with no place at all publishes under v1/<Device>/....
  • Every character that is not a letter, a digit, _ or - becomes _. Lyon Foods Plant becomes Lyon_Foods_Plant, Line 1 becomes Line_1.
  • <category> is telemetry for values and state for the device's state.
TopicRetainedSent
.../telemetry/<tag>noevery time the tag is read
.../telemetry/_summarynoall tags of the device in one message, at most every SummaryIntervalMs (5 s)
.../state/_lastSeenyesthe time of the latest reading, at most every LastSeenIntervalMs (5 s)
.../state/_statusyesOnline when values arrive, Offline when the device is disabled or deleted. For a device that publishes its own values (see below), also Offline when its client disconnects and Timeout after five minutes without values.

Retained messages are kept by the broker and sent to a new subscriber at once, so a client that connects later still learns the status of every device. Set UNSRetainMessages = false to turn retaining off.

The payloads

One tag value, on v1/Lyon_Foods_Plant/Packaging/LYS_PACKER_04/telemetry/Temperature:

{"ts":"2026-10-15T19:01:43.450Z","value":25.4,"dataType":"Double","unit":"°C","quality":"Good","source":"Proxus"}
FieldMeaning
tsWhen the value was read, UTC, ISO 8601 with milliseconds.
valueThe value as a JSON number, true/false or string.
dataTypeBool, Int, Long, Float, Double, DateTime or String. It is worked out from the value itself, so a UShort tag arrives as Int.
unitThe tag's unit. Left out when the tag has none.
qualityAlways Good on this topic. Values that could not be read are not published here; see the device page for read errors.
sourceAlways Proxus.

With TelemetryThinPayload = false, each tag message also carries a context object with enterprise, site, area, processCell, equipmentModule, deviceId, deviceName and metric.

The summary, on .../telemetry/_summary:

{
  "ts": "2026-10-15T19:01:46.955Z",
  "deviceId": "48",
  "deviceName": "MFB_LYS_MIXER_3",
  "metrics": {
    "Speed": {"value": 386, "dataType": "Int", "unit": "rpm", "quality": "Good"},
    "Running": {"value": true, "dataType": "Bool", "quality": "Good"}
  },
  "context": {"enterprise": "Meridian", "site": "Lyon Foods Plant", "area": "Processing",
              "processCell": "Dough", "equipmentModule": "_none"},
  "source": "Proxus"
}

context is left out when SummaryIncludeContext = false. _none means the device has no equipment level.

The state topics:

{"ts":"2026-10-15T19:01:39.551Z"}
{"status":"Online","ts":"2026-10-15T18:14:07.999Z"}
{"status":"Timeout","ts":"2026-10-15T19:20:00.000Z","reason":"Device timeout"}

Publish values from a device

A device or program can send its own values to the broker. It connects with the device's Token as user name and publishes JSON to the topic telemetry (or any topic under telemetry/). Each field becomes a tag of that device:

{"Temperature": 21.7, "DoorOpen": false, "Pressure": {"value": 2.4, "unit": "bar"}}

Nested objects become dotted names (Line.Speed), and arrays get an index (Axis[0]). The values then go through the same path as values the gateway reads itself: storage, pipelines, outbound targets and the UNS topics.

Writing to a device through MQTT, by publishing to a command topic, is not supported with the JSON format. Use a rule action or a pipeline to write values.

Sparkplug B

Set UNSPayloadFormat = "SparkplugB" in the [UNS] section of the gateway's configuration and restart the gateway. The gateway then publishes Sparkplug B 3.0 messages on its own broker instead of the JSON topics above:

  • Topic namespace spBv1.0/<UNSGroupId>/..., with the gateway as edge node <UNSEdgeNodeId>.
  • Each device is a Sparkplug device: a DBIRTH with its name, status, last-seen time and place, then DDATA with its tag values. Each metric carries Source, Quality and Unit properties.
  • The node answers the node commands Node Control/Rebirth (sends the births again), discovery and refresh_metadata.

Sparkplug host applications connect with the MasterToken as user name, the same as JSON clients.

Broker and UNS settings

These keys are in the gateway's configuration file. See Configuration keys for the environment-variable form.

KeyDefaultMeaning
[MQTTBroker] EnabledtrueRuns the broker on this gateway. With false there is no broker and no UNS publishing.
[MQTTBroker] MQTTBrokerPort1883The broker port. If it is taken, the gateway picks a free port and logs a warning, unless AllowPortFallback = false.
[MQTTBroker] TlsPort8883The TLS port, with the gateway's certificate. 0 turns TLS off.
[MQTTBroker] PlainEnabledtrueAccept connections without TLS on MQTTBrokerPort. false accepts TLS only.
[MQTTBroker] AllowAnonymousfalseAccept clients without a user name.
[MQTTBroker] MasterTokencreated at first startThe user name for UNS and Sparkplug clients.
[MQTTBroker] EnableMQTTHookstruePublishes the values the gateway reads to the UNS topics. With false, only values that devices publish themselves appear.
[UNS] UNSPayloadFormat"JSON"JSON or SparkplugB.
[UNS] UNSRetainMessagestrueRetain the state topics.
[UNS] UNSGroupId, UNSEdgeNodeId"ProxusGroup", "ProxusEdge"Sparkplug group and edge node.
[UNS.Optimizations] TelemetryThinPayloadtrueLeave context out of each tag message.
[UNS.Optimizations] SummaryIntervalMs5000Least time between two summaries of a device. 0 sends one with every reading.
[UNS.Optimizations] SummaryIncludeContexttruePut context in the summary.
[UNS.Optimizations] SummaryOnlyOnChangefalseSend a summary only when a value changed.
[UNS.Optimizations] LastSeenIntervalMs5000Least time between two _lastSeen messages.
[UNS.Optimizations] StatusOnChangeOnlytrueSend _status only when it changes.

The QoS levels are 0 for telemetry and 1 for state messages.

What's next

Was this page helpful?

Evaluating Proxus? See it on your own machines in a 30-minute technical session.