Read/Write/Update Dataset Tag using Sparkplug B

I am looking to read and write a dataset via sparkplug B. I think I have parsed the spec correctly to generate a sparkplug b payload. Using MQTTX, I am able to parse sparkplug b payload and when I capture the dataset payload it is being fully represented but the dataset does not update in ignition.

I hope someone with experience with this can assist me figuring out what I am doing wrong. I know that I can update other tags via sparkplug b, but with datasets I have hit a wall.

I am publishing to this topic which works for other tags

spBv1.0/Injection-H1/DCMD/MES/Zima

I am testing this from node-red, I have an inject node with msg.payload set to the following

{
    "metrics": [
        {
            "name": "Job/BOM",
            "datatype": 16,
            "dataset_value": {
                "num_of_columns": 5,
                "columns": [
                    "Item",
                    "Quantity",
                    "Unit of Measure",
                    "Operation",
                    "Type"
                ],
                "types": [
                    12,
                    9,
                    12,
                    2,
                    12
                ],
                "rows": [
                    {
                        "elements": [
                            {
                                "string_value": "Item Code"
                            },
                            {
                                "float_value": 1.588
                            },
                            {
                                "string_value": "LB"
                            },
                            {
                                "int_value": 10
                            },
                            {
                                "string_value": "RESN"
                            }
                        ]
                    }
                ]
            }
        }
    ]
}

Any assistance would be appreciated.

The DCMD topic is meant for publishing commands to devices.

Ignition is acting as the primary application, and I'd expect it's receiving updates from devices on the DDATA topic.

You've gone a bit deeper into nuts and bolts of Sparkplug than most people who use Ignition can talk to. For Sparkplug technical questions like this, you're likely to get a better response from the mailing list or slack workspace mentioned on this Sparkplug page.

On top of what Kevin said, I also suspect you aren't sending NBIRTH/DBIRTH messages first to inform Ignition of which tags to expect from your edge node. Sparkplug is a stateful system and you can't just throw one random data point in without setting up a sort of schema and announcing your device is online first.

In my case "Ignition" refers to an Ignition Edge instance which is acting as a device. It consumes tags from a PLC via OPC UA and has a few of it's own tags that are being broadcasted to our local ignition gateway via the MQTT Transmission plugin.

Like I said, the methodology I can using to set tags is working for every other tag I have tried and datasets are the only ones not working for me.

I don't know then. Maybe check on the Cirrus Link forum like @justin.brzozoski suggested.

I assume there's something with node red going on here that I don't know about. It must have some knowledge of Sparkplug so that it can encode that JSON object into the binary protobuf format that is actually used by Sparkplug. Could be an issue there when it comes to datasets?

To send a Sparkplug B message via Node-RED there are two ways to do so.

  1. Use the Sparkplug B nodes that can be added to the pallete
  2. Install the protobuf nodes, upload thesparkplug_b.proto file to the device, and use the encode/decode nodes to encode/decode a sparkplug B payload.

From your description, it sound like you have an Ignition edge running MQTT Transmission talking to an Ignition gateway running MQTT Engine. Write to the tag once from the gateway system and capture what the payload looks like to see what how it encodes it. Writing to tags from the MQTT Engine side of things generates NCMD/DCMD messages back to the edge.

Ok I'm not 100% sure what I did differently today from yesterday but I have figured it out. For one, in Ignition you can look at the raw data for a tag, which can give you an idea of what the payload should look like though it's not a one for one translation to Sparkplug B.

With 1 row of data in the dataset this is what the raw data looks like specifically looking at the value property.
image

Values Property

{
    "columns": [
        {
            "name": "Item",
            "type": "java.lang.String"
        },
        {
            "name": "Quantity",
            "type": "java.lang.Float"
        },
        {
            "name": "Unit of Measure",
            "type": "java.lang.String"
        },
        {
            "name": "Operation",
            "type": "java.lang.Short"
        },
        {
            "name": "Type",
            "type": "java.lang.String"
        }
    ],
    "rows": [
        [
            "Some Item",
            1.588,
            "LB",
            10,
            "RESN"
        ]
    ]
}

From Node-RED this is the payload I sent to get it to update.
image

{
    "metrics": [
        {
            "name": "Job/BOM",
            "datatype": 16,
            "dataset_value": {
                "num_of_columns": 5,
                "columns": [
                    "Item",
                    "Quantity",
                    "Unit of Measure",
                    "Operation",
                    "Type"
                ],
                "types": [
                    12,
                    9,
                    12,
                    2,
                    12
                ],
                "rows": [
                    {
                        "elements": [
                            {
                                "string_value": "Some Item"
                            },
                            {
                                "float_value": 1.588
                            },
                            {
                                "string_value": "LB"
                            },
                            {
                                "int_value": 10
                            },
                            {
                                "string_value": "RESN"
                            }
                        ]
                    }
                ]
            }
        }
    ]
}

Hope this can help someone else in the future

FWIW. I use this palette i NodeRed "node-red-contrib-mqtt-sparkplug-plus" then I don't have to worry about BIRTH/DEATH and encoding/decoding

Yes I know about those I was using node-RED as a scratch pad to figure out payloads for my android application.

If you just need node-red then those nodes are the way to go.