Sparkplug client functionality (publisher and subscriber)
8.2K
This is a utilty for debugging Sparkplug messages that are encoded using GPB (Google Protocol Buffers).
The docker container has two modes: 'pub'(publish) and 'sub'(subscribe).
When in subscribe mode, the docker container subscribes to a given MQTT topic, attempting to decode any messages it receives on this topic before printing them to the console (or a file see usage).
When in publish mode, the docker container will parse the given message (see usage) before encoding it and publishing it on the given topic.
For both encoding and decoding, all messages are expected to follow the Sparkplug B specification which can be found in section 6.4 in the this document.
An MQTT Broker is required to use this image.
This code is intended to be used as a docker container which can be pulled using:
docker pull iotechsys/sparkplug-client
The container can be used to publish an encoded message with:
docker run --rm --network host iotechsys/sparkplug-client pub -h <YourMQTTHostIP> -t <YourTopic> -m <YourMessageToBeEncoded>
Where
'{ "metrics":[ { "name": "Node Control/LogLevel", "datatype": 7, "value": 5 } ] }'There are a variety of flags available for use in publish mode. These can be found in section Flags.
The container can be used to subscribe to a topic and decode the messages with:
docker run --rm --network host iotechsys/sparkplug-client sub -h <YourMQTTHostIP> -t <YourTopic>
Where
Outputting to a file is also supported.
This is controlled via the -f flag, which should be supplied along with a path to the file.
In order to output the decoded messages a volume has to be mounted to share the files generated within the container with the host environment.
This can be done as follows:
mkdir volume
docker run --rm --network host -v ${PWD}/volume:/volume iotechsys/sparkplug-client sub -f /volume/output_file.json -t spBv1.0/# -v --indent
This will instruct the container to write all received messages to _/volume/output_file.json.
There are a variety of flags available for use in subscribe mode. These can be found in section Flags.
The Sparkplug Client includes a built-in Web UI for visualising MQTT messages in real-time through a browser interface. To enable the Web UI, use the --webui flag in subscribe mode:
docker run --rm --network host iotechsys/sparkplug-client sub --webui -h <YourMQTTHostIP> -t <YourTopic>
This starts the Web UI server on port 8080 by default. Access the interface at http://localhost:8080
To use a different port, add the --webui-port flag:
docker run --rm --network host iotechsys/sparkplug-client sub --webui --webui-port 9090 -h localhost -t "spBv1.0/#"
The Web UI provides real-time visualisation of decoded Sparkplug messages and runs alongside console output (unless --quiet is used).
This client has some limitations when handling messages that are missing datatypes such as DDATA and NDATA messages.
This is due to the Sparkplug specification utilising generic Protobuf types for several Sparkplug datatypes.
This means that types such as Int8 (1) and Int32 (3) are encoded over the wire as uint32s and the client is unaware as to their original datatypes of the metric.
For these ambiguous metrics, the client will print them using their Protobuf Value Names, for example the following message: { "metrics": [ { "name": "Int8 Metric (Datatype 1)", "value": -4 }, { "name": "UInt64 Metric (Datatype 8)", "value": 4 }, { "name": "String Metric (Datatype 12)", "value": "Test String" }, { "name": "UInt8 Array (Datatype 26)", "value": [3, 4] } ] }
would be printed as: { "metrics": [ { "name": "Int8 Metric (Datatype 1)", "int_value": 4294967292 }, { "name": "UInt64 Metric (Datatype 8)", "long_value": 4 }, { "name": "String Metric (Datatype 12)", "value": "Test String" } { "name": "UInt8 Array (Datatype 26)", "bytes_value":"AwQ=" } ] }
Notice that the String Metric is a non-ambiguous type and as such will not use Protobuf naming despite having no datatype.
Please find below a reference for all ambiguous types and their value names:
| Sparkplug Datatype | Protobuf Value String | Protobuf Datatype |
|---|---|---|
| Int8 (1) | int_value | uint32 |
| Int16 (2) | int_value | uint32 |
| Int32 (3) | int_value | uint32 |
| Int64 (4) | long_value | uint64 |
| UInt8 (5) | int_value | uint32 |
| UInt16 (6) | int_value | uint32 |
| UInt32 (7) | int_value | uint32 |
| UInt64 (8) | long_value | uint64 |
| Bytes (17) | bytes_value | bytes |
| File (18) | bytes_value | bytes |
| Int8Array (22) | bytes_value | bytes |
| Int16Array (23) | bytes_value | bytes |
| Int32Array (24) | bytes_value | bytes |
| Int64Array (25) | bytes_value | bytes |
| UInt8Array (26) | bytes_value | bytes |
| UInt16Array (27) | bytes_value | bytes |
| UInt32Array (28) | bytes_value | bytes |
| UInt46Array (29) | bytes_value | bytes |
| FloatArray (30) | bytes_value | bytes |
| DoubleArray (31) | bytes_value | bytes |
| BooleanArray (32) | bytes_value | bytes |
| StringArray (33) | bytes_value | bytes |
For more detail on the array types, please refer to the Sparkplug B Specification that outlines how these are encoded on the wire.
There are many flags which can be configured for your needs.
These can be viewed using:
docker run --rm --network host iotechsys/sparkplug-client --help
You can set as many of these flags as you wish in any order, for example:
docker run --rm --network host iotechsys/sparkplug-client sub -P user1password -u user1 -t another/topic/# -p 8883
Below you will find all flags that can be configured for this client
The file flag can be used to specify a file to send in the case of pub mode, or to specify a file to write received messages to in the case of sub mode.
In order to share the file a volume has to be mounted to allow the container to access the file on the host machine.
This can be done as follows for pub mode:
docker run --rm --network host -v ${PWD}/volume:/volume iotechsys/sparkplug-client pub -f /volume/message.txt
Where ${PWD}/volume/message.txt contains the json representation of the desired message.
And in sub mode:
docker run --rm --network host -v ${PWD}/volume:/volume iotechsys/sparkplug-client sub -f /volume/messages.txt
Where all messages received will be written to ${PWD}/volume/messages.txt
The client can also repeatedly publish the same message
The basic --repeat flag can be used to specify the number of times the message is sent, with --repeat-delay specifying the time in milliseconds between repeats
So the following would send the message 3 times, with 1000ms between each repeat:
docker run --rm --network host iotechsys/sparkplug-client pub -m '{"metrics":[{"datatype":6,"name":"Current","value":6}]}' --repeat 3 --repeat-delay 1000
The --repeat flag can also be combined with --auto-increment-initial and --auto-increment-value in order to send a changing value with each repeat where --auto-increment-initial specifies the value to start on, and --auto-increment-value specifies the incremental value.
The string "AUTO_INCREMENT" (including quotes) needs then be placed in the message where the value should be substituted.
For example:
docker run --rm --network host iotechsys/sparkplug-client pub -m '{"metrics":[{"datatype":6,"name":"Current","value":"AUTO_INCREMENT"}]}' --repeat 3 --repeat-delay 1000 --auto-increment-initial 15 --auto-increment-value 3
Would send:
{"metrics":[{"datatype":6,"name":"Current","value":15}]}
{"metrics":[{"datatype":6,"name":"Current","value":18}]}
{"metrics":[{"datatype":6,"name":"Current","value":21}]}
Exclusion of messages published on certain topics is another feature available when in subscribe mode.
This is controlled with the -et flag
For example:
docker run --rm --network host iotechsys/sparkplug-client sub -t "spBv1.0/#" -et "DBIRTH"
Would exclude any message received from a topic that included "DBIRTH", all other messages would be printed as normal.
| Flag | Default | Mode | Description |
|---|---|---|---|
| -h | "127.0.0.1" | [pub or sub] | MQTT Broker Host Address |
| -p | "1883" | [pub or sub] | MQTT Broker Port |
| -t | "spBv1.0/#" | [pub or sub] | MQTT topic, default not applicable in pub mode (# can be used as wild card in sub mode) |
| -f | "" | [pub or sub] | File containing message in json to encode and publish, or file in which to write received messages |
| -u | "" | [pub or sub] | MQTT Broker username |
| -P | "" | [pub or sub] | MQTT Broker password |
| -q | 0 | [pub or sub] | Quality of Service level to use (0 to 3) |
| -repeat | 1 | [pub] | Client will send the given message this many times |
| -repeat-delay | 0 | [pub] | If using --repeat, client will wait this many milliseconds between publishes |
| -msg-count | 0 | [sub] | Client will disconnect after receiving this many messages (0 means receive messages indefinitely) |
| -v | false | [sub] | Prints the topic the message was received on as well as the message |
| -et | "" | [sub] | Rejects messages from topics that are published on topics that contain the passed in string |
| -quiet | false | [sub] | Messages will not be printed |
| -print-timings | false | [sub] | If using --msg-count, print the time of receipt of the first message and the time of program termination |
| -m | "" | [pub] | Message in json to encode and publish, must follow Sparkplug Specification |
| -auto-increment-initial | 0.0 | [pub] | If using --repeat, string "AUTO_INCREMENT" in message will be replaced with a value that is incremented by auto-increment-value (defaults to 1) each repeat starting at the given value |
| -auto-increment-value | 1.0 | [pub] | If using --repeat and --auto-increment-initial, the "AUTO_INCREMENT" value will be incremented by this value |
| -connection-retry-interval | 100 | [pub or sub] | Sets the connection retry interval in milliseconds if the client is unable to connect to the broker |
| -indent | false | [sub] | Prints the message as indented json |
| -webui | false | [pub or sub] | Enable web UI (Default port 8080) |
| -webui-port | 8080 | [pub or sub] | Run the web UI on a different port |
The Sparkplug Specification does not presently have any support for objects. Because of this IOTech Systems Edge Connect enables sending of objects as JSON strings under the Text Datatype (Represented by value 14)
An example message that the client could send is should below: { "metrics": [ { "datatype": 14, "name": "Object Metric", "value": { "number": 4, "object": { "number2": 1, "string": "Example String" } } } ] }
which would then be received and printed as shown: { "metrics": [ { "datatype": 14, "name": "Object Metric", "value": "{"number":4,"object":{"number2":1,"string":"Example String"}}" } ] }
Worth noting, is that this object support does not prevent sending of regular strings in datatype 14, this will be handled as expected.
This client does not currently support certain datatypes. These are:
This client also does not currently support the publishing of messages that do not contain all datatypes.
Content type
Image
Digest
sha256:ce1b0e794…
Size
8.9 MB
Last updated
over 2 years ago
docker pull iotechsys/sparkplug-client