I was able to get a device going on my test bench with the following flow:
Here is the JSON of the flow if you’d like to try it out:
Node-RED Example Sparkplug Flow
[
{
"broker": "tcp://gateway",
"clientid": "NodeREDSimpleEdgeNode",
"credentials": {},
"edgenode": "Edge Node RED",
"enablecache": "false",
"groupid": "My MQTT Group",
"id": "21cb23aca25f8ff0",
"name": "",
"password": "changeme",
"port": "1883",
"publishdeath": "true",
"type": "sparkplug",
"user": "admin",
"version": "spBv1.0",
"wires": [
[
"ef55783b857bf953"
]
],
"x": 540,
"y": 320,
"z": "f6f2187d.f17ca8"
},
{
"active": true,
"complete": "true",
"console": false,
"id": "5a3e31b2cb00bee4",
"name": "sparkplug debug",
"statusType": "auto",
"statusVal": "",
"targetType": "full",
"tosidebar": true,
"tostatus": false,
"type": "debug",
"wires": [],
"x": 750,
"y": 320,
"z": "f6f2187d.f17ca8"
},
{
"finalize": "",
"func": "// Capture device name\nglobal.set(\"deviceId\", \"PLC 1\")\n\nvar payload = {\n \"timestamp\": msg.payload,\n}\nvar metrics = []\nmetrics.push({\n \"name\": \"CurrentSeconds\",\n \"value\": new Date().getSeconds(),\n \"type\": \"int32\"\n})\npayload[\"metrics\"] = metrics\nmsg.payload = payload\nmsg.topic = `${global.get(\"deviceId\")}/DBIRTH`\nflow.set(\"running\", true)\nreturn msg;\n",
"id": "744bbf99e693c7b5",
"initialize": "",
"libs": [],
"name": "DBIRTH",
"noerr": 0,
"outputs": 1,
"type": "function",
"wires": [
[
"f757327680907b72"
]
],
"x": 300,
"y": 260,
"z": "f6f2187d.f17ca8"
},
{
"id": "8bff98c79de5e59f",
"links": [
"5eebf0852ffa9b5c"
],
"name": "Rebirth",
"type": "link in",
"wires": [
[
"744bbf99e693c7b5"
]
],
"x": 55,
"y": 200,
"z": "f6f2187d.f17ca8"
},
{
"id": "5eebf0852ffa9b5c",
"links": [
"8bff98c79de5e59f"
],
"mode": "link",
"name": "Rebirth",
"type": "link out",
"wires": [],
"x": 845,
"y": 200,
"z": "f6f2187d.f17ca8"
},
{
"checkall": "true",
"id": "110b822bcda4a472",
"name": "Route Outputs",
"outputs": 1,
"property": "topic",
"propertyType": "msg",
"repair": false,
"rules": [
{
"t": "eq",
"v": "rebirth",
"vt": "str"
}
],
"type": "switch",
"wires": [
[
"5eebf0852ffa9b5c"
]
],
"x": 660,
"y": 200,
"z": "f6f2187d.f17ca8"
},
{
"crontab": "",
"id": "46bec1e9c2b3a746",
"name": "Update",
"once": true,
"onceDelay": 0.1,
"payload": "",
"payloadType": "date",
"props": [
{
"p": "payload"
},
{
"p": "running",
"v": "running",
"vt": "flow"
}
],
"repeat": "1",
"topic": "",
"type": "inject",
"wires": [
[
"09e10fa13e6c9609"
]
],
"x": 100,
"y": 320,
"z": "f6f2187d.f17ca8"
},
{
"finalize": "",
"func": "if (!msg.running) {\n return null;\n}\nvar payload = {\n \"timestamp\": msg.payload\n}\nvar metrics = []\nmetrics.push({\n \"name\": \"CurrentSeconds\",\n \"value\": new Date().getSeconds(),\n \"type\": \"int32\"\n})\npayload[\"metrics\"] = metrics\nmsg.payload = payload\nmsg.topic = `${global.get(\"deviceId\")}/DDATA`\nreturn msg;\n\n",
"id": "09e10fa13e6c9609",
"initialize": "",
"libs": [],
"name": "DDATA",
"noerr": 0,
"outputs": 1,
"type": "function",
"wires": [
[
"21cb23aca25f8ff0"
]
],
"x": 310,
"y": 320,
"z": "f6f2187d.f17ca8"
},
{
"finalize": "",
"func": "var payload = {\n \"timestamp\": msg.payload,\n}\nmsg.payload = payload\nmsg.topic = `${global.get(\"deviceId\")}/DDEATH`\nflow.set(\"running\", false)\nreturn msg;\n",
"id": "1d621881bee11c4e",
"initialize": "",
"libs": [],
"name": "DDEATH",
"noerr": 0,
"outputs": 1,
"type": "function",
"wires": [
[
"f757327680907b72"
]
],
"x": 300,
"y": 380,
"z": "f6f2187d.f17ca8"
},
{
"crontab": "",
"id": "08421e63bb112d1e",
"name": "Stop",
"once": false,
"onceDelay": 0.1,
"payload": "",
"payloadType": "date",
"props": [
{
"p": "payload"
},
{
"p": "reset",
"v": "true",
"vt": "str"
}
],
"repeat": "",
"topic": "",
"type": "inject",
"wires": [
[
"1d621881bee11c4e"
]
],
"x": 90,
"y": 380,
"z": "f6f2187d.f17ca8"
},
{
"crontab": "",
"id": "d95cf0a12dcc1815",
"name": "Start",
"once": false,
"onceDelay": 0.1,
"payload": "",
"payloadType": "date",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"topic": "",
"type": "inject",
"wires": [
[
"744bbf99e693c7b5"
]
],
"x": 90,
"y": 260,
"z": "f6f2187d.f17ca8"
},
{
"id": "ef55783b857bf953",
"type": "junction",
"wires": [
[
"5a3e31b2cb00bee4",
"110b822bcda4a472"
]
],
"x": 620,
"y": 320,
"z": "f6f2187d.f17ca8"
},
{
"id": "f757327680907b72",
"type": "junction",
"wires": [
[
"21cb23aca25f8ff0"
]
],
"x": 440,
"y": 320,
"z": "f6f2187d.f17ca8"
}
]
I hadn’t spooled up Node-RED in a while, and I think I had much better luck with this latest revision of the node-red-contrib-sparkplug node than the last time I tried a few years ago.