2017-05-02, 12:17 PM
Wasn't sure if starting a new post to share some node red was a bit untidy so maybe here's as good a place as any - is it worth having a sticky thread for people to share node-red code for others?
Anyway, first off -
This one takes a signalk feed from openplotter, turns it into json then strips out individual messages which are slowed down and sent to a gauge and graph - messages are from ds18B20 thermometers attached to engine head, alternator and exhaust.
(Also, openplotter turns the eng temp into a MTW water temp NMEA message which can be viewed in the dashboard of opencpn, really handy to see it all the time on opencpn running on an xperia android tablet in the cockpit)
This one displays the Pi processor temperature..
And this one controls a gpio pin as an output with a countdown timer. Set to seconds at the moment as I've only just got it working, easy to change to minutes by changing the "1000" to "60000". The output pin then controls a mosfet which turns on and off a fuel pump which in turn fills the diesel day tank from the main tank.
And finally this one either turns off the Pi or reboots it, closing down Opencpn first then waiting seconds.
The final page -
Anyone else have some late night work to share
Anyway, first off -
This one takes a signalk feed from openplotter, turns it into json then strips out individual messages which are slowed down and sent to a gauge and graph - messages are from ds18B20 thermometers attached to engine head, alternator and exhaust.
(Also, openplotter turns the eng temp into a MTW water temp NMEA message which can be viewed in the dashboard of opencpn, really handy to see it all the time on opencpn running on an xperia android tablet in the cockpit)
Code:
[
{
"id": "e4f071f4.9d219",
"type": "websocket in",
"z": "f2a52aa4.57c488",
"name": "SignalK input",
"server": "8d5a3102.d114b",
"client": "",
"x": 90,
"y": 60,
"wires": [
[
"6236cf2.e82443"
]
]
},
{
"id": "6236cf2.e82443",
"type": "json",
"z": "f2a52aa4.57c488",
"name": "",
"x": 110,
"y": 140,
"wires": [
[
"73afab5a.9132e4",
"4723ff3f.7f704",
"45d5799b.eb21c8"
]
]
},
{
"id": "73afab5a.9132e4",
"type": "jsonpath",
"z": "f2a52aa4.57c488",
"expression": "$.updates..values[?(@.path==\"propulsion.eng.temperature\")]..value",
"split": true,
"name": "EngTemp",
"x": 280,
"y": 40,
"wires": [
[
"48b77fcb.41eb6",
"e144dcc3.dd3bc"
]
]
},
{
"id": "48b77fcb.41eb6",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 430,
"y": 40,
"wires": [
[
"7f2f9ac3.dd65f4"
]
]
},
{
"id": "7f2f9ac3.dd65f4",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "Convert to deg C",
"func": "var numInput = Number(msg.payload);\nmsg.topic = \"Eng\";\nvar T = numInput-273.15;\nmsg.payload = T.toFixed(1);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 40,
"wires": [
[
"54c09bb3.2604a4"
]
]
},
{
"id": "54c09bb3.2604a4",
"type": "ui_chart",
"z": "f2a52aa4.57c488",
"name": "EngineGraph",
"group": "fd9a5f04.59fd5",
"order": 0,
"width": "23",
"height": "7",
"label": "Engine temperature history",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm",
"interpolate": "linear",
"nodata": "data",
"ymin": "",
"ymax": "",
"removeOlder": "4",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": "",
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"x": 800,
"y": 40,
"wires": [
[],
[]
]
},
{
"id": "618b030f.22a17c",
"type": "ui_gauge",
"z": "f2a52aa4.57c488",
"name": "EngTempGauge",
"group": "bdca5f6f.4b19b",
"order": 1,
"width": "3",
"height": "3",
"gtype": "gage",
"title": "Engine temperature",
"label": "Deg C",
"format": "{{value}}",
"min": 0,
"max": "120",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 800,
"y": 80,
"wires": []
},
{
"id": "4723ff3f.7f704",
"type": "jsonpath",
"z": "f2a52aa4.57c488",
"expression": "$.updates..values[?(@.path==\"propulsion.alt.temperature\")]..value",
"split": true,
"name": "Alt Temp",
"x": 280,
"y": 140,
"wires": [
[
"d06b0028.8768c",
"d8b26bd8.f0e168"
]
]
},
{
"id": "d06b0028.8768c",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 430,
"y": 120,
"wires": [
[
"a3a1d695.19e4d8"
]
]
},
{
"id": "a3a1d695.19e4d8",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "Convert to deg C",
"func": "var numInput = Number(msg.payload);\nmsg.topic = \"Eng\";\nvar T = numInput-273.15;\nmsg.payload = T.toFixed(1);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 120,
"wires": [
[
"43b342b.a6e44bc"
]
]
},
{
"id": "43b342b.a6e44bc",
"type": "ui_chart",
"z": "f2a52aa4.57c488",
"name": "Alt graph",
"group": "fd9a5f04.59fd5",
"order": 0,
"width": "23",
"height": "7",
"label": "Alt temperature history",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm",
"interpolate": "linear",
"nodata": "",
"ymin": "",
"ymax": "",
"removeOlder": "4",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": "",
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"x": 780,
"y": 120,
"wires": [
[],
[]
]
},
{
"id": "17de1699.4e1859",
"type": "ui_gauge",
"z": "f2a52aa4.57c488",
"name": "AltTempGauge",
"group": "bdca5f6f.4b19b",
"order": 1,
"width": "3",
"height": "3",
"gtype": "gage",
"title": "Alternator temperature",
"label": "Deg C",
"format": "{{value}}",
"min": 0,
"max": "120",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 800,
"y": 160,
"wires": []
},
{
"id": "45d5799b.eb21c8",
"type": "jsonpath",
"z": "f2a52aa4.57c488",
"expression": "$.updates..values[?(@.path==\"propulsion.exh.temperature\")]..value",
"split": true,
"name": "Exh Temp",
"x": 280,
"y": 240,
"wires": [
[
"29f50de2.54f8a2",
"4b8ee8f7.3b4618"
]
]
},
{
"id": "29f50de2.54f8a2",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 430,
"y": 200,
"wires": [
[
"32821815.27b8c8"
]
]
},
{
"id": "32821815.27b8c8",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "Convert to deg C",
"func": "var numInput = Number(msg.payload);\nmsg.topic = \"Eng\";\nvar T = numInput-273.15;\nmsg.payload = T.toFixed(1);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 200,
"wires": [
[
"33c47e65.c35d62"
]
]
},
{
"id": "33c47e65.c35d62",
"type": "ui_chart",
"z": "f2a52aa4.57c488",
"name": "ExhGraph",
"group": "fd9a5f04.59fd5",
"order": 0,
"width": "23",
"height": "7",
"label": "Exh temperature history",
"chartType": "line",
"legend": "true",
"xformat": "HH:mm",
"interpolate": "linear",
"nodata": "waiting",
"ymin": "",
"ymax": "",
"removeOlder": "4",
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": "",
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"x": 780,
"y": 200,
"wires": [
[],
[]
]
},
{
"id": "a29c25bf.5041f8",
"type": "ui_gauge",
"z": "f2a52aa4.57c488",
"name": "ExhTempGauge",
"group": "bdca5f6f.4b19b",
"order": 1,
"width": "3",
"height": "3",
"gtype": "gage",
"title": "Exhaust temperature",
"label": "Deg C",
"format": "{{value}}",
"min": 0,
"max": "120",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 805,
"y": 240,
"wires": []
},
{
"id": "4b8ee8f7.3b4618",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 430,
"y": 240,
"wires": [
[
"3a014991.dc6b26"
]
]
},
{
"id": "3a014991.dc6b26",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "Convert to deg C",
"func": "var numInput = Number(msg.payload);\nmsg.topic = \"Eng\";\nvar T = numInput-273.15;\nmsg.payload = T.toFixed(1);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 240,
"wires": [
[
"a29c25bf.5041f8"
]
]
},
{
"id": "d8b26bd8.f0e168",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "minute",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 430,
"y": 160,
"wires": [
[
"13c78571.dc64fb"
]
]
},
{
"id": "13c78571.dc64fb",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "Convert to deg C",
"func": "var numInput = Number(msg.payload);\nmsg.topic = \"Eng\";\nvar T = numInput-273.15;\nmsg.payload = T.toFixed(1);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 160,
"wires": [
[
"17de1699.4e1859"
]
]
},
{
"id": "e144dcc3.dd3bc",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"x": 430,
"y": 80,
"wires": [
[
"ddd247e5.33eef8"
]
]
},
{
"id": "ddd247e5.33eef8",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "Convert to deg C",
"func": "var numInput = Number(msg.payload);\nmsg.topic = \"Eng\";\nvar T = numInput-273.15;\nmsg.payload = T.toFixed(1);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 80,
"wires": [
[
"618b030f.22a17c"
]
]
},
{
"id": "8d5a3102.d114b",
"type": "websocket-listener",
"z": "",
"path": "ws://localhost:3000/signalk/v1/stream",
"wholemsg": "false"
},
{
"id": "fd9a5f04.59fd5",
"type": "ui_group",
"z": "",
"name": "Eng Temp Graphs",
"tab": "7cab7589.6fad8c",
"disp": true,
"width": "23"
},
{
"id": "bdca5f6f.4b19b",
"type": "ui_group",
"z": "",
"name": "Temperature gauges",
"tab": "5eb912bd.df78bc",
"disp": true,
"width": "24"
},
{
"id": "7cab7589.6fad8c",
"type": "ui_tab",
"z": "",
"name": "Graphs",
"icon": "dashboard",
"order": 2
},
{
"id": "5eb912bd.df78bc",
"type": "ui_tab",
"z": "",
"name": "Gauges",
"icon": "dashboard",
"order": 1
}
]
This one displays the Pi processor temperature..
Code:
[
{
"id": "a276b9a5.e58698",
"type": "exec",
"z": "f2a52aa4.57c488",
"command": "vcgencmd ",
"addpay": true,
"append": "measure_temp",
"useSpawn": "",
"timer": "",
"name": "",
"x": 290,
"y": 360,
"wires": [
[
"7abd88bc.53ddb8",
"fe55ec93.353fb"
],
[],
[]
]
},
{
"id": "7e75445e.4ae52c",
"type": "inject",
"z": "f2a52aa4.57c488",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "30",
"crontab": "",
"once": true,
"x": 130,
"y": 360,
"wires": [
[
"a276b9a5.e58698"
]
]
},
{
"id": "7abd88bc.53ddb8",
"type": "ui_text",
"z": "f2a52aa4.57c488",
"group": "bdca5f6f.4b19b",
"order": 0,
"width": "2",
"height": "3",
"name": "Textdisplay",
"label": "Pi processor ",
"format": "{{msg.payload}}",
"layout": "col-center",
"x": 470,
"y": 320,
"wires": []
},
{
"id": "fe55ec93.353fb",
"type": "debug",
"z": "f2a52aa4.57c488",
"name": "",
"active": true,
"console": "false",
"complete": "true",
"x": 470,
"y": 440,
"wires": []
},
{
"id": "bdca5f6f.4b19b",
"type": "ui_group",
"z": "",
"name": "Temperature gauges",
"tab": "5eb912bd.df78bc",
"disp": true,
"width": "24"
},
{
"id": "5eb912bd.df78bc",
"type": "ui_tab",
"z": "",
"name": "Gauges",
"icon": "dashboard",
"order": 1
}
]
And this one controls a gpio pin as an output with a countdown timer. Set to seconds at the moment as I've only just got it working, easy to change to minutes by changing the "1000" to "60000". The output pin then controls a mosfet which turns on and off a fuel pump which in turn fills the diesel day tank from the main tank.
Code:
[
{
"id": "7aafc8a2.97a328",
"type": "rpi-gpio out",
"z": "f2a52aa4.57c488",
"name": "GPIO 11 - fuel pump",
"pin": "11",
"set": true,
"level": "0",
"out": "out",
"x": 600,
"y": 520,
"wires": []
},
{
"id": "1edad220.4ff64e",
"type": "ui_text",
"z": "f2a52aa4.57c488",
"group": "9b61c17a.b3e3d",
"order": 0,
"width": "3",
"height": "1",
"name": "IsPumpRunning",
"label": "Pump=",
"format": "{{msg.payload}}",
"layout": "row-left",
"x": 580,
"y": 580,
"wires": []
},
{
"id": "d9824fa0.c7e1d",
"type": "debug",
"z": "f2a52aa4.57c488",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 570,
"y": 620,
"wires": []
},
{
"id": "7ac03ac7.e1f314",
"type": "function",
"z": "f2a52aa4.57c488",
"name": "",
"func": "\nvar value = context.get('value') || 1000;\n\nif (msg.topic == \"value\")\n{\n value = msg.payload * 1000;\n context.set('value',value); \n}\n\nelse if (msg.topic == \"start\")\n{\n var timer = setTimeout( myTimer,value);\n context.set('timer',timer); \n var count = value/1000;\n msg.payload=count;\n node.send([null,msg]);\n var countdown = setInterval(myCountdown, 1000);\n context.set('countdown',countdown);\n}\n\nelse if (msg.topic == \"stop\")\n{\n var timerstop = context.get('timer');\n clearTimeout(timerstop);\n var countdownstop = context.get('countdown');\n clearInterval(countdownstop);\n msg.payload = \"0\";\n node.send([msg,{ payload: \"Finished\" }]);\n}\n\n\nfunction myTimer() {\n msg.payload = \"0\";\n node.send([msg,{ payload: \"Finished\" }]);\n var countdownstop = context.get('countdown');\n clearInterval(countdownstop);\n}\n\nfunction myCountdown() {\n count=count-1;\n msg.payload=count; \n node.send([null,msg]);\n}\n",
"outputs": "2",
"noerr": 0,
"x": 370,
"y": 620,
"wires": [
[
"d9824fa0.c7e1d",
"7aafc8a2.97a328",
"1edad220.4ff64e"
],
[
"c6ccc0e8.112c6"
]
]
},
{
"id": "b6e2e216.485f5",
"type": "ui_numeric",
"z": "f2a52aa4.57c488",
"name": "",
"label": "Pump Time",
"group": "9b61c17a.b3e3d",
"order": 0,
"width": "3",
"height": "1",
"passthru": true,
"topic": "value",
"format": "{{value}}",
"min": "1",
"max": "30",
"step": 1,
"x": 190,
"y": 620,
"wires": [
[
"7ac03ac7.e1f314"
]
]
},
{
"id": "9ed2a8a6.1ba348",
"type": "ui_button",
"z": "f2a52aa4.57c488",
"name": "",
"group": "9b61c17a.b3e3d",
"order": 0,
"width": "1",
"height": "1",
"label": "Start",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "1",
"payloadType": "num",
"topic": "start",
"x": 170,
"y": 540,
"wires": [
[
"7ac03ac7.e1f314",
"7aafc8a2.97a328",
"1edad220.4ff64e"
]
]
},
{
"id": "5626da9f.3d51d4",
"type": "ui_button",
"z": "f2a52aa4.57c488",
"name": "",
"group": "9b61c17a.b3e3d",
"order": 0,
"width": "1",
"height": "1",
"label": "Stop",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "",
"payloadType": "str",
"topic": "stop",
"x": 170,
"y": 580,
"wires": [
[
"7ac03ac7.e1f314"
]
]
},
{
"id": "c6ccc0e8.112c6",
"type": "ui_text",
"z": "f2a52aa4.57c488",
"group": "9b61c17a.b3e3d",
"order": 0,
"width": "5",
"height": "1",
"name": "",
"label": "Timer",
"format": "{{msg.payload}} Seconds",
"layout": "row-spread",
"x": 550,
"y": 660,
"wires": []
},
{
"id": "9b61c17a.b3e3d",
"type": "ui_group",
"z": "",
"name": "Pump",
"tab": "5eb912bd.df78bc",
"disp": true,
"width": "11"
},
{
"id": "5eb912bd.df78bc",
"type": "ui_tab",
"z": "",
"name": "Gauges",
"icon": "dashboard",
"order": 1
}
]
And finally this one either turns off the Pi or reboots it, closing down Opencpn first then waiting seconds.
Code:
[
{
"id": "cb4dd236.be89",
"type": "inject",
"z": "f2a52aa4.57c488",
"name": "shutdown!",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": false,
"x": 140,
"y": 1020,
"wires": [
[
"bac39e6f.1de66"
]
]
},
{
"id": "bac39e6f.1de66",
"type": "exec",
"z": "f2a52aa4.57c488",
"command": "killall -s TERM opencpn ",
"addpay": false,
"append": "",
"useSpawn": "",
"timer": "",
"name": "Shutdown Opencpn",
"x": 310,
"y": 980,
"wires": [
[],
[
"f7cda5f8.20b658"
],
[]
]
},
{
"id": "f7cda5f8.20b658",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "delay",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 480,
"y": 980,
"wires": [
[
"5c164727.7e38c8"
]
]
},
{
"id": "a4b1a0dd.d1a0c",
"type": "ui_button",
"z": "f2a52aa4.57c488",
"name": "shutdown",
"group": "5cd0dd6a.d309e4",
"order": 8,
"width": "3",
"height": "1",
"label": "Shutdown!",
"color": "red",
"bgcolor": "",
"icon": "",
"payload": "",
"payloadType": "date",
"topic": "",
"x": 140,
"y": 940,
"wires": [
[
"bac39e6f.1de66"
]
]
},
{
"id": "5c164727.7e38c8",
"type": "exec",
"z": "f2a52aa4.57c488",
"command": "sudo shutdown -h now",
"addpay": true,
"append": "",
"useSpawn": "",
"timer": "",
"name": "Shutdown Pi",
"x": 630,
"y": 980,
"wires": [
[],
[],
[]
]
},
{
"id": "1bd3f953.598ed7",
"type": "inject",
"z": "f2a52aa4.57c488",
"name": "Reboot",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": false,
"x": 130,
"y": 1140,
"wires": [
[
"2e9e7073.f34f2"
]
]
},
{
"id": "2e9e7073.f34f2",
"type": "exec",
"z": "f2a52aa4.57c488",
"command": "killall -s TERM opencpn ",
"addpay": false,
"append": "",
"useSpawn": "",
"timer": "",
"name": "Shutdown Opencpn",
"x": 310,
"y": 1100,
"wires": [
[],
[
"af00df4e.6d5a9"
],
[]
]
},
{
"id": "af00df4e.6d5a9",
"type": "delay",
"z": "f2a52aa4.57c488",
"name": "",
"pauseType": "delay",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 480,
"y": 1100,
"wires": [
[
"5a516ec.7fb8a9"
]
]
},
{
"id": "31ec7f5b.80ef9",
"type": "ui_button",
"z": "f2a52aa4.57c488",
"name": "Reboot",
"group": "5cd0dd6a.d309e4",
"order": 8,
"width": "3",
"height": "1",
"label": "Reboot",
"color": "green",
"bgcolor": "",
"icon": "",
"payload": "",
"payloadType": "date",
"topic": "",
"x": 140,
"y": 1060,
"wires": [
[
"2e9e7073.f34f2"
]
]
},
{
"id": "5a516ec.7fb8a9",
"type": "exec",
"z": "f2a52aa4.57c488",
"command": "sudo reboot",
"addpay": true,
"append": "",
"useSpawn": "",
"timer": "",
"name": "Reboot Pi",
"x": 620,
"y": 1100,
"wires": [
[],
[],
[]
]
},
{
"id": "5cd0dd6a.d309e4",
"type": "ui_group",
"z": "",
"name": "Shutdown",
"tab": "5eb912bd.df78bc",
"disp": true,
"width": "6"
},
{
"id": "5eb912bd.df78bc",
"type": "ui_tab",
"z": "",
"name": "Gauges",
"icon": "dashboard",
"order": 1
}
]
The final page -
Anyone else have some late night work to share