Skip to main content

Configuration-driven SparkPlug B packet builder and decoder for industrial IoT applications

Project description

esio-spb-builder

A configuration-driven SparkplugB packet builder for IoT applications that simplifies the creation and management of SparkplugB protocol messages with proper bdSeq handling and hierarchical device organization.

Features

  • 🏗️ Configuration-Driven: Define your edge nodes and devices in JSON/YAML, not code
  • 📊 Proper bdSeq Management: Handles the critical birth/death sequence numbers correctly
  • 🌳 Hierarchical Structure: Group → Edge Node → Device organization
  • 💾 Persistence: Save and load configurations for consistent deployments
  • 🔄 Dynamic Updates: Runtime metric updates without recompilation
  • Protocol Compliance: Includes all required SparkplugB metrics (Node Control, bdSeq)
  • 🎯 Type Safety: Full type hints and validation
  • 🔍 Visualization: Built-in tools to explore and display your configuration

Why This Library?

SparkplugB is powerful but complex. Traditional approaches require:

  • Hardcoded enums for metric aliases
  • Custom classes for each node/device type
  • Manual bdSeq management (easy to get wrong)
  • Recompilation for configuration changes

esio-spb-builder solves these problems by:

  • Using configuration files instead of code
  • Automatically managing aliases and required metrics
  • Handling bdSeq correctly for MQTT session management
  • Supporting runtime configuration changes

Installation

pip install esio-spb-builder

Development installation:

git clone https://github.com/edgestack/esio-spb-builder
cd esio-spb-builder
pip install -e ".[dev]"

Quick Start

from esio_spb_builder import (
    SpBConfigurationManager,
    EdgeNodeFactory,
    HierarchyDisplay,
)

# Create configuration
config = SpBConfigurationManager()

# Add a group (location/namespace)
config.add_group("oil.field.texas", "Texas oil field site")

# Add an edge node with metrics
config.add_node(
    group_id="oil.field.texas",
    node_id="edge-01",
    description="Primary edge gateway",
    metrics=[
        {"name": "CPU/Load", "data_type": "Float", "value": 0.0},
        {"name": "Memory/Free", "data_type": "UInt64", "value": 0}
    ]
)

# Add a device to the node
config.add_device(
    group_id="oil.field.texas",
    node_id="edge-01",
    device_id="sensor-01",
    description="Temperature sensor",
    metrics=[
        {
            "name": "Temperature",
            "data_type": "Float",
            "value": 20.0,
            "properties": [
                {"name": "EngUnit", "data_type": "String", "value": "°C"}
            ]
        }
    ]
)

# Create factory and build runtime instance
factory = EdgeNodeFactory(config)
edge_node = factory.create_edge_node("oil.field.texas", "edge-01")

# Generate SparkplugB packets
nbirth = edge_node.birth_certificate()
print(f"Publishing to: {nbirth.topic}")
print(f"Payload: {nbirth.serialize()}")

# Update metrics
edge_node.update_metrics({
    "CPU/Load": 45.5,
    "Memory/Free": 8192000000
})

# Send data packet
ndata = edge_node.data_packet()

Configuration Structure

The library uses a hierarchical configuration that mirrors the SparkplugB protocol:

version: "1.0.0"
groups:
  oil.field.texas:
    description: "Texas oil field"
    edge_nodes:
      edge-01:
        description: "Primary edge gateway"
        metrics:
          - name: "CPU/Load"
            alias: 10  # Auto-assigned if not provided
            data_type: "Float"
            value: 0.0
        devices:
          ogi-camera:
            description: "Optical gas imaging camera"
            metrics:
              - name: "Flow/Rate"
                alias: 100
                data_type: "Float"
                value: 0.0
                properties:
                  - name: "EngUnit"
                    data_type: "String"
                    value: "SCFH"

Key Concepts

Required Metrics

The library automatically includes SparkplugB required metrics:

  • Node Control/Rebirth (alias 1): Command to request rebirth
  • Node Control/Next Server (alias 0): Command for failover
  • Node Control/Reboot (alias 2): Command to reboot
  • bdSeq: Birth/death sequence for session management

bdSeq Management

The birth/death sequence (bdSeq) is critical for MQTT session management. The library handles this automatically:

# First session
nbirth1 = edge_node.birth_certificate()  # bdSeq included
# ... send data ...
ndeath1 = edge_node.death_certificate()   # bdSeq incremented

# Next session will have incremented bdSeq
nbirth2 = edge_node.birth_certificate()  # New bdSeq

Metric Aliases

Aliases are numeric identifiers for metrics that reduce payload size. The library:

  • Auto-assigns aliases if not provided
  • Prevents conflicts between metrics
  • Preserves aliases when configuration changes
  • Tracks deprecated aliases to prevent reuse

Advanced Usage

Loading from File

# Load from JSON
config = SpBConfigurationManager.load_from_file("config.json")

# Load from YAML
config = SpBConfigurationManager.load_from_file("config.yaml")

Visualization Tools

from esio_spb_builder import HierarchyDisplay, MetricExplorer

# Display hierarchy
display = HierarchyDisplay(config)
print(display.display_tree())

# Explore metrics
explorer = MetricExplorer(config)
flow_metrics = explorer.find_metric("flow")
command_metrics = explorer.get_command_metrics()

Command Processing

# Process NCMD command
action = edge_node.process_command(alias=1, value=True)
if action == "rebirth":
    packets = edge_node.rebirth()  # Returns all birth certificates

Change Tracking

# Only send changed metrics in NDATA
edge_node.update_metric("CPU/Load", 50.0)
data_packet = edge_node.data_packet(send_all=False)  # Only CPU/Load

MQTT Integration

import paho.mqtt.client as mqtt
from esio_spb_builder import EdgeNodeFactory

# Create MQTT client
client = mqtt.Client()
client.connect("broker.mqtt.com", 1883)

# Create edge node
factory = EdgeNodeFactory(config)
edge_node = factory.create_edge_node("group", "node")

# Send NBIRTH
nbirth = edge_node.birth_certificate()
client.publish(nbirth.topic, nbirth.serialize())

# Send NDATA periodically
def send_data():
    edge_node.update_metrics(get_current_values())
    ndata = edge_node.data_packet()
    client.publish(ndata.topic, ndata.serialize())

API Reference

Core Classes

  • SpBConfigurationManager: Manages the complete configuration
  • EdgeNodeFactory: Creates runtime instances from configuration
  • DynamicEdgeNode: Runtime edge node that generates packets
  • DynamicDevice: Runtime device that generates packets

Packet Types

  • NBirthPacket: Node birth certificate
  • NDataPacket: Node data
  • NDeathPacket: Node death certificate
  • NCmdPacket: Node command
  • DBirthPacket: Device birth certificate
  • DDataPacket: Device data
  • DDeathPacket: Device death certificate
  • DCmdPacket: Device command

Utilities

  • HierarchyDisplay: Visualize configuration structure
  • MetricExplorer: Search and analyze metrics
  • PacketDecoder: Decode received SparkplugB packets

Testing

Run the test suite:

pytest tests/

Run with coverage:

pytest --cov=esio_spb_builder tests/

Examples

See the examples/ directory for complete examples:

  • complete_example.py: Full demonstration of all features
  • Configuration samples in JSON and YAML

Architecture

Configuration (JSON/YAML)
         ↓
SpBConfigurationManager
         ↓
EdgeNodeFactory
         ↓
DynamicEdgeNode / DynamicDevice
         ↓
SparkplugB Packets (NBIRTH, NDATA, etc.)
         ↓
MQTT Broker

Comparison with Traditional Approach

Traditional (sparkplug-b-packets style)

# Requires hardcoded enums
class AliasMap(IntEnum):
    CPU_Load = 3
    Memory_Avail = 4

# Requires custom classes
class MyNodeBirth(NBirthPacket):
    def __init__(self):
        super().__init__(metrics=get_metrics())

# Metrics defined in code
def get_metrics():
    return OrderedDict(...)

With esio-spb-builder

# Load configuration
config = SpBConfigurationManager.load_from_file("config.json")

# Create and use
factory = EdgeNodeFactory(config)
node = factory.create_edge_node("group", "node")
birth = node.birth_certificate()

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Acknowledgments

Built for the EdgeStack IoT platform to simplify SparkplugB implementation and ensure protocol compliance.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

esio_spb_builder-0.1.0.tar.gz (125.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

esio_spb_builder-0.1.0-py3-none-any.whl (28.8 kB view details)

Uploaded Python 3

File details

Details for the file esio_spb_builder-0.1.0.tar.gz.

File metadata

  • Download URL: esio_spb_builder-0.1.0.tar.gz
  • Upload date:
  • Size: 125.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for esio_spb_builder-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e49c65af2bf3c82ef2d4d2dd2994ab6f182ef3eb4e4f05cafcd10f437a89a243
MD5 c1968f6e0d65cb7a5081578960e9b359
BLAKE2b-256 9eb77be6dbdf6e63919ff3c85dcae0bcdf4fd2a593199fb964301c1082f39362

See more details on using hashes here.

File details

Details for the file esio_spb_builder-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: esio_spb_builder-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 28.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for esio_spb_builder-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5dc2f5b32c5a496a34fea7c4034c5e04206bc07448a9f2bba5e9a0eec9a3b259
MD5 44ca913c4a3785761321a1878b3f69cc
BLAKE2b-256 94faf8c90596ed9f82902c8c6d70e9676d0416c87484e905c768ab51b8e3b97d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page