Cumulative running time

#1

I am looking for suggestions on a node, or way to capture cumulative running time of equipment. For example: a machine runs for 2 hrs, then is down for 20 minutes, then starts again for 3 hrs, so the cumulative time is currently 5 hrs. I would also like to access this value at anytime say 5 hrs 4 minutes, 5 minutes, 6 minutes etc...

thanks

0 Likes

Pausing timer in mytimeout
#2

How are you capturing the running time i.e. is it initiated from a flow in your code i.e. Start Stop - or is it an external event you are being notified of (through MQTT or some other mechanism).

I am not aware of a node as i went looking for one a while ago.

How long do you want to keep the info and does it have to persist across Node-red restarts, reloads etc ?

Is it only a single device you wish to monitor ?

Craig

0 Likes

#3

I would be initiating the start and stops based on the value of a single input.....if "true" start keeping track of time and it "false" stop the tally and just hold the value.

It would not have to store it for restarts or reloads.

Yes, a single device at a time.

0 Likes

#4

This can be done using a state machine node like dsm.
I'd upload a flow if you want to try.

0 Likes

#5

Please upload something I could try.

0 Likes

#6

This is a basic example but it can be modified / improved:

[{"id":"5b83329.fe12dcc","type":"inject","z":"895bbff8.0e6c4","name":"on","topic":"on","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":3420,"wires":[["cb31d3c.377153"]]},{"id":"2a77b639.990e2a","type":"inject","z":"895bbff8.0e6c4","name":"off","topic":"off","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":3460,"wires":[["cb31d3c.377153"]]},{"id":"9770ea8e.ef7358","type":"inject","z":"895bbff8.0e6c4","name":"reset","topic":"reset","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":3500,"wires":[["cb31d3c.377153"]]},{"id":"cb31d3c.377153","type":"dsm","z":"895bbff8.0e6c4","name":"operating time","sm_config":"{\n    \"currentState\": \"stopped\",\n    \"states\": {\n        \"stopped\": {\n            \"on\": \"started\"\n        },\n        \"started\": {\n            \"inc\": \"counting\",\n            \"off\": \"stopped\"\n        },\n        \"counting\": {\n            \"inc\": \"counting\",\n            \"off\": \"stopped\"\n        }\n    },\n    \"data\": {\n        \"time\": 0,\n        \"step\": 1,\n        \"prev_time\": null\n    },\n    \"methods\": {\n        \"on\": [\n            \"if (sm.currentState === 'started') {\",\n            \"   sm.data.prev_time = Date.now();\",\n            \"   node.send(msg);\",\n            \"   resume('inc', msg);\",\n            \"}\"\n        ],\n        \"inc\": [\n            \"timeout.interval = setTimeout(function() {\",\n            \"   var now = Date.now();\",\n            \"   sm.data.time += now - sm.data.prev_time;\",\n            \"   sm.data.prev_time = now;\",\n            \"   resume('inc', msg);\",\n            \"}, sm.data.step*1000);\",\n            \"output = false;\"\n        ],\n        \"off\": [\n            \"clearTimeout(timeout.interval);\"\n        ],\n        \"reset\": [\n            \"sm.data.time = 0;\"\n        ],\n        \"onTransition\": [\n            \"sm.text = 'time '+ Math.round(sm.data.time / 1000);\"\n        ],\n        \"status\": {\n            \"fill\": {\n                \"get\": \"sm.currentState === 'counting' ? 'green' : 'grey';\"\n            },\n            \"shape\": \"dot\",\n            \"text\": {\n                \"get\": \"sm.text;\"\n            }\n        }\n    }\n}","x":330,"y":3460,"wires":[["9d1fae36.a0661"]]},{"id":"9d1fae36.a0661","type":"debug","z":"895bbff8.0e6c4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":3460,"wires":[]}]

You need to install the latest dsm version.

0 Likes

#7

Wow that is WAAY Cool - very nice !

Craig

0 Likes

#8

That is a neat solution... is there a way to initialize some data when the node is deployed, before any state transition methods are ever executed? I was trying to add a total elapsed time counter, but need to set sm.data.init_time = Date.now(); and couldn't seem to find a place to put that.

0 Likes

#9

Good question! I'll put it on my todo list.
A workaround:

add init into the data and execute the statement once in the onBeforeTransition method:

    "data": {
        "init": true,
        "init_time": null,
        "time": 0,
        "step": 1,
        "prev_time": null
    },
    "methods": {
        "onBeforeTransition": [
            "if (sm.data.init) {",
            "   sm.data.init_time = Date.now();",
            "   sm.data.init = false;",
            "}"
        ],
        "on": [
       ...
0 Likes

#10

Excellent. Thank you for sharing. That should work out nicely.

0 Likes

#11

I am trying to utilize one of the dsm examples and modify one to fit what I am trying to accomplish. Looking at the CO2 example, it has "value" arriving in as msg.payload.value. I am trying to use a function Node and set the number that is coming in to the function node as msg.payload to msg.payload.value so that is looks the same to the dsm node. I was trying something like:

if (msg.payload > 5)
{ msg.payload.value = msg.payload};
return msg;

However, I still only get the value to be in msg.payload

Can you tell me where I am going wrong?

My ultimate goal is to read in a value (Total weight) divide it by the elapsed time determined by the dsm, and return the answer every second or so.

0 Likes

#12

Can you post your flow here or send me a direct message (click on my user icon and click 'message')

I'll have a look.

Note: how to share code or flow json

0 Likes