Skip to content

MQTT Sparkplug B ​

Last updated

License feature: MQTT Sparkplug B

Scada.Ink can act as a Sparkplug B edge node: it connects to an MQTT broker and publishes the live values of the devices you choose, with birth and death certificates so a Sparkplug host (Ignition MQTT Engine, HiveMQ, a unified-namespace consumer) discovers the tags on its own.

It publishes, and — only for device mappings you opt in — accepts writes from the host (DCMD). Scada.Ink does not act as a Sparkplug host and does not subscribe to other edge nodes. To read data from an MQTT broker into Scada.Ink, add an MQTT device instead — see Open Standards.

Where and who ​

System → Sparkplug (/sparkplug, title MQTT Sparkplug B). Needs the mqtt_sparkplug licensed feature. Anyone with the feature can view connections and status; creating, editing, connecting, disconnecting and mapping devices needs admin. The page has three tabs: Connections, Device Map and Status.

Set up publishing ​

  1. On Connections, click New Connection.
  2. Enter Name, Broker URL (for example tcp://10.20.0.5:1883), Group ID (for example PlantA) and Node ID (for example Line3-Edge). Add Username and Password if the broker needs them.
  3. For TLS, tick Use TLS and paste the certificates (below).
  4. Click Create Connection.
  5. Click the power icon (Connect) on the connection's row. This also marks it to reconnect automatically when the API restarts.
  6. Open Device Map, pick the connection, click Add Device.
  7. Choose the Local Device, type a Sparkplug Device ID (for example Press4), set Publish Interval (ms) and optionally a Tag Filter, then Add.
  8. Watch the Status tab: the connection should show connected. On the broker, subscribe to spBv1.0/PlantA/# to see the NBIRTH, DBIRTH and DDATA messages.

Connection fields ​

FieldWhat it doesDefaultNotes
NameLabel in the list and the Status tab—Required
Broker URLBroker address as tcp://host:port or mqtts://host:porttcp://localhost:1883Required; not validated — a typo shows up as a connection error
Group IDSparkplug group — first level after spBv1.0/ScadaINKRequired. Avoid /, + and #; they are not rejected but break the topic
Node IDSparkplug edge node idEdge1Required; must be unique on the broker within the group
Username / PasswordBroker credentialsemptyThe password is stored encrypted on the appliance and reads back as ••••••••
Keep Alive (s)MQTT keep-alive60Form minimum 10
Use TLSConnect with TLSoffSee TLS below
EnabledConnect automatically when the API startsoffTicking it does not connect now — use Connect
CA Certificate, Client Certificate, Client KeyPEM text, shown when Use TLS is tickedemptyPaste the whole -----BEGIN …----- block

When you edit a connection, the Password shows as •••••••• and the certificate fields are empty, because the appliance never sends them back to the browser. Leave them as they are to keep what's stored; type or paste a new value to replace it.

The Password can be a reference to the Secrets store, written ${secret:BROKER_PW}. A reference is a name rather than a credential, so the field shows it as you typed it; the appliance looks the value up each time it connects to the broker. A name that matches no secret leaves the connection in error with Secret "BROKER_PW" is not in the Secrets store, and nothing is sent to the broker.

Edits are not applied to a live connection: click Disconnect, then Connect, after saving.

Device mapping fields ​

FieldWhat it doesDefaultNotes
Local DeviceThe Scada.Ink device whose tags are published—Required; any device, including Local Tags. One mapping per device per connection; cannot be changed when editing
Sparkplug Device IDLast topic level, for example spBv1.0/PlantA/DDATA/Line3-Edge/Press4—Required
Publish Interval (ms)How often changed values are sent1000Form minimum 100
Tag Filter (glob, empty = all)Which tag paths to publishempty (all)Matched against the whole tag path; * matches within one path level (Spindle/*), ** matches across levels (Spindle/**)
EnabledInclude this mappingon
Accept commands (DCMD)Let the host write to this device's tagsoffSee Commands from the host below

What is published ​

MessageTopicWhenContent
NBIRTHspBv1.0/<group>/NBIRTH/<node>On every connect and reconnect, and on RebirthbdSeq and Node Control/Rebirth (Boolean, false)
DBIRTHspBv1.0/<group>/DBIRTH/<node>/<device>After NBIRTH for each enabled mapping; when a device reconnects; when mappings changeEvery tag the device currently has a value for, filtered by Tag Filter
DDATAspBv1.0/<group>/DDATA/<node>/<device>Every Publish Interval if anything changedOnly the tags that changed since the last send
DDEATHspBv1.0/<group>/DDEATH/<node>/<device>When the device's status becomes disconnectedNo metrics
NDEATHspBv1.0/<group>/NDEATH/<node>Sent by the broker as the last will when the connection drops, including DisconnectbdSeq
  • Metric names are the Scada.Ink tag paths (Spindle/Speed). No aliases, units or properties are sent.
  • Types: integer tags → Int32, float/double tags → Float (32-bit), boolean → Boolean, everything else → String.
  • Report by exception. Only changed values are sent, after each tag's own deadband. Nothing is sent for a device whose values did not change. The timestamp on each metric is the time the change reached the Sparkplug service.
  • Tags without a value yet are left out of the DBIRTH; if they report later they arrive in DDATA without having been born, which strict hosts may reject — send a Rebirth once everything is connected.
  • Device diagnostics such as _STATUS/Connected are part of the device's values and are published unless your filter excludes them.
  • Expression tags cannot be published — they do not belong to a device you can map. Copy them into local tags with a script or workflow if a host needs them.
  • Quality. A tag with bad quality (for example, its device lost communication) is published as a null value of its own type, with a Quality property of 0; an uncertain value keeps its value and carries Quality 64. When the tag reads good again, its next value carries Quality 192. Good values otherwise carry no properties.
  • Sequence numbers. seq runs 0–255 across all messages of the connection; bdSeq is a random value chosen at each Connect and repeated in NBIRTH and the last will.
  • QoS. Births and DDEATH use QoS 1; DDATA uses QoS 0; nothing is retained.

Commands from the host ​

Scada.Ink subscribes to spBv1.0/<group>/NCMD/<node> and spBv1.0/<group>/DCMD/<node>/+. There is no primary-host (STATE) awareness.

  • NCMD: only Node Control/Rebirth = true is acted on; it republishes NBIRTH and every DBIRTH. Other NCMD metrics are ignored.
  • DCMD writes each metric's value to the tag of the same path on the mapped device. A DCMD writes to real equipment, so it's refused unless all of these are true:
    1. The device mapping has Accept commands (DCMD) ticked. It's off for every mapping until you turn it on.
    2. The metric name is a tag path inside the mapping's Tag Filter, and is a configured tag on that device.
    3. The device has Allow Tag Writes on. Tags on the Local Tags device are the exception, as for REST and OPC-UA writes.
    4. The tag has no write security level. A Sparkplug host has no user who could hold one, so such tags can't be written over Sparkplug.

Sparkplug has no reply to a command. A refused or failed command is logged in the API log with the reason (Sparkplug DCMD … refused: …); an applied one is recorded in the Audit Log as sparkplug_write. Null metrics are ignored.

TLS ​

  • Tick Use TLS and put the broker's TLS port in the URL, usually tcp://broker.plant.local:8883. With Use TLS ticked the connection uses TLS whatever scheme you typed — tcp://host:1883 would attempt TLS on port 1883.
  • Paste the CA Certificate when the broker's certificate is not signed by a public authority (typical on a plant network, and on an air-gapped appliance always).
  • Paste Client Certificate and Client Key only if the broker requires client-certificate authentication.
  • The broker certificate is always verified, and its name must match the host in the URL. There is no option to skip verification.
  • Writing mqtts:// in the URL without ticking Use TLS also connects with TLS, but ignores the pasted certificates.

Restarts and outages ​

  • Connections that are Enabled (set by Connect) reconnect when the API starts; a new bdSeq is chosen.
  • If the broker drops, the client retries every second. On reconnect it publishes NBIRTH and all DBIRTHs again.
  • Values that change while the broker is unreachable are not buffered — only the latest value per tag is sent after the reconnect. Sparkplug store-and-forward (historical flag) is not implemented.
  • Removing a mapping does not send DDEATH for it; the host keeps the device until the node rebirths.

Status and monitoring ​

The Status tab refreshes every 5 seconds and shows each connection's status (connected, disconnected or error), Broker, Group, Node, TLS and the last error. For a dashboard, add the Sparkplug Status widget and set its Connection ID (the number in /api/sparkplug/connections).

A failing connection shows disconnected between retries, with the last error kept until a connection succeeds. If it never reaches connected and the last error doesn't say why, contact Scada.Ink support for deeper log analysis.

API ​

MethodPathRolePurpose
GET/api/sparkplug/connectionsviewerList connections (password masked as ••••••••, or shown as its ${secret:NAME} reference; no certificates)
POST/api/sparkplug/connectionsadminCreate
PUT/api/sparkplug/connections/:idadminUpdate (fields you omit are kept; for the password and certificates, an empty string or •••••••• also keeps the stored value)
DELETE/api/sparkplug/connections/:idadminDisconnect and delete, with its mappings
POST/api/sparkplug/connections/:id/connectadminConnect and enable auto-connect
POST/api/sparkplug/connections/:id/disconnectadminDisconnect and disable auto-connect
GET/api/sparkplug/connections/:id/devicesviewerDevice mappings
POST/api/sparkplug/connections/:id/devicesadminAdd a mapping
PUT/api/sparkplug/device-map/:idadminUpdate a mapping
DELETE/api/sparkplug/device-map/:idadminRemove a mapping

A script can GET a connection, change a field, and PUT the whole object back; the masked password keeps the stored one. Mappings take acceptCommands (boolean, default false).

Sparkplug connections and their mappings can be copied between appliances in a configuration bundle (entity type sparkplug); the password and certificates are blanked unless sensitive data is included. See Bundles.

Troubleshooting ​

SymptomCauseFix
Status stays disconnectedBroker unreachable, wrong port, or credentials refusedRead the last error; test the broker with an MQTT client from the same network
The stored broker password could not be decryptedThe appliance's JWT secret changed after the password was savedEdit the connection and type the password again
Host writes don't reach the deviceAccept commands off, tag outside the filter, Allow Tag Writes off, or a write security level on the tagCheck the API log for Sparkplug DCMD … refused and the reason
TLS error such as self-signed certificate or unable to verify the first certificateCA not pasted, or wrong CAPaste the CA that signed the broker certificate
Hostname/IP does not match certificate's altnamesURL uses an IP or name not in the certificateUse the name the certificate was issued for
TLS handshake fails on port 1883Use TLS ticked with the plain portUse the broker's TLS port (usually 8883)
Host sees the node but no devicesNo enabled mapping, or the device has no values yetAdd a mapping; check the device is connected; send Rebirth
Some tags missingTag Filter too narrow, or tags had no value at birthClear the filter to test; send Rebirth
403 Feature "mqtt_sparkplug" is not enabled…Not in the licenseContact your supplier
MQTT Sparkplug B is not enabled on this license.License lapsed or changedSame
Changes on the connection do nothingEdits are not applied to a live connectionDisconnect, then Connect

See also ​

Scada.Ink Help Center