How to calculate machine running time

Hi,

I need to calculate my machine running time % and it needs to be updated every second.
(Machine running time = Normal Running Time/Total Working Time)

I have tried using this flow: https://github.com/cflurin/node-red-contrib-dsm/wiki/Operating-time
However I am facing some issues as I have posted on this topic: Operating time node issue.

So i was hoping of another method using the fucntion node.

So basically, when I inject "start" the payload will start from 0 and keep increasing by 1, and this signal must be sent out very second.

Then when I inject "stop" it must send the current payload value out every second also.

Then when I click reset, it will send out 0 at every second again.

But if I inject "stop" then "start", it should keep increasing the value of the payload by one again.

Basically, a timer for the machine running time. Like a stopwatch function.

Any ideas?

Use a global or flow variable that will hold the current state of your machine AND the increment: 0 if the machine is stopped, 1 if the machine is working. Use another global/flow variable for your counter.

Create a flow with

  1. An inject node that will trigger every second
  2. A function node that will get the value of the increment (global/flow variable) and the counter (global/flow variable). Add those two values, store the result in counter (global/flow variable). Send the result as msg.payload

Finally create three other flows, each beginning with an inject node, followed by a Change node. The inject nodes are your START/STOP/RESET nodes. Modify the Change nodes so that it modifies the increment variable or the counter variable accordingly.

A very quick lash-up. I'm sure it can be simplified. I'll leave it to you to insert the 'maths' you require.

ScreenShot049

[{"id":"eb33aa15.9c8518","type":"inject","z":"8a9f04ff.2bbeb","name":"Start","topic":"","payload":"start","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":200,"wires":[["8d16e77f.480b3"]]},{"id":"589fdea6.104618","type":"inject","z":"8a9f04ff.2bbeb","name":"Stop","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":260,"wires":[["8d16e77f.480b3"]]},{"id":"e56cbc00.56df5","type":"inject","z":"8a9f04ff.2bbeb","name":"Reset","topic":"","payload":"reset","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":190,"y":100,"wires":[["195356b.fb27129"]]},{"id":"195356b.fb27129","type":"function","z":"8a9f04ff.2bbeb","name":"","func":"flow.set(\"counter\",0);\nflow.set(\"status\",\"stop\");","outputs":0,"noerr":0,"x":390,"y":100,"wires":[]},{"id":"8d16e77f.480b3","type":"function","z":"8a9f04ff.2bbeb","name":"","func":"if (msg.payload == \"start\") {\n    flow.set(\"status\",\"start\");\n}\nelse if (msg.payload == \"stop\") {\n    flow.set(\"status\",\"stop\");\n}\n","outputs":0,"noerr":0,"x":390,"y":220,"wires":[]},{"id":"8f2c92c5.7b4c18","type":"inject","z":"8a9f04ff.2bbeb","name":"","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":360,"wires":[["fa23b6c6.f3b2a8"]]},{"id":"fa23b6c6.f3b2a8","type":"function","z":"8a9f04ff.2bbeb","name":"","func":"var status = flow.get(\"status\") || \"stop\";\nvar count  = flow.get(\"counter\") ||0;\n\nif (status == \"start\"){\n    msg.payload = count;\n    count = count + 1;\n    flow.set(\"counter\",count);\n    return msg;\n}\nelse if (status == \"stop\") {\n    msg.payload = count;\n    return msg;\n}\n","outputs":1,"noerr":0,"x":390,"y":360,"wires":[["d548edbb.889458"]]},{"id":"d548edbb.889458","type":"debug","z":"8a9f04ff.2bbeb","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":360,"wires":[]}]

Thanks guys, but i just solved it already. Instead of using a function node, I created this flow. Serves the same purpose.

Feel free to ask if you wanna know more. :slight_smile:

[{"id":"57244012.e6aee","type":"tab","label":"Flow 5","disabled":false,"info":""},{"id":"13d3c059.a4c13","type":"gate","z":"57244012.e6aee","name":"gate","controlTopic":"control","defaultState":"closed","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":244.01733016967773,"y":197.34387397766113,"wires":[["f3061e4a.a1dc2"]]},{"id":"d562c744.2b3838","type":"inject","z":"57244012.e6aee","name":"input","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":102.01742172241211,"y":198.34386706352234,"wires":[["13d3c059.a4c13"]]},{"id":"5d30a737.a655d8","type":"inject","z":"57244012.e6aee","name":"Start","topic":"control","payload":"open","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":98.0173511505127,"y":238.3437786102295,"wires":[["13d3c059.a4c13","fed1a4b1.a71798"]]},{"id":"162bad3d.dce733","type":"inject","z":"57244012.e6aee","name":"Stop","topic":"control","payload":"close","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":101.01739501953125,"y":277.3438415527344,"wires":[["13d3c059.a4c13","b25c02a3.1a24"]]},{"id":"e9f8d050.f1b6f","type":"debug","z":"57244012.e6aee","name":"Current Payload","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":560.0173263549805,"y":100.3438868522644,"wires":[]},{"id":"f3061e4a.a1dc2","type":"counter","z":"57244012.e6aee","name":"","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":2,"x":395.01721572875977,"y":198.01061248779297,"wires":[["c59c6f83.80961","3b2aff24.cbc9d"],[]]},{"id":"8f64e5f2.d0b918","type":"function","z":"57244012.e6aee","name":"Reset Counter","func":"msg.reset=msg.payload\nreturn msg;","outputs":1,"noerr":0,"x":300.00709533691406,"y":284.64606380462646,"wires":[["f3061e4a.a1dc2"]]},{"id":"4df0a2f5.90388c","type":"inject","z":"57244012.e6aee","name":"Reset","topic":"","payload":"0","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":98.5833568572998,"y":316.0834059715271,"wires":[["8f64e5f2.d0b918"]]},{"id":"fed1a4b1.a71798","type":"function","z":"57244012.e6aee","name":"Start","func":"msg.payload=\"close\"\nmsg.topic=\"control\"\nreturn msg;","outputs":1,"noerr":0,"x":266.46529388427734,"y":323.36769104003906,"wires":[["2c1d6ac1.f5b806"]]},{"id":"b25c02a3.1a24","type":"function","z":"57244012.e6aee","name":"STOP","func":"msg.payload=\"open\"\nmsg.topic=\"control\"\nreturn msg;","outputs":1,"noerr":0,"x":262.4652290344238,"y":360.3676452636719,"wires":[["2c1d6ac1.f5b806"]]},{"id":"2c1d6ac1.f5b806","type":"gate","z":"57244012.e6aee","name":"gate","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":629.0173416137695,"y":320.12154960632324,"wires":[["4d077d69.45e204"]]},{"id":"c59c6f83.80961","type":"trigger","z":"57244012.e6aee","op1":"","op2":"","op1type":"pay","op2type":"nul","duration":"-1","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":515.0173492431641,"y":260.12152671813965,"wires":[["2c1d6ac1.f5b806"]]},{"id":"4d077d69.45e204","type":"counter","z":"57244012.e6aee","name":"","init":"0","step":"1","lower":"","upper":"","mode":"increment","outputs":2,"x":723.0172348022461,"y":262.1215181350708,"wires":[["9b5929b.a338dd8"],["def262ef.f2b4"]]},{"id":"9b5929b.a338dd8","type":"debug","z":"57244012.e6aee","name":"To Proof the current payload is sent every second after STOP/RESET","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":992.0172805786133,"y":110.1215991973877,"wires":[]},{"id":"3b2aff24.cbc9d","type":"function","z":"57244012.e6aee","name":"[s] to [hh:mm:ss]","func":"// Message from preceeding node is in seconds - should be less than 24 hours (86400 seconds).\nvar time = (new Date(msg.payload * 1000)).toUTCString().match(/(\\d\\d:\\d\\d:\\d\\d)/)[0];\n// Pass on the string to the next node, what ever that may be. (groov Data Store for example).\nmsg.payload = time;\nreturn msg;","outputs":1,"noerr":0,"x":573.0173110961914,"y":195.12156295776367,"wires":[["e9f8d050.f1b6f","a97cb65e.07def8"]]},{"id":"def262ef.f2b4","type":"function","z":"57244012.e6aee","name":"[s] to [hh:mm:ss]","func":"// Message from preceeding node is in seconds - should be less than 24 hours (86400 seconds).\nvar time = (new Date(msg.payload * 1000)).toUTCString().match(/(\\d\\d:\\d\\d:\\d\\d)/)[0];\n// Pass on the string to the next node, what ever that may be. (groov Data Store for example).\nmsg.payload = time;\nreturn msg;","outputs":1,"noerr":0,"x":882.0172805786133,"y":337.1215419769287,"wires":[["a97cb65e.07def8"]]},{"id":"a97cb65e.07def8","type":"debug","z":"57244012.e6aee","name":"MACHINE RUNNING TIME","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","x":1000.0173530578613,"y":227.0104112625122,"wires":[]}]

Wow this is so much simpler than mine. Worked like magic. HAHA if only I knew coding. Thanks a lot though.

Just had to have a go at simplifying the flow and the JavaScript.
I've also renamed 'start' to 'run' as the name seemed to make more sense (to me).

ScreenShot050

[{"id":"eb33aa15.9c8518","type":"inject","z":"8a9f04ff.2bbeb","name":"Run","topic":"","payload":"run","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":200,"wires":[["8d16e77f.480b3"]]},{"id":"589fdea6.104618","type":"inject","z":"8a9f04ff.2bbeb","name":"Stop","topic":"","payload":"stop","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":260,"wires":[["8d16e77f.480b3"]]},{"id":"e56cbc00.56df5","type":"inject","z":"8a9f04ff.2bbeb","name":"Reset","topic":"","payload":"reset","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":190,"y":100,"wires":[["8d16e77f.480b3"]]},{"id":"8d16e77f.480b3","type":"function","z":"8a9f04ff.2bbeb","name":"","func":"if (msg.payload == \"reset\") {\n    flow.set(\"counter\",0);\n}\n\nflow.set(\"status\",msg.payload);","outputs":0,"noerr":0,"x":390,"y":200,"wires":[]},{"id":"8f2c92c5.7b4c18","type":"inject","z":"8a9f04ff.2bbeb","name":"","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":true,"onceDelay":"0.5","x":190,"y":360,"wires":[["fa23b6c6.f3b2a8"]]},{"id":"fa23b6c6.f3b2a8","type":"function","z":"8a9f04ff.2bbeb","name":"","func":"var status = flow.get(\"status\")  || \"stop\";\nvar count  = flow.get(\"counter\") || 0;\n\nif (status == \"run\"){\n    count = count + 1;\n}\n\nflow.set(\"counter\",count);\nmsg.payload = count;\nreturn msg;\n","outputs":1,"noerr":0,"x":390,"y":360,"wires":[["d548edbb.889458"]]},{"id":"d548edbb.889458","type":"debug","z":"8a9f04ff.2bbeb","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":360,"wires":[]},{"id":"5e75f97b.246908","type":"comment","z":"8a9f04ff.2bbeb","name":"Simplified version - Happy Christmas 2019","info":"","x":480,"y":100,"wires":[]}]
2 Likes

I have the probably same thing, I have one LED connected with RPi and I wanna calculate running time of LED. While I have dashboard switch to turn ON/OFF LED.

This kind of counter is what I am looking for to count the total runtime of specific components of my machine...but if I redeploy the flow it starts over at 0. Is there a way to have it pick up counting where it left off? Or pull from an InfluxDB instance and add to that? Also am looking for a "master time" counter which just counts the total time my Node-Red program is on.

Please don't ask the same question in multiple places, it will just get confusing. I am closing this thread as it is 7 months old.