Copying the post from the archive:
I wanted to share a flow I created that shows master and slave inverter stats, and any imbalances.
You will need to edit the “cerbo” mqtt endpoint to point to the IP of your own system or just use localhost (127.0.0.1).
Device ID’s are fixed values for every installation. See the note in the flow. The defaults for single (L1) phase will work.
Additional phases can be added using the mapping provided.
The flow uses dashboard 2.0 (flowfuse/node-red-dashboard) but you can replace those nodes with dash 1.0.
At low power the inverters may track high imbalances, this is especially true for AC IN if you are maintaining a low setpoint. It should show a representative value under load.
When working it should look like this:
Here is the flow:
[
{
"id": "af466230632ad910",
"type": "tab",
"label": "Parallel L1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "76406dc6e7e04f2b",
"type": "ui-text",
"z": "af466230632ad910",
"group": "93e86f6a5912e02d",
"order": 6,
"width": 0,
"height": 0,
"name": "L1 Slave AC OUT",
"label": "L1 Slave AC OUT (W)",
"format": "{{msg.payload}}",
"layout": "row-spread",
"style": false,
"font": "",
"fontSize": 16,
"color": "#717171",
"wrapText": false,
"className": "",
"x": 530,
"y": 180,
"wires": []
},
{
"id": "a67391c82331d181",
"type": "ui-text",
"z": "af466230632ad910",
"group": "93e86f6a5912e02d",
"order": 5,
"width": 0,
"height": 0,
"name": "L1 Master AC OUT",
"label": "L1 Master AC OUT (W)",
"format": "{{msg.payload}}",
"layout": "row-spread",
"style": false,
"font": "",
"fontSize": 16,
"color": "#717171",
"wrapText": false,
"className": "",
"x": 530,
"y": 240,
"wires": []
},
{
"id": "c5a5dd36f002a701",
"type": "ui-text",
"z": "af466230632ad910",
"group": "93e86f6a5912e02d",
"order": 4,
"width": 0,
"height": 0,
"name": "L1 Slave AC IN",
"label": "L1 Slave AC IN (W)",
"format": "{{msg.payload}}",
"layout": "row-spread",
"style": false,
"font": "",
"fontSize": 16,
"color": "#717171",
"wrapText": false,
"className": "",
"x": 520,
"y": 300,
"wires": []
},
{
"id": "6b93b71f638181ed",
"type": "ui-text",
"z": "af466230632ad910",
"group": "93e86f6a5912e02d",
"order": 3,
"width": 0,
"height": 0,
"name": "L1 Master AC IN",
"label": "L1 Master AC IN (W)",
"format": "{{msg.payload}}",
"layout": "row-spread",
"style": false,
"font": "",
"fontSize": 16,
"color": "#717171",
"wrapText": false,
"className": "",
"x": 520,
"y": 360,
"wires": []
},
{
"id": "2fd15a2be5c55233",
"type": "function",
"z": "af466230632ad910",
"name": "calc delta",
"func": "var master = flow.get(\"MACOUT\");\nvar slave = flow.get(\"SACOUT\");\nvar delta = master - slave;\nvar total = master + slave;\nif (delta < 0) {\n delta = slave - master;\n}\nvar perc = (delta/total)*100;\nmsg.payload = perc.toFixed(0);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 320,
"y": 540,
"wires": [
[
"963907f37327c2a1"
]
]
},
{
"id": "53ecadfcb64d4205",
"type": "inject",
"z": "af466230632ad910",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "2",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 540,
"wires": [
[
"2fd15a2be5c55233"
]
]
},
{
"id": "efb8a0149eecb44a",
"type": "change",
"z": "af466230632ad910",
"name": "",
"rules": [
{
"t": "set",
"p": "MACOUT",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 510,
"y": 100,
"wires": [
[]
]
},
{
"id": "9fb61f21a877dcaa",
"type": "change",
"z": "af466230632ad910",
"name": "",
"rules": [
{
"t": "set",
"p": "SACOUT",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 510,
"y": 60,
"wires": [
[]
]
},
{
"id": "963907f37327c2a1",
"type": "ui-gauge",
"z": "af466230632ad910",
"name": "Parallel imbalance",
"group": "93e86f6a5912e02d",
"order": 2,
"value": "payload",
"valueType": "msg",
"width": 0,
"height": 0,
"gtype": "gauge-half",
"gstyle": "needle",
"title": "Output imbalance",
"units": "%",
"icon": "",
"prefix": "",
"suffix": "",
"segments": [
{
"from": "0",
"color": "#5cd65c"
},
{
"from": "8",
"color": "#ffc800"
},
{
"from": "16",
"color": "#ea5353"
}
],
"min": 0,
"max": "20",
"sizeThickness": 16,
"sizeGap": 4,
"sizeKeyThickness": 8,
"styleRounded": true,
"styleGlow": false,
"className": "",
"x": 570,
"y": 540,
"wires": []
},
{
"id": "690e79ed2160cf69",
"type": "change",
"z": "af466230632ad910",
"name": "",
"rules": [
{
"t": "set",
"p": "MACIN",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 480,
"wires": [
[]
]
},
{
"id": "2c358cbfb3088750",
"type": "change",
"z": "af466230632ad910",
"name": "",
"rules": [
{
"t": "set",
"p": "SACIN",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 420,
"wires": [
[]
]
},
{
"id": "e032d9f7800ca055",
"type": "function",
"z": "af466230632ad910",
"name": "calc IN delta",
"func": "var master = flow.get(\"MACIN\");\nvar slave = flow.get(\"SACIN\");\nvar delta = Math.abs(master - slave);\nvar total = Math.abs(master) + Math.abs(slave);\nvar perc = (delta/total)*100;\nmsg.payload = perc.toFixed(0);\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 600,
"wires": [
[
"d9dcfee5b8f91221"
]
]
},
{
"id": "095569a80c1ac60a",
"type": "inject",
"z": "af466230632ad910",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "2",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 600,
"wires": [
[
"e032d9f7800ca055"
]
]
},
{
"id": "d9dcfee5b8f91221",
"type": "ui-gauge",
"z": "af466230632ad910",
"name": "Input imbalance",
"group": "93e86f6a5912e02d",
"order": 1,
"width": 0,
"height": 0,
"gtype": "gauge-half",
"gstyle": "needle",
"title": "Input imbalance",
"units": "%",
"icon": "",
"prefix": "",
"suffix": "",
"segments": [
{
"from": "0",
"color": "#5cd65c"
},
{
"from": "30",
"color": "#ffc800"
},
{
"from": "60",
"color": "#ea5353"
}
],
"min": 0,
"max": "100",
"sizeThickness": 16,
"sizeGap": 4,
"sizeKeyThickness": 8,
"styleRounded": true,
"styleGlow": false,
"className": "",
"x": 560,
"y": 600,
"wires": []
},
{
"id": "107682690189825e",
"type": "victron-input-custom",
"z": "af466230632ad910",
"service": "com.victronenergy.vebus/276",
"path": "/Devices/3/Ac/Out/P",
"serviceObj": {
"service": "com.victronenergy.vebus/276",
"name": "Nuclear Reactor (276)"
},
"pathObj": {
"path": "/Devices/3/Ac/Out/P",
"name": "/Devices/3/Ac/Out/P",
"type": "number",
"value": 717
},
"name": "L1 Slave AC OUT",
"onlyChanges": false,
"roundValues": "0",
"x": 200,
"y": 160,
"wires": [
[
"76406dc6e7e04f2b",
"9fb61f21a877dcaa"
]
]
},
{
"id": "e278c4827acd63aa",
"type": "victron-input-custom",
"z": "af466230632ad910",
"service": "com.victronenergy.vebus/276",
"path": "/Devices/0/Ac/Out/P",
"serviceObj": {
"service": "com.victronenergy.vebus/276",
"name": "Nuclear Reactor (276)"
},
"pathObj": {
"path": "/Devices/0/Ac/Out/P",
"name": "/Devices/0/Ac/Out/P",
"type": "number",
"value": 613
},
"name": "L1 Master AC OUT",
"onlyChanges": false,
"roundValues": "0",
"x": 210,
"y": 240,
"wires": [
[
"a67391c82331d181",
"efb8a0149eecb44a"
]
]
},
{
"id": "2c33f62af1fe7949",
"type": "victron-input-custom",
"z": "af466230632ad910",
"service": "com.victronenergy.vebus/276",
"path": "/Devices/3/Ac/In/P",
"serviceObj": {
"service": "com.victronenergy.vebus/276",
"name": "Nuclear Reactor (276)"
},
"pathObj": {
"path": "/Devices/3/Ac/In/P",
"name": "/Devices/3/Ac/In/P",
"type": "number",
"value": 0
},
"name": "L1 Slave AC IN",
"onlyChanges": false,
"roundValues": "0",
"x": 200,
"y": 300,
"wires": [
[
"c5a5dd36f002a701",
"2c358cbfb3088750"
]
]
},
{
"id": "320757b9dd9ed716",
"type": "victron-input-custom",
"z": "af466230632ad910",
"service": "com.victronenergy.vebus/276",
"path": "/Devices/0/Ac/In/P",
"serviceObj": {
"service": "com.victronenergy.vebus/276",
"name": "Nuclear Reactor (276)"
},
"pathObj": {
"path": "/Devices/0/Ac/In/P",
"name": "/Devices/0/Ac/In/P",
"type": "number",
"value": 0
},
"name": "L1 Master AC IN",
"onlyChanges": false,
"roundValues": "0",
"x": 200,
"y": 360,
"wires": [
[
"6b93b71f638181ed",
"690e79ed2160cf69"
]
]
},
{
"id": "2e7ded39964f02bb",
"type": "comment",
"z": "af466230632ad910",
"name": "Device ID order for Multis and Quattros",
"info": "L1 Master 0\nL1 Slave1 3\nL1 Slave2 6\nL1 Slave3 9\nL2 Master 1\nL2 Slave1 4\nL2 Slave2 7\nL2 Slave3 10\nL3 Master 2\nL3 Slave1 5\nL3 Slave2 8\nL3 Slave3 11",
"x": 170,
"y": 80,
"wires": []
},
{
"id": "4098f447ca28b495",
"type": "ui-chart",
"z": "af466230632ad910",
"group": "93e86f6a5912e02d",
"name": "L1 AC OUT balance",
"label": "L1 AC OUT balance",
"order": 9007199254740991,
"chartType": "doughnut",
"category": "series",
"categoryType": "property",
"xAxisLabel": "",
"xAxisProperty": "inverter",
"xAxisPropertyType": "property",
"xAxisType": "radial",
"xAxisFormat": "",
"xAxisFormatType": "auto",
"xmin": "",
"xmax": "",
"yAxisLabel": "",
"yAxisProperty": "power",
"yAxisPropertyType": "property",
"ymin": "",
"ymax": "",
"bins": 10,
"action": "replace",
"stackSeries": false,
"pointShape": "circle",
"pointRadius": 4,
"showLegend": true,
"removeOlder": 1,
"removeOlderUnit": "3600",
"removeOlderPoints": "",
"colors": [
"#0095ff",
"#ff7f0e",
"#ff7f0e",
"#2ca02c",
"#a347e1",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"textColor": [
"#666666"
],
"textColorDefault": true,
"gridColor": [
"#e5e5e5"
],
"gridColorDefault": true,
"width": "3",
"height": "3",
"className": "",
"interpolation": "linear",
"x": 640,
"y": 660,
"wires": [
[]
]
},
{
"id": "05b3cd7a4fa49669",
"type": "function",
"z": "af466230632ad910",
"name": "Format chart",
"func": "var master = flow.get(\"MACOUT\");\nvar slave = flow.get(\"SACOUT\");\n\nmsg.payload = {};\nmsg.payload = {};\nmsg = { \"payload\": [{\n \"series\" : \"L1 Power\",\n \"inverter\": \"Master\", \n \"power\": master },\n {\"series\" : \"L1 Power\",\n \"inverter\": \"Slave\", \n \"power\": slave\n}]\n}\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 390,
"y": 660,
"wires": [
[
"4098f447ca28b495"
]
]
},
{
"id": "d392ad592cfffeef",
"type": "inject",
"z": "af466230632ad910",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "2",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 660,
"wires": [
[
"05b3cd7a4fa49669"
]
]
},
{
"id": "acea9df5e2d0fb1b",
"type": "ui-chart",
"z": "af466230632ad910",
"group": "93e86f6a5912e02d",
"name": "L1 AC IN balance",
"label": "L1 AC IN Balance",
"order": 9007199254740991,
"chartType": "doughnut",
"category": "series",
"categoryType": "property",
"xAxisLabel": "",
"xAxisProperty": "inverter",
"xAxisPropertyType": "property",
"xAxisType": "radial",
"xAxisFormat": "",
"xAxisFormatType": "auto",
"xmin": "",
"xmax": "",
"yAxisLabel": "",
"yAxisProperty": "power",
"yAxisPropertyType": "property",
"ymin": "",
"ymax": "",
"bins": 10,
"action": "replace",
"stackSeries": false,
"pointShape": "circle",
"pointRadius": 4,
"showLegend": false,
"removeOlder": 1,
"removeOlderUnit": "3600",
"removeOlderPoints": "",
"colors": [
"#0095ff",
"#ff7f0e",
"#ff7f0e",
"#2ca02c",
"#a347e1",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"textColor": [
"#666666"
],
"textColorDefault": true,
"gridColor": [
"#e5e5e5"
],
"gridColorDefault": true,
"width": "3",
"height": "3",
"className": "",
"interpolation": "linear",
"x": 630,
"y": 720,
"wires": [
[]
]
},
{
"id": "6f37874711cc944c",
"type": "function",
"z": "af466230632ad910",
"name": "format chart",
"func": "var master = flow.get(\"MACIN\");\nvar slave = flow.get(\"SACIN\");\n\nmsg.payload = {};\nmsg.payload = {};\nmsg = { \"payload\": [{\n \"series\" : \"L1 Power\",\n \"inverter\": \"Master\", \n \"power\": master },\n {\"series\" : \"L1 Power\",\n \"inverter\": \"Slave\", \n \"power\": slave\n}]\n}\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 390,
"y": 720,
"wires": [
[
"acea9df5e2d0fb1b"
]
]
},
{
"id": "b360957c1fc7d251",
"type": "inject",
"z": "af466230632ad910",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "2",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 720,
"wires": [
[
"6f37874711cc944c"
]
]
},
{
"id": "5941c96ce50a5fa1",
"type": "function",
"z": "af466230632ad910",
"name": "Chart inverters",
"func": "msg.payload = {};\nvar masterin = flow.get(\"MACIN\");\nvar slavein = flow.get(\"SACIN\");\nvar masterout = flow.get(\"MACOUT\");\nvar slaveout = flow.get(\"SACOUT\");\nvar deltaout = Math.abs(masterout - slaveout);\nvar deltain = Math.abs(masterin - slavein);\n\nmsg = { \"payload\": [{\n \"series\" : \"AC OUT imbalance\",\n \"y\" : deltaout\n},{\n \"series\" : \"AC IN imbalance\",\n \"y\" : deltain\n},{\n \"series\" : \"Master IN\",\n \"y\" : masterin\n},{\n \"series\" : \"Slave IN\",\n \"y\" : slavein\n},{\n \"series\" : \"Master OUT\",\n \"y\" : masterout\n},{\n \"series\" : \"Slave OUT\",\n \"y\" : slaveout\n}]\n}\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 380,
"y": 780,
"wires": [
[
"cab2172cb8138722"
]
]
},
{
"id": "5b8f182e6bee161a",
"type": "inject",
"z": "af466230632ad910",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "30",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 170,
"y": 780,
"wires": [
[
"5941c96ce50a5fa1"
]
]
},
{
"id": "cab2172cb8138722",
"type": "ui-chart",
"z": "af466230632ad910",
"group": "90a5c95cd3c30a40",
"name": "Inverter Balance",
"label": "Inverter power and deviation",
"order": 6,
"chartType": "line",
"category": "series",
"categoryType": "property",
"xAxisLabel": "Time",
"xAxisProperty": "",
"xAxisPropertyType": "property",
"xAxisType": "time",
"xAxisFormat": "",
"xAxisFormatType": "auto",
"xmin": "",
"xmax": "",
"yAxisLabel": "Power (W)",
"yAxisProperty": "y",
"yAxisPropertyType": "property",
"ymin": "-9000",
"ymax": "9000",
"bins": "",
"action": "append",
"stackSeries": false,
"pointShape": "circle",
"pointRadius": "2",
"showLegend": true,
"removeOlder": "24",
"removeOlderUnit": "3600",
"removeOlderPoints": "",
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"textColor": [
"#666666"
],
"textColorDefault": true,
"gridColor": [
"#e5e5e5"
],
"gridColorDefault": true,
"width": "8",
"height": "7",
"className": "",
"interpolation": "linear",
"x": 640,
"y": 780,
"wires": [
[]
]
},
{
"id": "93e86f6a5912e02d",
"type": "ui-group",
"name": "Parallel stats",
"page": "1f3f6aba836b135f",
"width": "3",
"height": "1",
"order": 1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "90a5c95cd3c30a40",
"type": "ui-group",
"name": "Charts",
"page": "1f3f6aba836b135f",
"width": "8",
"height": "1",
"order": 3,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "1f3f6aba836b135f",
"type": "ui-page",
"name": "Home",
"ui": "20a0d5584e491036",
"path": "/page1",
"icon": "Home",
"layout": "grid",
"theme": "199c1371468ee29c",
"order": 1,
"className": "",
"visible": true,
"disabled": false
},
{
"id": "20a0d5584e491036",
"type": "ui-base",
"name": "Home",
"path": "/dashboard",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false
},
{
"id": "199c1371468ee29c",
"type": "ui-theme",
"name": "Default",
"colors": {
"surface": "#ffffff",
"primary": "#0094ce",
"bgPage": "#eeeeee",
"groupBg": "#ffffff",
"groupOutline": "#cccccc"
},
"sizes": {
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
}
]
Click the link to download.
26/7 updated to add donut chart and line chart that graphs 24 hours of data.







