Over the years, I have been critical of the MQTT protocol. I am a manufacturing guy from way back and my technologies were always EtherNet/IP, Modbus TCP, and PROFINET IO. There were several things I didn’t like about it.
- The broker was a point of failure and a single source with lots of data. It’s a very attractive component of a system to hackers.
- There was no definition of the payload. Both the clients providing the data to the broker and the clients receiving the data from the broker had to understand the content of the data. [You may note that I was an enthusiastic supporter of EtherNet/IP even though EtherNet/IP had a roundabout way of sharing payload definitions.]
- It was designed for small payloads and applications with many devices, which is the opposite of the situation we have in many industrial applications.
Given these serious issues, I was not a proponent of the technology, I campaigned against it and actively supported OPC UA as an alternative. On a pure technology-to-technology comparison, there is no question that OPC UA is superior.
But the market has spoken, and it hasn’t chosen what I had proposed. In fact, the market has run from my advice. In fact, it has galloped, dashed, raced, and hurried to do the opposite: implement MQTT by the boatload. So, today I capitulate and become an MQTT supporter.
What’s changed my mind? Is it that I realized the error of my earlier conclusions? No, it’s Sparkplug™ B.
Sparkplug provides an open and freely available specification for how native and gateway devices can communicate bi-directionally within an MQTT Infrastructure in a more structured way. Sparkplug B, the second of two alternate payload definitions, resolves many of my earlier arguments. Between the enhancement to the operation of MQTT and my getting run over by the bus of popular sentiment in the automation industry, I am withdrawing my opposition and have become a supporter of MQTT.
The Sparkplug B specification enhances the original MQTT specification in three significant ways.
An Enhanced Topic Namespace
One of the advantages of MQTT is that a device can just define an arbitrary topic name like “Perfume Unit 4 Oven Temp” and start sending data. One of the disadvantages of MQTT is that a device can just define an arbitrary topic name like “Perfume Unit 4 Oven Temp” and start sending data. It’s both an advantage and a disadvantage!
With the Sparkplug specification, the Topic Namespace is much more well thought out and optimized for more serious application development. For data to be easily useful to other MQTT client applications that want to consume data values, the Topic Namespace needs to be understood by everyone participating in the data exchange.
All MQTT clients using the Sparkplug specification will use the following Topic Namespace structure.
- namespace is either “spAv1.0” or “spBv1.0” (the Sparkplug A and Sparkplug B).
- group_id is an ASCII string reference to a logical grouping of nodes such as a manufacturing cell or a pipeline segment.
- message_type element is an ASCII string that defines how the MQTT server processes the message (see state representation below).
- edge_node_id is the ASCII ID of the MQTT: 1) edge device that interfaces to real-world inputs and outputs, or 2) gateway device that communicates to a device that has some proprietary or open protocol other than MQTT. An example of the latter is an MQTT edge node that is a Modbus RTU client device.
- device_id is the ASCII ID of the end device that physically interfaces to the real-world input and outputs. The device ID is optional and not present if the edge node is the actual device interfacing to the real-world inputs and outputs. In the case of where the edge node is a Modbus master, the device ID might be the ID of a Modbus RTU slave on a Modbus RTU network.
MQTT State Management
One of the deficiencies of standard MQTT is that the consumers of data published by an MQTT server are never aware of the state of the end device. In MQTT, messages are published on data changes. If no data changes, no messages are published. But no messages are published if the end node has failed, and that’s a problem. Sparkplug B provides MQTT state management such that consumers of MQTT can be notified when a node is “born” and when it “dies.”
Classic MQTT does not define any payload format. A payload is simply a binary array of bytes of some size. The Sparkplug specification defines two payload formats: payload definition A (a Google Kura standard), and payload definition B (a model for industrial automation).
Sparkplug B defines how a payload is encoded and the data that is required. It provides support for these elements.
- Complex data types using templates
- Rich metrics with the ability to add property metadata for each metric
- Metric alias support to maintain rich metric naming while minimizing bandwidth usage
- Historical data
- File data
For specific information on the payload formats and the encoding associated with each, you’ll have to read the specification.
This is just a quick introduction to Sparkplug B and the advantages it brings to MQTT. It is also a validation that when I am wrong, I admit it. I’d like to say it won’t happen again, but I’m sure I’ll be writing more of these types of blogs as time goes on. Until then, if you need help figuring out MQTT or any other industrial protocols, give RTA a call at 800-249-1812 or send an email.