MQTT and Sparkplug B Simplified
In the world of Industry 4.0 and Digital Transformation, you will frequently see the terms MQTT, Sparkplug B, and Unified Namespace pop up.
This post will dive into MQTT and Sparkplug B and explain how they fit into digital manufacturing—including how to pave the way for utilizing a Unified Namespace as you progress on your Digital Transformation journey.
What is MQTT?
MQTT is a communications protocol designed for devices and software platforms to communicate with each other. It’s built on the concept of MQTT Brokers acting as the main data highway, and MQTT Clients (devices or software) publishing and/or subscribing to these MQTT Brokers. Clients subscribe to or publish the data sent to the Broker as a "topic". Since data can be configured to be sent only sent when it changes (and not constantly), MQTT can be "report by exception". This reduces the overall amount of data sent and is great for remote sites on cellular modems with expensive data costs.
Unlike most industrial protocols (which are polled), MQTT is publish/subscribe (pub/sub). Polled protocols like OPC-UA and Modbus require devices and software to periodically poll for data from other devices. The process repeats on a loop: they send out a poll request and data is returned.
For example, a level sensor in a tank could publish the tank level to an MQTT broker, and anyone who subscribes to that topic will get an update every time the level changes. If the level isn't changing, the sensor will not publish data until it changes. Any system or device that needs to know the tank level can subscribe to it through the MQTT broker. Whenever the value changes, it will be sent to the broker and everyone who subscribes to this topic will get the new value.
By contrast, In a polled environment a software platform like Ignition will request data from the level sensor every second and require that request to be sent to the sensor. It will also require a response from the sensor is sent to Ignition.
The “report by exception” approach used by MQTT has many benefits. Devices do not need to know anything about each other, so there’s a reduced overall network and security overhead—since each device only need to connect to the broker. It can support asynchronous communication, and devices without 100% network uptime. When a value is updated, everyone will see the latest value even if the device is only online once a day to send it.
What is an MQTT Topic?
Besides brokers and how devices connect to them, the next major piece of MQTT you need to understand is an MQTT Topic. Topics have a hierarchical organization, similar to a folder structure. This makes it easy to build out a tree view for MQTT Tags in Ignition for example.
An example topic for our tank level might be:
Lynchburg Distillery/Fermentation/Floor 1/Tank 1/Level
Within this hierarchy we could have other values for this tank, such as:
Lynchburg Distillery/Fermentation/Floor 1/Tank 1/Temperature Lynchburg Distillery/Fermentation/Floor 1/Tank 1/BatchID
If we have another tank, we could then use:
Lynchburg Distillery/Fermentation/Floor 1/Tank 2/Level Lynchburg Distillery/Fermentation/Floor 1/Tank 2/Temperature Lynchburg Distillery/Fermentation/Floor 1/Tank 2/BatchID
Each of these topics will have associated data like a value, units, timestamps, etc. sent over as the payload from the device that is sending the messages.
Devices subscribing to these topics can subscribe to each individual datapoint, or they could use wildcards to subscribe to multiple datapoints. To get all the data for Tank 1 for example, you can use the # wildcard which will match anything at this level of the tree:
Lynchburg Distillery/Fermentation/Floor 1/Tank 1/#
To get all temperatures from all tanks on Floor 1 we could use a unary wildcard to get all temperatures from devices matching this hierarchy:
Lynchburg Distillery/Fermentation/Floor 1/+/Temperature
Ready to get your project started immediately?
Schedule a 15 minute meeting with Cody Johnson in sales
What is Sparkplug B?
When working with MQTT, one limitation is that there’s no definition of what the topics should look like. If you are working with ten different level sensors, you could see ten different topic structures.
Sparkplug B is a framework built on top of MQTT to pre-define topic structures for Industrial Data. While this does mean you need to conform to the framework to get the value out of it—which limits what information the devices can give you, this is a GREAT THING because framework limitations create structure.
By using Sparkplug B enabled devices, you will know EXACTLY what their topic namespace will look like. This ultimately ties into the idea of a Unified Namespace, which we will cover in a future post.
The Sparkplug B topic namespace looks like this:
spBv1.0/Group ID/Message Type/Edge Node ID/Device ID
spBv1.0 specifies the Sparkplug B Protocol. Message Type is pre-defined by the specification, indicating if it is state information, data, or a command and if it pertains to a node, device or the primary application.
The Group ID, Edge Node ID, and Device ID are configurable by the user.
Sparkplug B also pre-defines the payload format:
{ "timestamp": 1486144502122, "metrics": [{ "name": "My Metric", "alias": 1, "timestamp": 1479123452194, "dataType": "String", "value": "Test" }], "seq": 2 }
Sparkplug B and pre-defining the topic namespace give you a standardized format to build your topic definitions. Rather than sending data to a particular topic, with one topic per data point, you can send all of your data contained in the payload at one time to a particular topic. The payload data is compressed so you can send more data using Sparkplug B than with vanilla MQTT and use less bandwidth.
The major difference between the 2 is using vanilla MQTT you can subscribe to any individual topics you want and filter down your data by limiting your subscriptions to only what you want. Contrasting this with Sparkplug B you can subscribe to topics, but not individual metrics within topics. You will get the entire payload.
There are ways to get around this by “intercepting” the Sparkplug B payload and expanding it into MQTT topics or like with the Cirrus Link MQTT Engine Module for Ignition using the MQTT Sparkplug B payload metrics to create tags in Ignition.
For this reason we highly recommend using Sparkplug B to pass data from devices, especially where you would like to reduce bandwidth, then breaking apart the Sparkplug B data one level removed from the Unified Namespace, then use vanilla MQTT at the Unified Namespace layer so you can gain the additional topic flexibility to integrate with your semantic hierarchy in the Unified Namespace itself.
***NOTE***
If you are using ISA-95 to model your process you might think the format of the Sparkplug B topic can easily map to to the equipment model format of Site/Area/Line. We don’t recommend taking this approach.
You certainly CAN do this, and the popular Parris and Schulz methods give you two guidelines on how to do it.
Use Sparkplug B to pass data from devices. Don’t layer anything on top of it beyond “devices send values and they can have some organizational structure with the topic definition”. Think of Sparkplug B as “somewhat organized raw data”. When you need to add the site/area/line context to the raw data do that in the layer where you need the context. Sparkplug B does not save you from doing the actual work of mapping data to the systems that need the data, it simply helps you organize the raw data, even if it is just a little bit.
Combining the equipment model and the Sparkplug B topic namespace is simply adding technical complexity to someone else who needs to ingest your data without providing a lot of value. Keep it simple and remove additional layers of abstraction like ISA-95’s equipment model when sending data. For more context on why you should do this please check out Parts 6 and 7 of the ISA-95 standard, or our post on Everything You Need to Know About ISA-95.
Let's Simplify Sparkplug B
The easiest way to think about Sparkplug B is to picture the topic namespace like a URL for a website. For this exercise, if we ignore the "spBv1.0" and "Message Type" portions of the topic and use a Corso Systems Blog Post URL as an example we would have the following:
corsosystems.com/posts/ignition-bindings-deep-dive
Mapping this to the Sparkplug B topic (ignoring "spBv1.0" and "Message Type") we have:
Group ID/Edge Node ID/Device ID
In this case, Group ID would be our domain name, corsosystems.com. Edge Node ID would be the posts section of the website. And Device ID names the specific post we are looking at: ignition-binding-deep-dive.
If we think of our web browser as an MQTT Client subscribing to this topic, the particular payload we would receive is the content of the blog post. Any time we open up the page in our browser, it will retrieve the latest version of the post on our server.
To retrieve the data for all the posts on our site you could subscribe to corsosystems.com/posts/# and get all of the posts returned.
If we wanted to look at this metaphor from the publisher perspective, we can think of the Sparkplug B topic as the URL we will send something to. The Message Type would be an HTTP POST, and our payload would be the data we were sending to the server—just as if we were using an API call like we would if we were to use the Ignition Web Dev module for example.
Sparkplug B simply defines the structure of the URL we would use to interact with an MQTT Broker, as though it were any server accessible on the internet.
If we wanted to go totally into the deep end we could make some arguments Sparkplug B is like using a URL shortener for industrial data. There is a post we like about the advantages and disadvantages of short names for things like URLs, or in our case Topic Definitions we recommend checking out if you want to think more about that.
Let's Simplify MQTT
Using the URL concept from the previous section, if Sparkplug B's topic namespace is a pre-defined URL format, then vanilla MQTT is basically the same thing, but without a strict naming convention enforcement for the topic namespace.
Compared to using Sparkplug B, vanilla MQTT is more like writing your own webserver without a pre-defined URL format.
For example, you could reference the URL from earlier as a topic in different ways depending on your naming convention:
While each of these examples could be valid if publishers were sending data to them, there is no specific naming convention you need to use. Ideally, you would pick something useful and clearly understood to simplify navigation. But with vanilla MQTT, you would not be required to!
This is not unlike writing your own webserver program where you can structure the URL to be whatever you want, even if it makes you and your user's lives more difficult to use your website.
Wrapping Up
Sparkplug B is a great framework layered on top of MQTT. It gives you a mostly pre-defined topic namespace. By using Sparkplug B, you get a huge head start on building a Unified Namespace for your business.
While it can be convenient and easy to throw endpoints together like you can with vanilla MQTT, once you move to any level of scale the structure provided by something like Sparkplug B is much better than the convenience afforded with no limitations.
You will still need to define your metrics, so Sparkplug B won’t be getting you a free lunch at the Unified Namespace cafe, although it does get you a heck of a lot closer than starting from scratch with vanilla MQTT.
Do you need help with a project involving Sparkplug B? Contact Corso Systems or schedule a meeting with Cody Johnson in sales to get started immediately.