Skip to content

About

Sparkplug B 3.0 MQTT CLI for monitoring, publishing and Protobuf encoding/decoding. Simulate Edge Nodes and Hosts; debug birth/death lifecycle events.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

sparkplugbctl

Sparkplug B 3.0.0 CLI for MQTT monitoring, publishing, simulation and debugging.

Go License: MIT CI Release

sparkplugbctl is a command-line tool for exploring, monitoring, publishing, simulating and debugging Eclipse Sparkplug B 3.0.0 MQTT infrastructure. Built in Go on go-sparkplugb.


Install

curl -fsSL https://get.otfabric.io/sparkplugbctl | sh
irm https://get.otfabric.io/sparkplugbctl.ps1 | iex

Linux (amd64, arm64, armv7), macOS (Intel, Apple silicon) and Windows (amd64, arm64). The installer verifies the release's SHA-256 checksum, installs per user without sudo (~/.local/bin, Windows %LOCALAPPDATA%\OTFabric\bin), and upgrades in place when run again. Pin a version with OTF_VERSION=x.y.z; for CI, containers and device images use OTF_UNMANAGED_INSTALL=<dir>; all options: otfabric/install. For offline machines, the archives and checksums are on Releases.

From source (Go 1.26.0+): go install github.com/otfabric/sparkplugbctl@latest

Shell completion

Besides the commands and flags, the type in --metric name:type=value completes, and the TLS flags complete .pem, .crt, .cer and .key files.

# bash (needs the bash-completion package)
mkdir -p ~/.local/share/bash-completion/completions
sparkplugbctl completion bash > ~/.local/share/bash-completion/completions/sparkplugbctl

# zsh: a directory on your fpath, then restart the shell
mkdir -p ~/.zsh/completions && sparkplugbctl completion zsh > ~/.zsh/completions/_sparkplugbctl
# and once in ~/.zshrc:  fpath=(~/.zsh/completions $fpath); autoload -U compinit && compinit

# fish
mkdir -p ~/.config/fish/completions && sparkplugbctl completion fish > ~/.config/fish/completions/sparkplugbctl.fish
# PowerShell: add this line to your profile ($PROFILE)
sparkplugbctl completion powershell | Out-String | Invoke-Expression

Quick start

# Listen to all Sparkplug B traffic on a broker
sparkplugbctl listen --broker tcp://localhost:1883

# Simulate an edge node publishing temperature every 2 s
sparkplugbctl edge --group plant --node gw1 \
  --metric "temperature:Double=22.5" --interval 2s

# Decode a base64-encoded Sparkplug payload
base64 -d < payload.b64 | sparkplugbctl decode

# Run a host application that tracks every edge node
sparkplugbctl host --host-id scada --broker tcp://localhost:1883

# Run a passive application (no STATE, just tracking)
sparkplugbctl app --broker tcp://localhost:1883

Commands

sparkplugbctl
├── listen         Subscribe to spBv1.0/# and decode Sparkplug payloads and STATE live
├── publish        Publish a single Sparkplug B payload with typed metrics
├── edge           Simulate a Sparkplug B edge node (birth, data, rebirth)
├── host           Simulate a Sparkplug B host application (STATE, tracking)
├── app            Run a Sparkplug B application (subscriber, no STATE)
├── decode         Decode a binary Sparkplug B Protobuf payload (stdin or file)
├── encode         Encode typed metrics into binary Sparkplug B Protobuf
├── completion     Generate shell completion (bash|zsh|fish|powershell)
└── version        Print version and build info

Global flags

Flag Default Description
--broker tcp://localhost:1883 MQTT broker URL
--client-id auto-generated MQTT client ID
--username MQTT username
--password MQTT password
--tls-cert TLS client certificate file
--tls-key TLS client key file
--tls-ca TLS CA certificate file
--json false Output as JSON

Usage

listen

Subscribe to all Sparkplug B topics and decode payloads in real time. A primary host's STATE message (JSON) is shown as such.

# All traffic
sparkplugbctl listen --broker tcp://localhost:1883

# Filter by group and node
sparkplugbctl listen --group plant --node gateway

# JSON output for scripting
sparkplugbctl listen --json

Example output:

[STATE] spBv1.0/STATE/scada
  online=true  ts=2026-10-27T11:12:18Z

[NBIRTH] spBv1.0/plant/NBIRTH/gw1
  seq=0  ts=2026-10-27T11:12:18Z
  bdSeq                 Int64    1
  Node Control/Rebirth  Boolean  false
  temperature           Double   22.5

[DBIRTH] spBv1.0/plant/DBIRTH/gw1/sensor1
  seq=1  ts=2026-10-27T11:12:18Z
  status  Boolean  true

[NDATA] spBv1.0/plant/NDATA/gw1
  seq=2  ts=2026-10-27T11:12:20Z
  temperature  Double  22.816084857923634

A metric with a quality property shows it, e.g. quality=STALE.

edge

Simulate a Sparkplug B edge node with automatic lifecycle management and periodic data publishing. Each device is born with one metric, status (Boolean). Received NCMD and DCMD messages are reported; a rebirth request is answered with new births.

With --primary-host, the node waits for that host's STATE to be online before its births. When the host goes offline, the node publishes NDEATH, reconnects and waits again, as Sparkplug 3.0.0 requires.

# Default metrics (temperature, humidity, pressure)
sparkplugbctl edge --group plant --node gateway

# Custom metrics and devices
sparkplugbctl edge --group plant --node gw1 \
  --device sensor1 --device sensor2 \
  --metric "temperature:Double=22.5" \
  --metric "pressure:Double=1013.25" \
  --interval 2s

# With primary host awareness
sparkplugbctl edge --group plant --node gw1 --primary-host scada

Example output:

[INFO]  state: disconnected -> connecting
[INFO]  state: connecting -> subscribing
[INFO]  state: subscribing -> waiting_for_primary_host
Connected to tcp://localhost:1883 as plant/gw1
Waiting for primary host scada to be online
Publishing data every 2s (Ctrl+C to stop)
[INFO]  state: waiting_for_primary_host -> online
Published NBIRTH (1 metrics)
Published DBIRTH for sensor1
Published NDATA (1 metrics)
^C
Shutting down edge node...
Published DDEATH for sensor1
Disconnected

host

Run a Sparkplug B host application that publishes STATE birth/death certificates and tracks all edge nodes.

sparkplugbctl host --host-id scada --broker tcp://localhost:1883

Example output:

[INFO]  host state: disconnected -> connecting
[INFO]  host state: connecting -> connected
Host scada online (broker: tcp://localhost:1883)
Listening for edge activity (Ctrl+C to stop)
[NBIRTH] plant/gw1 (3 metrics)
[DBIRTH] plant/gw1/sensor1 (1 metrics)
[NDATA]  plant/gw1 (1 metrics)
^C
Shutting down host...
[INFO]  host state: connected -> disconnected
Disconnected

app

Run a Sparkplug B application that subscribes to all Sparkplug B traffic and tracks edge nodes and devices — without publishing STATE birth/death certificates. Use this when you want passive monitoring or when another tool is the primary host.

# Monitor all edge activity
sparkplugbctl app --broker tcp://localhost:1883

# Filter by group
sparkplugbctl app --group plant

# JSON output for scripting
sparkplugbctl app --json

Example output:

[INFO]  application state: disconnected -> connecting
[INFO]  application state: connecting -> connected
Application mode (no STATE) — broker: tcp://localhost:1883
Listening for edge activity (Ctrl+C to stop)
2026-10-27T12:12:18+01:00  [NBIRTH] plant/gw1 (3 metrics)
2026-10-27T12:12:18+01:00  [DBIRTH] plant/gw1/sensor1 (1 metrics)
2026-10-27T12:12:20+01:00  [NDATA]  plant/gw1 (1 metrics)
2026-10-27T12:12:30+01:00  [NDEATH] plant/gw1
^C
Shutting down application...
[INFO]  application state: connected -> disconnected
[INFO]  application state: disconnected -> closed
Disconnected

publish

Publish a single Sparkplug B payload with typed metrics.

sparkplugbctl publish \
  --topic "spBv1.0/plant/NDATA/gateway" \
  --metric "temperature:Double=23.1" \
  --metric "status:Boolean=true" \
  --seq 5

decode

Decode a binary Sparkplug B Protobuf payload from stdin or a file. Convert hex or base64 to binary first.

# From a file
sparkplugbctl decode --file payload.bin

# Binary on stdin
sparkplugbctl encode --metric "temperature:Double=23.1" | sparkplugbctl decode

# From hex or base64
xxd -r -p payload.hex | sparkplugbctl decode
base64 -d < payload.b64 | sparkplugbctl decode

# JSON output
sparkplugbctl decode --file payload.bin --json

Example output:

seq=5  ts=2026-10-27T11:09:22Z
  temperature  Double   23.1
  status       Boolean  true

encode

Encode typed metrics into a binary Sparkplug B Protobuf payload.

# To stdout (pipe to file or another tool)
sparkplugbctl encode \
  --metric "temperature:Double=22.5" \
  --metric "status:Boolean=true" \
  > payload.bin

# To file, with a sequence number
sparkplugbctl encode --file payload.bin --seq 5 \
  --metric "temperature:Double=22.5"

# Base64 output
sparkplugbctl encode --metric "temperature:Double=22.5" | base64

completion

Generate shell completion scripts for bash, zsh, fish and PowerShell; how to install them: Shell completion.

version

sparkplugbctl version
sparkplugbctl version --json

One line on stdout. A release build:

sparkplugbctl 0.4.0 (tag v0.4.0, commit 1802d0f9afe8642d1e278120b76fcdfac967cb9e, built 2026-11-05T15:41:49Z, go-sparkplugb 0.3.3, go1.27.3, darwin/arm64)

A development build (go build, go run, or make build off a tag; go install …@vX.Y.Z reports that version):

sparkplugbctl dev (commit 1802d0f9afe8642d1e278120b76fcdfac967cb9e-dirty, built unknown, go-sparkplugb 0.3.3, go1.27.3, darwin/arm64)

With --json (or SPARKPLUGBCTL_FORMAT=json) it prints one JSON object; the fields are in docs/json-output.md.

{"name":"sparkplugbctl","version":"0.4.0","tag":"v0.4.0","commit":"1802d0f9afe8642d1e278120b76fcdfac967cb9e","built":"2026-11-05T15:41:49Z","libraries":[{"name":"go-sparkplugb","version":"0.3.3"}],"go":"go1.27.3","platform":"darwin/arm64"}

Examples

Runnable shell scripts are in the examples/ directory:

Script Description
01-listen.sh Subscribe to all Sparkplug B traffic
02-edge-node.sh Simulate an edge node with devices and metrics
03-host-app.sh Run a host application (STATE + tracking)
04-application.sh Run an application subscriber (no STATE)
05-encode-decode.sh Encode metrics to binary and decode back
06-publish.sh Publish a single Sparkplug B payload
07-edge-with-host.sh Full scenario: host + edge + listener
# Run any example (start a local broker first)
./examples/02-edge-node.sh

Supported metric types

--metric (on publish, encode and edge) takes Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64, Float, Double, Boolean (or Bool), String, Text, UUID and Bytes (the value's UTF-8 bytes); type names are case-insensitive.

Metric syntax: name:Type=value — for example temperature:Double=22.5 or active:Boolean=true.

listen and decode show metrics of every datatype a payload carries, including DateTime, arrays, DataSet and Template.


Environment variables

Every global flag can be set via an environment variable. The flag takes precedence when both are set.

Variable Flag Default
SPARKPLUGBCTL_BROKER --broker tcp://localhost:1883
SPARKPLUGBCTL_CLIENT_ID --client-id auto-generated
SPARKPLUGBCTL_USERNAME --username
SPARKPLUGBCTL_PASSWORD --password
SPARKPLUGBCTL_TLS_CERT --tls-cert
SPARKPLUGBCTL_TLS_KEY --tls-key
SPARKPLUGBCTL_TLS_CA --tls-ca
SPARKPLUGBCTL_JSON --json false
SPARKPLUGBCTL_FORMAT json sets --json; SPARKPLUGBCTL_OUTPUT_FORMAT is accepted too

Exit codes are listed in docs/exitcodes.md, and the --json output is described in docs/json-output.md.


Building and development

Target Description
make build Build the binary to bin/sparkplugbctl
make test Run all tests
make lint Run go vet and staticcheck
make install Install to $GOPATH/bin
make clean Remove build artifacts
git clone https://github.com/otfabric/sparkplugbctl.git
cd sparkplugbctl
make build
make test

License

MIT — see LICENSE.

About

Sparkplug B 3.0 MQTT CLI for monitoring, publishing and Protobuf encoding/decoding. Simulate Edge Nodes and Hosts; debug birth/death lifecycle events.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages