# How can I count the running hours of a machine (PLC, S7)

**URL:** <https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915>\
**Category:** Industrial\
**Created:** [28 April 2022 09:07 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915 "2022-04-28T09:07:44Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [28 April 2022 09:07 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/1 "2022-04-28T09:07:44Z")

</div>

has anyone developed a flow that can count the running hours of a machine using a bit coming from Siemens PLC and emailing the hours in an excel or CSV file on specific time

---

<div class="post-metadata">

**Author:** ![nico25](https://avatars.discourse-cdn.com/v4/letter/n/d2c977/32.png) [@nico25](https://discourse.nodered.org/u/nico25)\
**Post date:** [28 April 2022 09:58 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/2 "2022-04-28T09:58:09Z")

</div>

hi alee,

I would recommend to calculate the running hours on the PLC and provide the value to Nodered afterwards.  
Otherwise you are risking to lose information when connection is disturbed or nodered crashes.

I created a flow to collect the running hours from our machines and mail them to people here every monday at 08:00. Let me know if you get stuck.

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [28 April 2022 10:18 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/3 "2022-04-28T10:18:12Z")

</div>

Hi nico25,

thanks a lot for the suggestion. I have a PC onboard the machine on which I can install Node-Red. PLC is connected with the PC over ethernet so the chances of losing connections with PLC are very low. additionally, if i create an hour meter on PLC the there are two problems;

1. the program of the PLC can be updated mistakenly and we can lose all the information.
2. PLC clock does not measure the time accurately over a longer duration of time as it does not have a real-time clock of its own.  
I prefer to just get 1 bit as a trigger for the timer from the PLC and the rest done in PC and on node-red.  
I was having a problem connecting Siemens PLC from node-red. if you have any working flow please share.

---

<div class="post-metadata">

**Author:** ![StrongTown](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@StrongTown](https://discourse.nodered.org/u/StrongTown)\
**Post date:** [28 April 2022 21:22 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/4 "2022-04-28T21:22:05Z")

</div>

`alee`

Perhaps this will work for you. You can convert the ms to whatever time format you desire for the CSV.

```auto
// NOTE: The time calculations herein are in milliseconds

var now = new Date().getTime();
var run_indicator = msg.payload;
// Assuming msg.payload input is of type number and 1 means "ON" and 0 means "OFF"

if (typeof (context.last_time_check) === 'undefined') context.last_time_check = 0;
if (typeof (context.run_time) === 'undefined') context.run_time = 0;
if (typeof (context.run_state) === 'undefined') context.run_state = "off";

// This code operates when machine first comes on
if (run_indicator === 1 && context.run_state === "off")
{ context.run_state = "on"; // machine is on, lets remember this
    context.last_time_check = now;
    context.run_time = 0;
}    

// This code operates when machine continues to indicate it's on
if (run_indicator === 1 && context.run_state === "on") context.run_time = context.run_time + (now - context.last_time_check);

// Assuming msg.payload input is of type number and = 0 (bit) to indicate "OFF"
if (run_indicator === 0) context.run_state = "off"; // machine is off, lets remember this

node.warn("State: " + context.run_state + " Run time: " + context.run_time)
context.last_time_check = now;
return;

```

---

<div class="post-metadata">

**Author:** ![nico25](https://avatars.discourse-cdn.com/v4/letter/n/d2c977/32.png) [@nico25](https://discourse.nodered.org/u/nico25)\
**Post date:** [29 April 2022 05:59 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/5 "2022-04-29T05:59:56Z")

</div>

Maybe we should start with your connection problem. what kind of plc do you have and how do you want to connect?

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [29 April 2022 06:35 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/6 "2022-04-29T06:35:45Z")

</div>

I have s7-400 on old equipment and s7-300 on new equipment connected to PC using Industrial Ethernet

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [29 April 2022 06:37 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/7 "2022-04-29T06:37:54Z")

</div>

thanks a lot. does it restart from 0 every time the system restarts?

---

<div class="post-metadata">

**Author:** ![nico25](https://avatars.discourse-cdn.com/v4/letter/n/d2c977/32.png) [@nico25](https://discourse.nodered.org/u/nico25)\
**Post date:** [29 April 2022 07:15 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/8 "2022-04-29T07:15:38Z")

</div>

That´s one of my connection:

 ![grafik](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/4/240be4cd2a8f72a7cff78ab4defdeb61032c3682.png)  
DBs must not be optimized, otherwise it won´t work

---

<div class="post-metadata">

**Author:** ![StrongTown](https://avatars.discourse-cdn.com/v4/letter/s/4bbf92/32.png) [@StrongTown](https://discourse.nodered.org/u/StrongTown)\
**Post date:** [29 April 2022 11:22 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/9 "2022-04-29T11:22:11Z")

</div>

Yes it does.  
 ![Runtime Clock](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/d/2da955e0bd1a51428c7ac2ad9f32154f1bd3a839.gif)

Here is the code:

```auto

[{"id":"7357d72d8f169424","type":"function","z":"f64d7463a1b093c1","name":"Runtime \\n Clock","func":"// NOTE: The time calculations herein are in milleseconds\n\nvar now = new Date().getTime();\nvar run_indicator = msg.payload;\n\nif (typeof (context.last_time_check) === 'undefined') context.last_time_check = 0;\nif (typeof (context.run_time) === 'undefined') context.run_time = 0;\nif (typeof (context.run_state) === 'undefined') context.run_state = \"off\";\n\n// Assuming msg.payload input is of type number and 1 means \"ON\" and 0 means \"OFF\"\n\n// This code operates when machine first comes on\nif (run_indicator === 1 && context.run_state === \"off\")\n{ context.run_state = \"on\"; // machine is on, lets remember this\n context.last_time_check = now;\n context.run_time = 0;\n} \n\n// This code operates when machine continues to indicate it's on\nif ((run_indicator === 1 || msg.payload === \"clock\") && context.run_state === \"on\") context.run_time = context.run_time + (now - context.last_time_check);\n\n// Assuming msg.payload input is of type number and = 0 (bit) to indicate \"OFF\"\nif (run_indicator === 0) context.run_state = \"off\"; // machine is off, lets remember this\n\n//node.warn(\"State: \" + context.run_state + \" Run time: \" + context.run_time)\nif (context.run_state === \"on\") node.status({ fill: \"green\", shape: \"dot\", text: \"ON \" + context.run_time })\nelse node.status({ fill: \"red\", shape: \"ring\", text: \"OFF \" + context.run_time });\n\ncontext.last_time_check = now;\nmsg = { payload: context.run_time};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":230,"wires":[["8ecf9c23a7e0bc2f"]]},{"id":"2d7c05d5ba560ef9","type":"inject","z":"f64d7463a1b093c1","name":"Running (1)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":430,"y":205,"wires":[["7357d72d8f169424"]]},{"id":"69b428dc9d65eeb2","type":"inject","z":"f64d7463a1b093c1","name":"Stopped (0)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":430,"y":250,"wires":[["7357d72d8f169424"]]},{"id":"b97d859f180e66bf","type":"inject","z":"f64d7463a1b093c1","name":"Clock","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"clock","payloadType":"str","x":435,"y":295,"wires":[["7357d72d8f169424"]]},{"id":"8ecf9c23a7e0bc2f","type":"debug","z":"f64d7463a1b093c1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":755,"y":230,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [2 May 2022 08:31 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/10 "2022-05-02T08:31:01Z")

</div>

it's working great. but how to continue the counter from the last stopped value? I have used hourglass it works perfectly. the only problem that I have with it is that I want the time from the hourglass in hours and it shows in dd:hh:mm:ss:ms additionally I am want to save the hours in a CSV or Excel file

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [2 May 2022 08:32 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/11 "2022-05-02T08:32:10Z")

</div>

@nico25 thanks a lot I have tried this but i am getting the fault message "no connection"

---

<div class="post-metadata">

**Author:** ![nico25](https://avatars.discourse-cdn.com/v4/letter/n/d2c977/32.png) [@nico25](https://discourse.nodered.org/u/nico25)\
**Post date:** [2 May 2022 09:20 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/12 "2022-05-02T09:20:52Z")

</div>

Maybe you could try TSAP. Here is a sample config:

![grafik](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/3/9316245ad333ecef5966716db68d726813a05809.png)

---

<div class="post-metadata">

**Author:** ![jupiter8](https://avatars.discourse-cdn.com/v4/letter/j/34f0e0/32.png) [@jupiter8](https://discourse.nodered.org/u/jupiter8)\
**Post date:** [2 May 2022 18:36 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/13 "2022-05-02T18:36:54Z")

</div>

I do it with the DSM node: [node-red-contrib-dsm (node) - Node-RED](https://flows.nodered.org/node/node-red-contrib-dsm)

Here's the flow. Just inject the setup hour meter and you can reset to zero by injecting reset

```auto
[{"id":"ea94dabbdf5b8487","type":"inject","z":"780bf582.9ae65c","name":"reset counter","props":[{"p":"payload","v":"reset","vt":"str"},{"p":"topic","v":"reset","vt":"string"}],"repeat":"","crontab":"00 00 * * *","once":false,"onceDelay":0.1,"topic":"reset","payload":"reset","payloadType":"str","x":580,"y":540,"wires":[["787eb536f8f64e14"]]},{"id":"c97ba88edc50d383","type":"inject","z":"780bf582.9ae65c","name":"setup hour meter","repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"set","payload":"{\"triggerInput\":\"payload\",\"currentState\":\"stopped\",\"states\":{\"stopped\":{\"on\":\"started\"},\"started\":{\"inc\":\"counting\",\"off\":\"stopped\"},\"counting\":{\"inc\":\"counting\",\"off\":\"stopped\"}},\"data\":{\"prev_time\":null,\"time\":0,\"seconds\":0,\"interval\":5},\"methods\":{\"init\":[\"sm.calc_time = function () {\",\" var now = Date.now();\",\" sm.data.time += now - sm.data.prev_time;\",\" sm.data.prev_time = now;\",\" sm.data.seconds = Math.round(sm.data.time / 1000);\",\"};\",\"sm.sec2hhmmss = function(t) {\",\" var min = t/60;\",\" var t_h = pad(parseInt(min / 60));\",\" var t_m = pad(parseInt(min % 60));\",\" var t_s = pad(Math.round(t % 60));\",\" return t_h+':'+t_m+':'+t_s;\",\"};\"],\"on\":[\"if (sm.currentState === 'started') {\",\" sm.data.prev_time = Date.now();\",\" resume('inc', msg);\",\"}\",\"output = false;\"],\"inc\":[\"timeout.interval = setTimeout(function() {\",\" sm.calc_time();\",\" msg.data = sm.data;\",\" /* msg.payload = sm.sec2hhmmss(sm.data.seconds);\",\" node.send(msg); */\",\" resume('inc', msg);\",\"}, sm.data.interval*1000);\",\"output = false;\"],\"off\":[\"clearTimeout(timeout.interval);\",\"sm.calc_time();\",\"msg.payload = sm.sec2hhmmss(sm.data.seconds);\"],\"reset\":[\"sm.data.time = 0;\",\"sm.data.seconds = 0;\",\"node.send(msg);\"],\"status\":{\"fill\":{\"get\":\"sm.currentState === 'counting' ? 'green' : 'grey';\"},\"shape\":\"dot\",\"text\":{\"get\":\"'time '+ sm.sec2hhmmss(sm.data.seconds);\"}}}}","payloadType":"json","x":580,"y":700,"wires":[["787eb536f8f64e14"]]},{"id":"4917bbfdc0cfa85c","type":"inject","z":"780bf582.9ae65c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":590,"y":600,"wires":[["787eb536f8f64e14"]]},{"id":"1156e7ef8bfa46ae","type":"inject","z":"780bf582.9ae65c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":590,"y":640,"wires":[["787eb536f8f64e14"]]},{"id":"787eb536f8f64e14","type":"dsm","z":"780bf582.9ae65c","name":"Total","sm_config":"","x":740,"y":620,"wires":[["078cc63621cba533"]]},{"id":"078cc63621cba533","type":"debug","z":"780bf582.9ae65c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":930,"y":600,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [3 May 2022 07:35 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/14 "2022-05-03T07:35:05Z")

</div>

@jupiter8 thanks alot.  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/e/fea44731714e05beacd3c7ca491a198408700714.png)

please see the image i am having this DSM undefined. please advise.

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [3 May 2022 11:42 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/15 "2022-05-03T11:42:38Z")

</div>

@jupiter8 thanks it's done.

---

<div class="post-metadata">

**Author:** ![OriolFM](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/oriolfm/32/30710_2.png) [@OriolFM](https://discourse.nodered.org/u/OriolFM)\
**Post date:** [3 May 2022 13:23 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/16 "2022-05-03T13:23:49Z")

</div>

Let's see:

- [The S7 PLCs can syncronize the time, for instance with a local NTP server](https://support.industry.siemens.com/cs/document/86535497/time-synchronization-time-synchronization-in-the-automation-environment?dti=0&lc=en-WW), they're not supposed to measure it internally (only as a last resort). This is a screenshot from one of my PLC's Device Configuration \> Properties screen, you'd just have to enable NTP server and connect to your local one (either the gateway, or your main network server):  

- Another option (probably easier) is to sync the HMI to an NTP server (easy, if you're using a Simatic Comfort HMI, they run on Windows CE), then tell the PLC to sync its clock with the HMI one.

Both options will give you an exact time calculation on the PLC. If you do the calculation PLC-side and store the result in a persistent tag, you can read it from NR and back it up.

In the rare event that someone broke the program as you mentioned, you could always use TIA Portal to go online and initialize the value manually. It would take about 2 minutes at most, and it would be far more reliable than measuring the time and doing the calculation with NR (consider that every time you deploy NR you're essentially missing a few seconds of operating time, whereas the PLC can calculate the running time even if the connection is severed).

As for connecting the S7 node to the Siemens PLCs, I've used [node-red-contrib-s7](https://flows.nodered.org/node/node-red-contrib-s7) both S7-1200 and S7-300 PLCs (more than 30) in production and without issues, I think S7-400 should work as well, but I can't say for sure.

All of the PLCs I use are using Rack/Slot mode, but you have to doublecheck in TIA Portal that the Rack and Slot numbers are correct (sometimes they're mounted on another rack or slot, and then they won't work). This is the Device Configuration screen on one of my PLCs:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/3/d3649a2f96bfae121deeb12487c9b31bc45c2971.png)

I would also suggest to make the timeout time bigger than the refresh time (I usually give it an additional 50%, for instance, if I read every 2000ms, I set the timeout at 3000ms).

If all this is OK but still does not work, check that the PLC data block is not protected against Reading/Writing, and that the Optimized Block Access for the blocks you want to work with is disabled.  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/c/0cf53acef186f86aec543a74fd0862149995df1f.png)

Hops this helps.

---

<div class="post-metadata">

**Author:** ![alee](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@alee](https://discourse.nodered.org/u/alee)\
**Post date:** [5 May 2022 07:50 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/17 "2022-05-05T07:50:01Z")

</div>

@OriolFM thanks for the information I am using S7-300 and S-7400 with step 7 5.6. do i have to make any changes?

---

<div class="post-metadata">

**Author:** ![OriolFM](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/oriolfm/32/30710_2.png) [@OriolFM](https://discourse.nodered.org/u/OriolFM)\
**Post date:** [5 May 2022 12:10 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/18 "2022-05-05T12:10:21Z")

</div>

I wouldn't know, since you haven't posted any information on how your PLCs or your S7 nodes are configured.

If you add more details, I can take a look.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [4 July 2022 12:11 UTC](https://discourse.nodered.org/t/how-can-i-count-the-running-hours-of-a-machine-plc-s7/61915/19 "2022-07-04T12:11:07Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
