The MQTT Publishers configuration page defines outbound connections to MQTT brokers. EnvisionSCADA publishes the values of linked project variables to the broker when they change and, when Subscribe is switched on, accepts writes for those variables from the broker.
Each MQTT publisher is one broker connection with its own topic structure and payload format. Several publishers can run side by side, for example one publisher that sends every value to its own topic on a plant broker and one that sends JSON messages to a single topic of a cloud IoT hub.
The variables are selected on the variable itself, in the same way as the OPC UA setting. Every variable has an MQTT Publisher field on the Gateway tab of its variable dialog. A variable whose MQTT Publisher field holds the name of a publisher is published by that publisher, so each variable is linked to one publisher at most. Variables of every device type can be linked, including Local variables, MQTT variables, and OPC UA variables. For variables created from a UDT definition, the field is set on the variable member.
MQTT Publishers works independently of the MQTT configuration pages and of the MQTT Broker. MQTT clients, devices, and variables read and write the variables of MQTT devices through topics configured per variable. The MQTT Broker is the broker built into EnvisionSCADA. An MQTT publisher connects to an external broker, or to the built-in MQTT Broker, as an ordinary MQTT client.
With Payload Format Sparkplug B, a publisher is a Sparkplug B edge node. It publishes the linked variables in the Sparkplug B topic namespace, with birth and death certificates, metric aliases, data types, and quality, and it accepts Sparkplug commands. A Sparkplug host application, for example an MQTT device with Protocol Sparkplug B in another EnvisionSCADA system, then receives the variables without a topic per variable. See Sparkplug B Edge Node.
Open the page from Configuration > MQTT Publishers. The page is available to users of the Administrators group.
Publisher List
Create a new publisher with the Add button in the toolbar. The Add Publisher dialog contains all publisher settings organized in the sections General, Connection, Topic and Payload, Subscribe, and Diagnostics, with default values already filled in. Enter at least the Name and the Broker URL and press Create.
The publisher row shows Enable, Name, Broker, Payload Format, Variables, Subscribe, Status, and Description. Enable, Name, Broker URL and Port, Payload Format, Subscribe, and Description can be edited in place. The other settings can be added to the grid with the Columns button and are edited in place as well. Press the Settings icon on a publisher row to open the Edit Publisher dialog, which contains the same sections and all settings of the publisher. Press Save to apply the changes.
Each row offers three actions: Settings opens the Edit Publisher dialog, Publisher Variables opens the list of variables linked to the publisher, and Delete removes the publisher. The toolbar offers Import and Export in CSV or JSON format, Delete for the selected publishers, Search, and Columns. The Enable check box in the column header enables or disables all publishers after a confirmation.
Saving changed settings restarts that publisher only. It reconnects to the broker and publishes the current value of every linked variable again. The other publishers keep their connection.
| Column | Description |
|---|---|
| Enable | Enables the publisher. Only an enabled publisher connects to the broker and publishes its linked variables. |
| Name | Unique publisher name. Variables refer to the publisher by this name in their MQTT Publisher field. |
| Broker | Broker URL and Port of the broker, edited as two fields. |
| Payload Format | Value Only or JSON Template. |
| Variables | Number of variables whose MQTT Publisher field names this publisher, including disabled variables and variables of disabled devices. Click the number to open the Publisher Variables page. |
| Subscribe | Accepts writes from the broker for linked variables that are Writeable. |
| Status | Connection state of the publisher: Connected, Connecting, Reconnecting, Disabled, or Standby. The value refreshes every second. |
| Description | Free text description for documentation purposes. |
No rows match the filter.
Add Publisher and Edit Publisher Dialog
The Add Publisher and Edit Publisher dialogs show the settings on the left and the Payload Preview on the right. The settings are grouped in the sections General, Connection, Topic and Payload, Sparkplug B, Subscribe, and Diagnostics, described below.
Fields that apply to another choice are disabled, and their values are kept and saved. Payload Template is available when Payload Format is JSON Template. With Payload Format Sparkplug B, the Sparkplug B section is shown, and Topic Template, TimeStamp Format, Payload Template, QoS, Retain, Status Topic, Write Topic Template, Write Value Key, Write Name Key, and Republish Interval are hidden. Write Topic Template, Write Value Key, and Write Name Key are available when Subscribe is switched on.
In the Edit Publisher dialog, the Publisher Variables button at the bottom opens the list of variables linked to the publisher.
General
| Setting | Description | Example |
|---|---|---|
| Name | Unique name of the publisher, made of letters, digits, and underscores. The MQTT Publisher field of a variable must match the name exactly, including upper and lower case. Two publishers whose names differ by case only are refused. | SiteUNS |
| Description | Free text description for documentation purposes. | Site broker |
| Enable | Enables the publisher. Only an enabled publisher connects to the broker and publishes its linked variables. | true |
No rows match the filter.
Connection
| Setting | Description | Example |
|---|---|---|
| Broker URL | Host name or IP address of the broker. Required. | 192.168.1.10 |
| Port | TCP port of the broker, 1 to 65535. 1883 is the usual port without TLS, 8883 the usual port with TLS. | 1883 |
| Client Id | MQTT client identifier. When empty, ENVISION-<Name> is used. The identifier is the same on every connect, so the broker sees one client per publisher. | ENVISION-SiteUNS |
| Username | User name for broker authentication. Leave empty to connect without credentials. | envision |
| Password | Password for broker authentication. After saving, the field shows a mask. Saving the mask keeps the stored password; any other value, an empty value included, replaces it. | |
| Use TLS | Connects to the broker over TLS. | false |
| Allow Untrusted Certificates | Accepts a broker certificate that does not validate, for example a self-signed certificate. Applies when Use TLS is switched on. | false |
| Client Certificate Name | Subject name of a client certificate in the certificate store of the local computer (LocalMachine\My). On Docker the certificate is read from the files in the /app/certs/tls folder, the same as on the MQTT Clients page. The certificate is presented to the broker when Use TLS is switched on. Leave empty to connect without a client certificate. | envision01 |
| Protocol Version | MQTT protocol version: 3.1.1 or 5.0. | 5.0 |
| Keep Alive (s) | Keep alive interval in seconds, 1 to 65535. | 30 |
| Timeout (s) | Time in seconds to wait for the broker when connecting, publishing, and subscribing, 1 to 3600. | 6 |
| Retry (s) | Time in seconds between connection attempts after a failed connection, 1 to 3600. After a lost connection, the first attempt is made immediately. | 3 |
No rows match the filter.
Topic and Payload
| Setting | Description | Example |
|---|---|---|
| Topic Template | Topic each linked variable is published to. A template with {FullName}, {TopicPath}, or {VariableName} gives every variable its own topic. Required. The MQTT wildcards + and # are refused. | envision/{TopicPath} |
| Payload Format | Value Only: the payload is the value of the variable as text. JSON Template: the payload is the Payload Template with the tokens replaced. Sparkplug B: the publisher is a Sparkplug B edge node, see Sparkplug B Edge Node. | Value Only |
| TimeStamp Format | Format of the {TimeStamp} token: ISO 8601 (UTC), Unix Milliseconds, Unix Seconds, or Custom. | ISO 8601 (UTC) |
| Custom Format | Shown when TimeStamp Format is Custom. A .NET custom date and time format, applied to the time stamp in UTC. | yyyy-MM-dd HH:mm:ss |
| Payload Template | JSON message used when Payload Format is JSON Template. The template must produce valid JSON. | {"tag":"{FullName}","value":{VariableValue},"ts":"{TimeStamp}"} |
| QoS | MQTT quality of service of the published messages, of the status messages, and of the write subscriptions: 0, 1, or 2. | 1 |
| Retain | Publishes with the retain flag, so a client that subscribes later receives the last value at once. Switch Retain off when all variables share one topic. | true |
| Status Topic | Topic for the connection status of the publisher: online after every connect, offline when the publisher stops or loses its connection. Leave empty to publish no status. | envision/status |
No rows match the filter.
Below the Payload Template, the available tokens are listed. Click a token to insert it in the last focused template field: Topic Template, Payload Template, or Write Topic Template. Inside quotes a token is inserted escaped; outside quotes it is inserted as a JSON value. The tokens are described in Topic and Payload Tokens.
Sparkplug B
| Setting | Description | Example |
|---|---|---|
| Group ID | Sparkplug group ID, the second element of every Sparkplug topic. Required with Payload Format Sparkplug B. The characters +, /, and # are refused. | Site1 |
| Edge Node ID | Sparkplug edge node ID. Leave empty to use the Name of the publisher. The characters +, /, and # are refused. Group ID and Edge Node ID together must differ from every other Sparkplug B publisher. | Envision01 |
| Device Mapping | Device: every device is a Sparkplug device, and its linked variables are the metrics of that device. Local variables are metrics of the edge node. Node: every linked variable is a metric of the edge node. See Sparkplug B Edge Node. | Device |
| Primary Host ID | Host ID of the Sparkplug Primary Host Application. Leave empty to publish the birth certificates as soon as the connection is made. When set, the publisher publishes only while the primary host reports online. | EnvisionHost |
No rows match the filter.
Subscribe
| Setting | Description | Example |
|---|---|---|
| Subscribe | Accepts writes from the broker for linked variables that are Writeable. Switched off by default. With Payload Format Sparkplug B, Subscribe accepts Sparkplug NCMD and DCMD commands for linked variables that are Writeable. A Node Control/Rebirth request is always honoured. | false |
| Write Topic Template | Topic on which writes are received. With Write Name Key empty, every Writeable variable gets its own write topic, built from {Topic} (the topic of the variable) or from the tokens {FullName}, {TopicPath}, and {VariableName}. With Write Name Key set, enter one fixed topic without tokens. | {Topic}/set |
| Write Value Key | Leave empty to use the whole payload as the value. Otherwise the JSON path to the value inside a JSON payload. | data.value |
| Write Name Key | Leave empty to identify the variable by its write topic. Otherwise the JSON path to the full variable name inside a JSON payload received on the single topic of Write Topic Template. | name |
No rows match the filter.
Diagnostics
| Setting | Description | Example |
|---|---|---|
| Republish Interval (s) | Interval in seconds at which every linked variable is published again, 0 to 86400. With 0, variables are published on change and after every connect. | 0 |
| Minimum Interval (ms) | Minimum time in milliseconds between two publishes of the same variable, 0 to 3600000. A change within that time is held back and the latest value is sent once the time has passed. 0 sets no minimum. | 0 |
| Verbose | Logging level of the publisher, 0 to 2. See Status and Diagnostics. | 0 |
No rows match the filter.
Payload Preview
The Payload Preview on the right of the dialog shows the result of the current settings while they are typed: the Topic, the Payload, and the Write Topic of one variable. Select the variable under Linked variable. The list holds up to 25 variables linked to the publisher. For a new publisher, or a publisher without linked variables, the preview uses the example variable PLC1.Pump1.Speed.
Payload shows No value yet: not sent for a Value Only publisher when the selected variable has no value yet. Write Topic shows - while Subscribe is switched off, and is dimmed when the selected variable is not Writeable.
Below the preview, every rule the current settings break is listed as a warning, with the same texts as the validation on save. The settings are validated again when the publisher is saved.
With Payload Format Sparkplug B, Topic shows the NDATA or DDATA topic of the selected variable, Birth Topic shows its NBIRTH or DBIRTH topic, Payload shows the metric as the birth certificate carries it (name, time stamp, data type, and value), and Write Topic shows the NCMD or DCMD topic while Subscribe is switched on.
Topic and Payload Tokens
Tokens are written in braces and are replaced per variable when a message is published. The examples are for the Modbus TCP variable PLC1.Pump1_Speed on device PLC1, with asset Plant/Line1, data type REAL, units rpm, description Pump 1 speed, value 1450.5, and status Good, published by the publisher SiteUNS with the Topic Template envision/{TopicPath}.
| Token | Description | Templates | Example |
|---|---|---|---|
| {FullName} | Full variable name. | Topic Template, Payload Template, Write Topic Template | PLC1.Pump1_Speed |
| {TopicPath} | Full variable name with every dot replaced by a slash. | Topic Template, Payload Template, Write Topic Template | PLC1/Pump1_Speed |
| {DeviceName} | Device the variable belongs to. Local for a Local variable. | Topic Template, Payload Template, Write Topic Template | PLC1 |
| {VariableName} | Variable name without the device name in front of it. | Topic Template, Payload Template, Write Topic Template | Pump1_Speed |
| {Asset} | Asset path of the variable. | Topic Template, Payload Template, Write Topic Template | Plant/Line1 |
| {Publisher} | Name of the publisher. | Topic Template, Payload Template, Write Topic Template | SiteUNS |
| {Topic} | Topic of the variable, rendered from the Topic Template. | Write Topic Template | envision/PLC1/Pump1_Speed |
| {VariableValue} | Value of the variable. | Payload Template | 1450.5 |
| {TimeStamp} | Time stamp of the value in UTC, in the TimeStamp Format. | Payload Template | 2026-10-09T08:15:30.125Z |
| {Status} | Status of the variable as a number. | Payload Template | 0 |
| {StatusText} | Status of the variable as text. | Payload Template | Good |
| {Units} | Engineering units of the variable. | Payload Template | rpm |
| {DataType} | Data type of the variable. | Payload Template | REAL |
| {Description} | Description of the variable. | Payload Template | Pump 1 speed |
No rows match the filter.
{DeviceName} and {VariableName} are taken from the device the variable belongs to, not from the dots in the name. For PLC1.Pump1_Speed on device PLC1, {VariableName} is Pump1_Speed. For a variable named Pump1_Speed on device PLC1, {DeviceName} is PLC1 and {VariableName} is Pump1_Speed as well. For the Local variable Counter, {DeviceName} is Local, and {VariableName}, {FullName}, and {TopicPath} are Counter.
{Status} is the number and {StatusText} the name of the variable status: Good (0), Disabled (1), ConnectionLost (2), FormatError (3), Timeout (4), Warning (5), and Unknown (6). See Variable Status.
A token used in a template where it is not available, and any other text in braces, is left unchanged.
Value Only and JSON Template
With Value Only, the payload is the value of the variable as text, exactly as it is stored, with a dot as decimal separator, for example 1450.5. The message carries no status and no time stamp. A variable is published once it has a value: a device variable after its driver delivered the first value, a Local variable and a variable of a simulated device from the start. This prevents an empty retained message, which a broker treats as the instruction to delete the retained value of the topic.
With JSON Template, the payload is the Payload Template with the tokens replaced. The template must produce valid JSON; this is checked when the publisher is saved, by rendering the template for a sample variable. Each token is inserted according to its position in the template:
| Position | Token | Inserted as |
|---|---|---|
| Inside quotes | Every token | The text of the token, JSON escaped: quotes, backslashes, and control characters are escaped. {VariableValue} is the value text, or empty when the variable has no value. |
| Outside quotes | {VariableValue} | A JSON number for numeric data types, true or false for Boolean data types, a quoted string for text data types and for values that are not a finite number, and null when the variable has no value. |
| Outside quotes | {Status} | A JSON number. |
| Outside quotes | {TimeStamp} | A JSON number with Unix Milliseconds and Unix Seconds, a quoted string with the other formats. |
| Outside quotes | Every other token | A quoted string. |
No rows match the filter.
{"tag":"{FullName}","value":{VariableValue},"unit":"{Units}","quality":"{StatusText}","ts":"{TimeStamp}"}{"tag":"PLC1.Pump1_Speed","value":1450.5,"unit":"rpm","quality":"Good","ts":"2026-10-09T08:15:30.125Z"}Both forms are valid. {"value":{VariableValue}} sends 1450.5 as a JSON number, and {"value":"{VariableValue}"} sends "1450.5" as a JSON string. A Boolean variable is sent as true or false in the first form and as its value text in the second form.
A full state publish, after a connect, at the Republish Interval, or when a variable becomes linked, sends variables that have a value. A status change of a variable without a value, for example a lost connection before the first reading, is published with null as {VariableValue}.
TimeStamp Format
TimeStamp Format sets how the {TimeStamp} token of a JSON Template is written. The time stamp is the time of the value of the variable, converted to UTC, not the time the message is sent. A Value Only payload carries no time stamp.
| Option | Output | Example |
|---|---|---|
| ISO 8601 (UTC) | Date and time in UTC with milliseconds, yyyy-MM-ddTHH:mm:ss.fffZ. | 2026-10-09T08:15:30.125Z |
| Unix Milliseconds | Milliseconds since 1970-01-01 00:00:00 UTC. | 1791533730125 |
| Unix Seconds | Whole seconds since 1970-01-01 00:00:00 UTC. | 1791533730 |
| Custom | The .NET custom date and time format entered in Custom Format, applied to the time in UTC. A format that cannot be applied is refused on save. | yyyy-MM-dd HH:mm:ss gives 2026-10-09 08:15:30 |
No rows match the filter.
Per-Variable Topics and Single Topic
A Topic Template that contains {FullName}, {TopicPath}, or {VariableName} gives every variable its own topic, for example envision/{TopicPath}. This is the usual layout for a broker that holds the current state of the plant. With Retain switched on, the broker keeps the last value of every topic, so a client that subscribes later receives the current state at once. {FullName} and {TopicPath} are unique per variable.
A Topic Template without one of these tokens sends every variable to the same topic, for example the event topic of a cloud IoT hub. Such a publisher requires Retain switched off, because a retained message on a shared topic holds one arbitrary variable, and Payload Format JSON Template with {FullName}, {TopicPath}, or {VariableName} in the Payload Template, so the receiver can tell the variables apart.
Topic Template: site1/{TopicPath}
Payload Format: Value Only
Retain: on
Topic: site1/PLC1/Pump1_Speed
Payload: 1450.5Topic Template: devices/envision01/messages/events
Payload Format: JSON Template
Payload Template: {"deviceId":"envision01","tag":"{FullName}","value":{VariableValue},"unit":"{Units}","quality":"{StatusText}","ts":"{TimeStamp}"}
Retain: off
Topic: devices/envision01/messages/events
Payload: {"deviceId":"envision01","tag":"PLC1.Pump1_Speed","value":1450.5,"unit":"rpm","quality":"Good","ts":"2026-10-09T08:15:30.125Z"}When two variables render the same topic, for example with the Topic Template site1/{VariableName} and a Pump1_Speed variable on two devices, the variable that comes first when sorted by full name is published to that topic. The other variable is marked Topic collision on the Publisher Variables page and is reported once in the System Log. A variable whose rendered topic is empty, contains + or #, or equals the Status Topic is marked Invalid topic: not sent.
Status Topic and Last Will
When Status Topic is set, the publisher registers the Last Will message offline on that topic, retained and with the QoS of the publisher. After every connect, the publisher publishes online on the Status Topic, retained. When the publisher stops, for example because it is disabled, changed, or deleted, or because the node becomes the standby node, it publishes offline before it disconnects. When the connection drops without a normal disconnect, the broker publishes the Last Will offline. A subscriber of the Status Topic therefore always reads whether the publisher is online.
The Status Topic must not contain + or #. Choose a Status Topic that differs from the topics of the linked variables: a variable whose topic equals the Status Topic is held back and marked Invalid topic: not sent.
Writes from the Broker
With Subscribe switched on, the publisher subscribes to write topics at the broker and writes the received values to the linked variables. A message is written when all of the following conditions are met:
- Subscribe is switched on for the publisher.
- The variable is linked to this publisher through its MQTT Publisher field.
- The variable is Writeable.
- A Local variable has External Source enabled.
- The variable and its device are enabled.
- The message was published without the retain flag. Retained messages are ignored, because the broker delivers them again on every reconnect and the same write would be repeated.
- The node is the primary node.
Per-variable write topics. With Write Name Key empty, every linked Writeable variable gets its own write topic from the Write Topic Template. The default {Topic}/set adds /set to the topic of the variable, so PLC1.Pump1_Speed, published on envision/PLC1/Pump1_Speed, is written through envision/PLC1/Pump1_Speed/set. The write topic must differ from the topic of the variable, because the publisher would otherwise receive its own messages as writes. {Topic} gives a unique write topic per variable when the Topic Template contains a per-variable token.
Topic: envision/PLC1/Pump1_Speed/set
Payload: 1500Single command topic. With Write Name Key set, the publisher subscribes once to the fixed topic entered in Write Topic Template, and every message names the variable in its JSON payload. Write Name Key is the JSON path to the full variable name, and the named variable must be linked to this publisher. Set Write Value Key as well, so the value is read from the same JSON payload.
Topic: envision/commands
Payload: {"name":"PLC1.Pump1_Speed","data":{"value":1500}}Write Value Key. With Write Value Key empty, the whole payload is the value, for example 1500. An empty payload is ignored. With Write Value Key set, the payload must be JSON, and Write Value Key is the JSON path to the value, for example data.value for the value field inside a data object. The path must point to a single value: a number, a string, true, or false. The values true and false, as JSON values or as text, are written as 1 and 0.
An accepted write is recorded as a historic event with the identity MqttPublisher and the message SetValue <variable> <value> (<publisher>, <topic>), for example SetValue PLC1.Pump1_Speed 1500 (SiteUNS, envision/PLC1/Pump1_Speed/set). The value is then written in the same way as a Set Value action. When the value of the variable changes, the new value is published on the topic of the variable; the write topic carries commands only.
The publisher connects with a clean session. A command that is sent while EnvisionSCADA is disconnected from the broker is not delivered later, so an old command is never applied after a reconnect. With Protocol Version 5.0, the write subscriptions also ask the broker to send no retained messages at subscribe time and to return none of the publisher's own messages.
A refused message is logged in the System Log with its reason, for example not Writeable, when Verbose is 1 or higher.
Sparkplug B Edge Node
With Payload Format Sparkplug B, the publisher is a Sparkplug B edge node as defined by the Eclipse Sparkplug 3.0 specification. Every message uses the topic spBv1.0/<Group ID>/<message type>/<Edge Node ID>, followed by /<device> for the messages of a Sparkplug device, and carries a binary Sparkplug B payload. Birth, data, and device death messages are published with QoS 0 and without the retain flag. The death certificate of the edge node is registered as the Last Will with QoS 1. The publisher uses these message types:
| Message | Direction | Description |
|---|---|---|
| NBIRTH | Published | Birth certificate of the edge node: the session number bdSeq, the metric Node Control/Rebirth, and every edge node metric with its name, alias, data type, time stamp, and value. |
| DBIRTH | Published | Birth certificate of one Sparkplug device, with every metric of that device. |
| NDATA, DDATA | Published | Changed values of edge node metrics and device metrics, identified by alias. |
| NDEATH | Published | Death certificate of the edge node with its bdSeq. Registered as the Last Will at every connect, and published when the publisher stops. |
| DDEATH | Published | Death certificate of a Sparkplug device whose variables are no longer linked to the publisher, and of every Sparkplug device before the NDEATH when the publisher stops. |
| NCMD, DCMD | Received | Commands of a host application: Node Control/Rebirth and writes to metrics. |
| STATE | Received | State of the Primary Host Application named in Primary Host ID. |
No rows match the filter.
Device Mapping decides how the linked variables are arranged. The metric name is the variable name with every dot replaced by a slash. With Device Mapping Device, the device name at the start of the variable name is left out of the metric name. The table shows the variable PLC1.Pump1_Speed of device PLC1 and the Local variable Counter:
| Device Mapping | Variable | Sparkplug device | Metric name |
|---|---|---|---|
| Device | PLC1.Pump1_Speed | PLC1 | Pump1_Speed |
| Device | Counter | Edge node | Counter |
| Node | PLC1.Pump1_Speed | Edge node | PLC1/Pump1_Speed |
| Node | Counter | Edge node | Counter |
No rows match the filter.
Birth certificates and data. After every connect, the publisher publishes its birth certificates: NBIRTH, followed by one DBIRTH per Sparkplug device. With Primary Host ID set, it first waits until the primary host reports online. After the birth certificates, a change of the value or the status of a linked variable is published in NDATA or DDATA. Values that did not change are not published again, so Republish Interval is not used. Minimum Interval applies as for the other formats.
The publisher publishes new birth certificates with the same bdSeq when a host application sends Node Control/Rebirth, and 2 seconds after the set of linked metrics changed, for example when a variable is linked, unlinked, renamed, or changes its data type. A Sparkplug device whose variables are all unlinked receives a DDEATH first.
bdSeq. bdSeq is the session number of the edge node, from 0 to 255. It increases with every connection, is stored in the configuration database, and is replicated to the standby node, so it continues after a restart and after a failover.
The data type of a metric follows the data type of the variable. Variables of other protocols use the type of the same size, for example Float for an OPC UA Float variable and Boolean for a BACnet binary object.
| Data type of the variable | Sparkplug data type |
|---|---|
| BOOL | Boolean |
| BYTE | UInt8 |
| INT | Int16 |
| UINT, WORD | UInt16 |
| DINT | Int32 |
| UDINT, DWORD | UInt32 |
| LINT | Int64 |
| ULINT | UInt64 |
| REAL | Float |
| LREAL | Double |
| DateTime (OPC UA) | DateTime |
| STRING and other types | String |
No rows match the filter.
The status of a variable is published as the Quality property of its metric, with the values defined by Sparkplug B. In a birth certificate, the property is present when the quality is not GOOD. In NDATA and DDATA, it is present when the quality changed, including the return to GOOD. A variable without a value is published as a null value. A value that does not match the data type of the metric is published as a null value with the quality BAD and is logged in the System Log.
| Status | Quality |
|---|---|
| Good, Warning | 192 (GOOD) |
| Unknown, Timeout | 500 (STALE) |
| ConnectionLost, FormatError, Disabled | 0 (BAD) |
No rows match the filter.
Primary host. With Primary Host ID set, the publisher subscribes to the STATE topic spBv1.0/STATE/<Primary Host ID> and publishes its birth certificates only while the primary host reports online. Until then, the Status of the publisher is Waiting for Host. When the primary host reports offline, the publisher publishes its NDEATH, disconnects, connects again, and waits for the primary host. An MQTT client of EnvisionSCADA is a primary host when its Sparkplug Host ID is set, see the MQTT article.
Commands. With Subscribe switched on, a metric in an NCMD or DCMD command is written to the linked variable of that metric, identified by alias or by name, when the variable is Writeable. The conditions of Writes from the Broker apply, and the write is recorded as a historic event with the identity MqttPublisher, for example SetValue PLC1.Pump1_Speed 1500 (SiteEdge, spBv1.0/Site1/DCMD/Envision01/PLC1, metric Pump1_Speed). A Node Control/Rebirth request is always accepted, also with Subscribe switched off. Retained commands are ignored.
Publishing
A linked variable is published while the variable and its device are enabled. It is published when its value or its status changes. Changes are collected in a short window of 100 ms, so a variable that changes several times within that window is published once, with its latest state. A pulse shorter than the window is therefore not visible on the broker. Use the Historian or a Data Forwarder when every change must be recorded.
After every connect, the publisher publishes the current state of every linked variable. A variable that becomes linked, for example when its MQTT Publisher field is set or when it is created with the field already set, is published once with its current value. Changes made while the broker was unreachable are covered by this full state publish after the reconnect and are not replayed one by one.
Republish Interval publishes the full state again at a fixed interval. Minimum Interval limits how often one variable is published: a change within the interval is held back, and the latest value is sent once the interval has passed.
When the broker refuses a publish for a temporary reason, for example Quota exceeded, the variable is sent again after a delay that starts at 1 second and doubles up to 60 seconds. After a permanent refusal, for example Not authorized, the variable is sent again with its next change, at the next Republish Interval, or after the next connect.
Publisher Variables
The Publisher Variables page lists every variable linked to one publisher, with the topics the publisher uses for each variable and its live value. A variable that is disabled, or whose device is disabled, is listed with the Status Disabled and the note Not running: the variable or its device is disabled, because the publisher does not publish it. Open it with the number in the Variables column, with the Publisher Variables icon on the publisher row, or with the Publisher Variables button in the Edit Publisher dialog. The page is read-only. A link is changed on the variable or on its UDT member.
The header shows the publisher name, the broker, the Status of the publisher, the Payload Format, and whether Subscribe is switched on. Live Value, Status, and the Status of the publisher refresh every second. The Variables column of the publisher list counts the same links, including disabled variables and variables of disabled devices.
For a Sparkplug B publisher, the header also shows the Group ID and the Edge Node ID, and the list shows the columns Sparkplug Device, Metric Name, and Alias. Topic is the NDATA or DDATA topic and Write Topic the NCMD or DCMD topic of the metric. Alias is the alias of the metric in the current birth certificate.
| Column | Description |
|---|---|
| Variable | Full variable name. |
| Device | Device the variable belongs to. Local for a Local variable. |
| Asset | Asset path of the variable. |
| DataType | Data type of the variable. |
| Writeable | Writeable setting of the variable. |
| Sparkplug Device | Sparkplug B only. Sparkplug device of the metric. Empty for a metric of the edge node. |
| Metric Name | Sparkplug B only. Name of the metric. |
| Alias | Sparkplug B only. Alias of the metric in the current birth certificate. Empty before the first birth certificate. |
| Topic | Topic the variable is published to. |
| Write Topic | Write topic of the variable. Shown when Subscribe is switched on and the variable is Writeable. |
| Live Value | Current value of the variable. |
| Status | Current status of the variable. |
| Last Published | Time of the last publish of the variable by the running publisher, in the local time of the server. - when the variable was not published since the publisher started. |
| Notes | Remarks about the variable, see the table below. |
No rows match the filter.
The Notes column shows why a variable is held back and whether writes are accepted:
| Note | Meaning |
|---|---|
| No value yet: not sent | The variable has no value yet. It is published once it has one. |
| Invalid topic: not sent | The rendered topic is empty, contains + or #, or equals the Status Topic. |
| Topic collision | Another variable that comes first when sorted by full name uses the same topic, so this variable is held back. Hover over the note to see the other variable. |
| Invalid metric: not sent | Sparkplug B only. The metric name is empty or reserved (bdSeq or a name starting with Node Control/), or the device name is not a valid Sparkplug device ID. |
| Metric collision | Sparkplug B only. Another variable that comes first when sorted by full name has the same Sparkplug device and metric name, so this variable is held back. |
| Write topic subscribed | The write topic of the variable is subscribed at the broker, so writes for this variable are accepted. |
| Not running: the variable or its device is disabled | The variable or its device is disabled. The variable keeps its link and is published once both are enabled. |
No rows match the filter.
Linking Variables
A variable is linked to a publisher through its MQTT Publisher field. Open the variable dialog on any variable configuration page and select the Gateway tab. The tab holds Modbus Address, OPC UA, Writeable, MQTT Publisher, Kafka Device, Kafka Remap Device, and Kafka Remap Variable. Enter the publisher name in MQTT Publisher, or press the ... button next to the field to select a publisher from the list. The (none) entry clears the field. An empty field means the variable is not published. Writes from the broker also need Writeable on the same tab.
The MQTT Publisher field must name an existing publisher, with the same upper and lower case. The check is made when the field is changed, so a variable whose link was imported without a check stays editable in its other fields.
The variable grids offer MQTT Publisher as a column that can be added with the Columns button. The column shows the link of every variable, filters the list on a publisher, and can be edited in place.
For variables created from a UDT definition, set MQTT Publisher on the variable member, in the Gateway group of the member details. The field accepts tokens, for example {Broker} for a definition parameter named Broker, so each instance can be published by its own publisher. A push writes the resolved name to every materialized variable, and the field of a materialized variable is managed by the definition like the other member settings. When the resolved name matches no existing publisher, the push is refused with a message that names the variable, the member, and the publisher, and nothing is written for that instance. See UDT Manager.
Status and Diagnostics
The connection state of each publisher is shown in the Status column of the publisher list and in the header of the Publisher Variables page. It is also available at runtime in the system variable SYSTEM.MqttPublisherState_<Name>, for example SYSTEM.MqttPublisherState_SiteUNS, which can be shown on pages and used in conditions.
| Status | Meaning |
|---|---|
| Connecting | The publisher is starting and connects to the broker. |
| Connected | The publisher is connected and publishes the linked variables. |
| Reconnecting | The connection failed or was lost. The publisher retries at the Retry interval. |
| Waiting for Host | Payload Format Sparkplug B with a Primary Host ID: the publisher is connected and publishes its birth certificates once the primary host reports online. |
| Disabled | Enable is switched off. |
| Standby | The node is the standby node. Publishers run on the primary node. |
No rows match the filter.
System Metrics lists every publisher in the Messaging and forwarding section with the type MQTT publisher. The row shows the Status, the number of variables waiting to be published in Queue, the number of enabled linked variables in Variables, and below the name the broker, the number of published messages, the time since the last publish, and the last error. An enabled publisher that is not connected on the primary node is reported as an issue.
Messages of a publisher appear in the System Log with the origin MqttPublisher:<Name>, for example MqttPublisher:SiteUNS. Verbose sets how much is logged:
| Verbose | Logged |
|---|---|
| 0 | Connects, lost connections, connect failures (each new reason once), configuration errors, variables held back because of their topic, write topics that cannot be subscribed, subscriptions refused by the broker, and the first publish refusal of each reason per connection. |
| 1 | Level 0, plus repeated connect failures, state changes, every publish refusal, refused write messages, ignored retained messages, and subscribed write topics. |
| 2 | Level 1, plus every published message with its topic and payload, and every accepted write. |
No rows match the filter.
Use Verbose 2 only during commissioning or diagnostics. It logs every published message and increases the log volume significantly.
Redundancy
MQTT publishers run on the primary node only. The standby node keeps no broker connection, which prevents duplicate messages and two connections with the same Client Id. On the standby node, the Status of every enabled publisher is Standby, and System Metrics reports no issue for it.
After a failover, the new primary node connects every enabled publisher, publishes online on the Status Topic, and publishes the full state of all linked variables. Retained values on the broker bridge the time in between, and the Last Will of the previous primary node marks the publisher offline when its connection dropped.
Writes from the broker are accepted on the primary node only. Publisher settings are changed on the primary node and are replicated to the standby node with the rest of the configuration.
Both nodes use the same Client Id. When both nodes act as primary node at the same time, the broker closes the older connection each time the other node connects, which shows as alternating Reconnecting states in the System Log of both nodes.
A Sparkplug B publisher runs on the primary node only as well. After a failover, the new primary node connects with the next bdSeq, replicated from the previous primary node, and publishes its birth certificates. When the connection of the previous primary node is still open at the broker, the broker closes it and publishes its death certificate before it accepts the new connection, because both nodes use the same Client Id.
Validation
The publisher settings are checked when a publisher is created or saved, in the dialog, in the grid, and on import. A publisher is saved when it meets every rule below; otherwise the message of the rule is shown. With Payload Format Sparkplug B, the Sparkplug B rules apply instead of the rules for the topics, the time stamp, and the payload.
| Rule | Message |
|---|---|
| Name is filled in and contains letters, digits, and underscores only. | The Name field is required. / The Name field is invalid. |
| Name differs from every other publisher, also by case. | MQTT publisher '<Name>' already exists. |
| Broker URL is filled in. | The Broker URL is required. |
| Protocol Version is 3.1.1 or 5.0. | Protocol Version must be 3.1.1 or 5.0. |
| Payload Format is Value Only, JSON Template, or Sparkplug B. | Payload Format must be Value Only, JSON Template or Sparkplug B. |
| Topic Template is filled in and contains no + or #. | The Topic Template is required and must not contain the MQTT wildcards + or #. |
| Status Topic contains no + or #. | The Status Topic field is invalid. |
| Custom Format is a valid .NET date and time format. | The TimeStamp Format is not a valid date and time format. |
| A Topic Template without a per-variable token has Retain switched off. | A Topic Template without a per-variable token sends every variable to one topic, so Retain must be off. |
| A Topic Template without a per-variable token has Payload Format JSON Template with a per-variable token in the Payload Template. | A Topic Template without a per-variable token sends every variable to one topic, so the Payload Format must be JSON Template with {FullName}, {TopicPath} or {VariableName} in the Payload Template. |
| A JSON Template produces valid JSON. | The Payload Template does not produce valid JSON for a sample variable. |
| With Subscribe switched on, Write Topic Template contains {Topic} or a per-variable token, or, with Write Name Key set, one fixed topic without tokens. It contains no + or #. | The Write Topic Template must contain {Topic} or a per-variable token. With a Write Name Key it must be one fixed topic without tokens. |
| With Subscribe switched on, the write topic differs from the topic of the variable. | The Write Topic Template resolves to the same topic as the Topic Template. The publisher would receive its own messages as writes. |
| Sparkplug B: Group ID is filled in and contains no +, /, or #. | The Sparkplug Group ID is required and cannot contain + / or #. |
| Sparkplug B: Edge Node ID and Primary Host ID contain no +, /, or #. | <field> is not a valid Sparkplug id. It cannot contain + / or #. |
| Sparkplug B: Device Mapping is Device or Node. | Device Mapping is not supported. Use Device or Node. |
| Sparkplug B: Group ID and Edge Node ID differ from every other Sparkplug B publisher, also by case. | Edge node <Group ID>/<Edge Node ID> is already used by <publisher>. |
| Port 1 to 65535, Keep Alive 1 to 65535, Timeout 1 to 3600, Retry 1 to 3600, QoS 0 to 2, Republish Interval 0 to 86400, Minimum Interval 0 to 3600000, Verbose 0 to 2. | The <field> field is invalid. |
No rows match the filter.
Two further checks protect the links between variables and publishers:
| Check | Message |
|---|---|
| The MQTT Publisher field of a variable names an existing publisher, with the same case. Checked when the field is changed. | MQTT publisher '<Name>' does not exist. |
| A publisher is deleted only when no variable links to it. | MQTT publisher '<Name>' is linked to <n> variable(s). Unlink the variables first. |
No rows match the filter.
Rename and Delete
Renaming a publisher updates every link in the same save: the MQTT Publisher field of every variable that named the old name, variables created from a UDT included, the MQTT Publisher field of UDT variable members that hold the old name, and the UDT parameter values and parameter defaults that hold the old name and are used only to feed the MQTT Publisher field of members. A parameter that is also used elsewhere in the definition, for example in a variable name, keeps the old name, and the next push of such an instance reports the missing publisher. The publisher then reconnects under its new name. With an empty Client Id, the client identifier becomes ENVISION-<new name>.
Pages and conditions that use the status variable SYSTEM.MqttPublisherState_<Name> keep the old name after the save. When such references exist, the Update references? dialog lists them and offers to update them to the new name.
A publisher can be deleted once no variable links to it. Deleting a publisher that is still linked keeps the publisher and shows the message: MQTT publisher '<Name>' is linked to <n> variable(s). Unlink the variables first.
The count includes disabled variables and variables of disabled devices. Clear the MQTT Publisher field of those variables first, for example in the MQTT Publisher column of the variable grids, or on the UDT variable member followed by a push. When several publishers are selected for deletion, the publishers without links are deleted and the others are reported.
Notes
Kafka devices use the same principle. The Kafka Device field on the Gateway tab links a variable to a Kafka device, and inbound Kafka writes need Consumer on the Kafka device and Writeable on the variable. See Kafka Devices.
Import reads a CSV or JSON file and matches the publishers by Name: an existing publisher is updated, a new one is added, and every row is validated with the rules above. Export writes the stored password in plain text, so an exported file imports complete into another project. Keep exported files in a protected location.
A project import, for example from Git, takes the MQTT Publisher fields of the variables as they are in the file. A variable that names a publisher that does not exist is published as soon as a publisher with that name is created.