2018-04-23, 06:02 PM
Hi all
I've spent a while putting together a Node Red Engine hours flow.
Its not the prettiest thing but I thought I'd share it here for the benefit of other NR newbies like me who are also going down the same path or wanting to implement other timers.
The counter is perpetually stored on Engine OFF so a RPi shutdown wont loose the count.
That said, I've no idea if the store would survive a NodeRed upgrade so Ive included an Inject Node which can be used to Zero the counter or preload an existing Hour Count (don't forget to make a note of the count before doing an NR or OP upgrade !).
In my setup the counter is triggered by an MQTT message generated by a remote sender when the engine is started. The counter is started/stopped with "1" or "0" so easy to modify the start trigger.
Bye the way, before you say it, no I dont time my engine running time to the second but its useful to have seconds ticking when testing and can easily be removed from the display.
Cheers
I've spent a while putting together a Node Red Engine hours flow.
Its not the prettiest thing but I thought I'd share it here for the benefit of other NR newbies like me who are also going down the same path or wanting to implement other timers.
The counter is perpetually stored on Engine OFF so a RPi shutdown wont loose the count.
That said, I've no idea if the store would survive a NodeRed upgrade so Ive included an Inject Node which can be used to Zero the counter or preload an existing Hour Count (don't forget to make a note of the count before doing an NR or OP upgrade !).
In my setup the counter is triggered by an MQTT message generated by a remote sender when the engine is started. The counter is started/stopped with "1" or "0" so easy to modify the start trigger.
Bye the way, before you say it, no I dont time my engine running time to the second but its useful to have seconds ticking when testing and can easily be removed from the display.
Cheers
Code:
[
{
"id": "3726e20.932761e",
"type": "ui_text",
"z": "2b47cf3c.1f345",
"group": "2381998f.63b6d6",
"order": 7,
"width": 0,
"height": 0,
"name": "",
"label": "Engine Hrs (Total)",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 670,
"y": 540,
"wires": []
},
{
"id": "cbaed108.85542",
"type": "inject",
"z": "2b47cf3c.1f345",
"name": "Ticker",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "1",
"crontab": "",
"once": true,
"x": 160,
"y": 420,
"wires": [
[
"c3696e78.931fe",
"be88c4f1.d85998",
"f4ebe418.011268"
]
]
},
{
"id": "c3696e78.931fe",
"type": "function",
"z": "2b47cf3c.1f345",
"name": "Send Tick if Eng ON",
"func": "var engineon = global.get(\"engineon\");\nif (engineon === 0){\n msg.reset = true;\n}else if (engineon === 1){\n msg.payload = \"tick\";\n return msg;\n}",
"outputs": 1,
"noerr": 0,
"x": 380,
"y": 420,
"wires": [
[
"f18b1e29.57f6b"
]
]
},
{
"id": "5b511c3d.d31514",
"type": "change",
"z": "2b47cf3c.1f345",
"name": "",
"rules": [
{
"t": "set",
"p": "engineon",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 410,
"y": 260,
"wires": [
[]
]
},
{
"id": "e3808594.7ac418",
"type": "key-value-write",
"z": "2b47cf3c.1f345",
"store": "964eb4a3.b5f7d8",
"action": "set",
"key": "",
"keyvalue": "",
"name": "Write to store",
"x": 970,
"y": 660,
"wires": [
[
"33bd62f2.6fc79e",
"92d95cd.b9113a"
]
]
},
{
"id": "ac105340.cb99c",
"type": "key-value-read",
"z": "2b47cf3c.1f345",
"store": "964eb4a3.b5f7d8",
"key": "",
"name": "Read Store",
"x": 630,
"y": 280,
"wires": [
[
"8f2e3d11.a5be9",
"ff81fc58.10e3c"
]
]
},
{
"id": "8f2e3d11.a5be9",
"type": "change",
"z": "2b47cf3c.1f345",
"name": "",
"rules": [
{
"t": "set",
"p": "storedcount",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1220,
"y": 280,
"wires": [
[]
]
},
{
"id": "124c5f9c.d6611",
"type": "change",
"z": "2b47cf3c.1f345",
"name": "",
"rules": [
{
"t": "set",
"p": "tripcount",
"pt": "global",
"to": "count",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1210,
"y": 340,
"wires": [
[]
]
},
{
"id": "9c2759d5.b48758",
"type": "function",
"z": "2b47cf3c.1f345",
"name": "Add Trip to Stored",
"func": "var storedcount = global.get(\"storedcount\");\nvar tripcount = global.get(\"tripcount\");\nmsg.payload = storedcount + tripcount;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 510,
"y": 360,
"wires": [
[
"5e63e3aa.5962ec"
]
]
},
{
"id": "bd85cdb9.dd59f",
"type": "inject",
"z": "2b47cf3c.1f345",
"name": "Reset Counters",
"topic": "",
"payload": "0",
"payloadType": "num",
"repeat": "",
"crontab": "",
"once": false,
"x": 140,
"y": 660,
"wires": [
[
"e3808594.7ac418"
]
]
},
{
"id": "a88657f9.7eceb8",
"type": "inject",
"z": "2b47cf3c.1f345",
"name": "Initialise Counters",
"topic": "",
"payload": "1",
"payloadType": "num",
"repeat": "",
"crontab": "",
"once": true,
"x": 130,
"y": 200,
"wires": [
[
"57ff78a4.fb80f8"
]
]
},
{
"id": "230fa1c0.55187e",
"type": "mqtt in",
"z": "2b47cf3c.1f345",
"name": "Eng ON",
"topic": "EngineOn1Switch",
"qos": "2",
"broker": "b1d0c3fc.a6fad",
"x": 70,
"y": 300,
"wires": [
[
"a80a6965.7e2a58"
]
]
},
{
"id": "a80a6965.7e2a58",
"type": "function",
"z": "2b47cf3c.1f345",
"name": "Strg to Nbr",
"func": "msg.payload = Number(msg.payload);\nmsg.topic = \"\";\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 210,
"y": 300,
"wires": [
[
"5b511c3d.d31514",
"f29f885f.276d88"
]
]
},
{
"id": "f29f885f.276d88",
"type": "switch",
"z": "2b47cf3c.1f345",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "num"
},
{
"t": "eq",
"v": "0",
"vt": "num"
}
],
"checkall": "true",
"outputs": 2,
"x": 370,
"y": 300,
"wires": [
[
"ac105340.cb99c"
],
[
"9c2759d5.b48758"
]
]
},
{
"id": "f18b1e29.57f6b",
"type": "counter",
"z": "2b47cf3c.1f345",
"name": "Trip Counter",
"init": "0",
"step": "1",
"lower": null,
"upper": null,
"mode": "increment",
"outputs": "1",
"x": 1010,
"y": 420,
"wires": [
[
"124c5f9c.d6611"
]
]
},
{
"id": "e001a5c0.1b8be8",
"type": "ui_text",
"z": "2b47cf3c.1f345",
"group": "2381998f.63b6d6",
"order": 6,
"width": 0,
"height": 0,
"name": "",
"label": "Engine Hrs (Trip)",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 670,
"y": 480,
"wires": []
},
{
"id": "5e63e3aa.5962ec",
"type": "key-value-write",
"z": "2b47cf3c.1f345",
"store": "964eb4a3.b5f7d8",
"action": "set",
"key": "",
"keyvalue": "",
"name": "Write to store",
"x": 690,
"y": 360,
"wires": [
[]
]
},
{
"id": "ff81fc58.10e3c",
"type": "function",
"z": "2b47cf3c.1f345",
"name": "Reset Trip",
"func": "msg.reset = true;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 890,
"y": 320,
"wires": [
[
"f18b1e29.57f6b"
]
]
},
{
"id": "33bd62f2.6fc79e",
"type": "change",
"z": "2b47cf3c.1f345",
"name": "",
"rules": [
{
"t": "set",
"p": "storedcount",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1220,
"y": 700,
"wires": [
[]
]
},
{
"id": "92d95cd.b9113a",
"type": "change",
"z": "2b47cf3c.1f345",
"name": "",
"rules": [
{
"t": "set",
"p": "tripcount",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1210,
"y": 660,
"wires": [
[]
]
},
{
"id": "57ff78a4.fb80f8",
"type": "delay",
"z": "2b47cf3c.1f345",
"name": "",
"pauseType": "delay",
"timeout": "1",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 440,
"y": 200,
"wires": [
[
"ac105340.cb99c"
]
]
},
{
"id": "be88c4f1.d85998",
"type": "function",
"z": "2b47cf3c.1f345",
"name": "Prep Trip Display",
"func": "var time = global.get(\"tripcount\");\nvar hours = Math.floor(time / 3600);\ntime = time - hours * 3600;\nvar minutes = Math.floor(time / 60);\nvar seconds = time % 60;\nmsg.payload = hours + \"hr \" + minutes + \"m \" + seconds + \"s \";\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 370,
"y": 480,
"wires": [
[
"e001a5c0.1b8be8"
]
]
},
{
"id": "f4ebe418.011268",
"type": "function",
"z": "2b47cf3c.1f345",
"name": "Prep Total Display",
"func": "var time = global.get(\"storedcount\") + global.get(\"tripcount\");\nvar hours = Math.floor(time / 3600);\ntime = time - hours * 3600;\nvar minutes = Math.floor(time / 60);\nvar seconds = time % 60;\nmsg.payload = hours + \"hr \" + minutes + \"m \" + seconds + \"s \";\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 370,
"y": 540,
"wires": [
[
"3726e20.932761e"
]
]
},
{
"id": "2381998f.63b6d6",
"type": "ui_group",
"z": "",
"name": "Col 1",
"tab": "dae185ad.0bda98",
"order": 1,
"disp": false,
"width": "4"
},
{
"id": "964eb4a3.b5f7d8",
"type": "key-value-store",
"z": "",
"filepath": "store.json",
"namespace": "",
"name": "Counter_store"
},
{
"id": "b1d0c3fc.a6fad",
"type": "mqtt-broker",
"z": "",
"broker": "10.10.10.1",
"port": "1883",
"clientid": "",
"usetls": false,
"compatmode": true,
"keepalive": "60",
"cleansession": true,
"willTopic": "",
"willQos": "0",
"willPayload": "",
"birthTopic": "",
"birthQos": "0",
"birthPayload": ""
},
{
"id": "dae185ad.0bda98",
"type": "ui_tab",
"z": "",
"name": "Rpi Performance",
"icon": "dashboard"
}
]