DB V2 - bar chart to track daily number of starts?

Is there an example somewhere for a bar chart to track number of starts daily?
We have a machine that we would like to have a bar chart that shows how many starts it does daily,
So one new bar for each day that shows number of starts as bar and a number count.
We are so far unable to accumulate the payload count in a bar chart.
We are now sending a number:1 to the bar chart every time it starts, but the chart does not add, but creates a new bar for each payload.

Is there any flow example or good starting point out there please? Many thanks!

Not sure if this will work, but you could calculate the total starts within your flow and store in a flow variable, Then add “1” to that for every start and send that in as the payload. I think you would need to change the chart to “replace” instead of “append”. If you are showing different machines on the same chart, it may get a bit more complicated.

1 Like

What operating system do you have?

If it's linux the last command shows reboots.

For example

$ last reboot --limit 10 --time-format iso
reboot   system boot  6.12.34+rpt-rpi- 2025-08-15T23:49:08+01:00   still running
reboot   system boot  6.12.34+rpt-rpi- 2025-07-29T17:02:37+01:00 - 2025-08-15T23:49:09+01:00 (17+06:46)
reboot   system boot  6.12.34+rpt-rpi- 2025-07-22T10:11:07+01:00 - 2025-07-29T17:02:38+01:00 (7+06:51)
reboot   system boot  6.12.34+rpt-rpi- 2025-07-21T17:00:15+01:00 - 2025-07-22T10:11:08+01:00  (17:10)
reboot   system boot  6.12.25+rpt-rpi- 2025-07-21T15:24:00+01:00 - 2025-07-21T17:00:16+01:00  (01:36)
reboot   system boot  6.12.25+rpt-rpi- 2025-06-20T16:18:30+01:00 - 2025-07-21T15:24:01+01:00 (30+23:05)
reboot   system boot  6.12.25+rpt-rpi- 2025-06-20T01:17:00+01:00 - 2025-06-20T16:18:31+01:00  (15:01)
reboot   system boot  6.12.25+rpt-rpi- 2025-06-08T00:17:00+01:00 - 2025-06-20T16:18:31+01:00 (12+16:01)
reboot   system boot  6.12.25+rpt-rpi- 2025-05-16T09:16:18+01:00 - 2025-06-20T16:18:31+01:00 (35+07:02)
reboot   system boot  6.12.25+rpt-rpi- 2025-05-10T14:49:34+01:00 - 2025-05-16T09:16:19+01:00 (5+18:26)

You could exec this and process the output to give a date/count

I may be wrong, but i think they want to track the number of starts of a machine like a motor may be ?

How does this 'machine' give you an input ? as @rakgupta is suggesting, it may be easy to store the data in a flow context and then chart, if you want to store many days of data, then may be you could use a database as well. here is a simple function node to process the inputs coming via different topic.

[{"id":"5892cfe45a6d6288","type":"inject","z":"9cd9fa2d0d2e7202","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"decrement","x":460,"y":3600,"wires":[["7f9ec18312f3e6cd"]]},{"id":"e695ff9f774255b4","type":"inject","z":"9cd9fa2d0d2e7202","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"reset","x":470,"y":3640,"wires":[["7f9ec18312f3e6cd"]]},{"id":"7f9ec18312f3e6cd","type":"function","z":"9cd9fa2d0d2e7202","name":"magic","func":"var count = flow.get('count1');\n\nif (msg.topic == \"reset\") {\n    count = 0;\n    context.set('count',0);\n    flow.set(\"count1\", 0);\n}\nelse if (msg.topic== \"increment\") {\n    count += 1;\n    context.set('count',count);\n    flow.set('count1',count)\n}\nelse if ( (msg.topic == \"decrement\")) {\n        count -= 1;\n    context.set('count',count);\n    flow.set('count1',count)\n}\n\n// make it part of the outgoing msg object\nmsg.count = count;\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nvar count = flow.get('count1');","finalize":"","libs":[],"x":630,"y":3600,"wires":[["89d6ca25481c3c8b"]]},{"id":"6e9b47373f6076e4","type":"inject","z":"9cd9fa2d0d2e7202","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"increment","x":460,"y":3560,"wires":[["7f9ec18312f3e6cd"]]},{"id":"89d6ca25481c3c8b","type":"debug","z":"9cd9fa2d0d2e7202","name":"debug 3056","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"count","statusType":"msg","x":800,"y":3600,"wires":[]}]

incre_decre_reset

1 Like

Yes, I experimented with something along those lines too but there seems to be missing functionality in the bar chart that requires external functions. This node node-red-contrib-dashboard-bar-chart-data2 appears to have done precisely this for the V1 dashboard but does not seem to work with V2. It does the summing if you send a number payload of 1 and you can set into create a new bar per time or day

Thanks @smanjunath211 . Yes I want to track a machine that already sends a payload when it starts.

Will have a look at your suggested flow and see if I get it. Many thanks!

Thanks again @smanjunath211

The machine has an attached shelly device that sends a payload when it starts: number: 10 and stops: number:1.
My working work in progress is a line chart that shows each starts like so:

But a bar chart with daily summed bars going back a month is what we want and need.
We are using this function for the chart data to survive restarts wich requires special settings in the chart.
..and this node appears to have done what we want for the V1 dashboard but unable so far to use it with the V2 dashboard. Many thanks again.

can eventually get what you want with many attempts, but i dont want to give you a incorrect or incomplete flow, i will wait for other experts to pitch in, roughly how many starts/stops are we expecting per day. just curious

Appreciated!

We would expect probably typically varying beween approximately 20 and 50 starts unless something is wrong and it could then be considerably more, which is one of the things we want to catch.

I would have thought that a statetrail chart would be a better one to use rather than a bar chart. a cluster of restarts should be easily visible. I think there is one for DB2?

1 Like

If you used a database such as sqlite you could insert a record each time the machine starts and select date, count(*) group by date to retrieve 30 days data and feed the chart.

I should apologise for lack of clarity. By “machine” I do not mean a computer but for example an electric motor or such with a relay that indicates start/stop..

To clarify my suggestion, the database could run on the same computing device as Node-red.

1 Like

Here is a sample flow that keeps track of counts by date in an array. When the date changes, it creates a new element. You can then send this into a chart.

However, as @jbudd suggested, it’s better to keep this in a database. Context variables will be reset if the Node-RED is restarted (unless you are wiriting them to the file storage system - I think there is an option in settings.js file but I haven’t used that)

[{"id":"7f9ec18312f3e6cd","type":"function","z":"6bd6b1f16707d706","name":"Get Chart Data","func":"var tempArray = flow.get('chartdata') || [];\nvar startDate = msg.payload.date;\nvar oldDate = flow.get('oldDate');\nvar oldCount = flow.get('oldCount') || 0;\nvar count = 0;\n\n// If this is the first time, initialize array\nif (tempArray.length === 0) {\n    tempArray.push({ date: startDate, starts: 0 });\n    }\n\nvar lastIndex = tempArray.length - 1;\n\nif (startDate === oldDate) {\n    count = oldCount + 1;\n    flow.set(\"oldCount\", count);\n    // Update last element\n    tempArray[lastIndex].date = startDate;\n    tempArray[lastIndex].starts = count;\n} else {\n    count = 1;\n    flow.set(\"oldCount\", count);\n    flow.set(\"oldDate\", startDate);\n    // Add new element\n    tempArray.push({ date: startDate, starts: count});\n}\n\n// Save to flow and msg\nflow.set(\"chartdata\", tempArray);\nmsg.chartData = tempArray;\n\nreturn msg;\n","outputs":1,"timeout":"","noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nvar count = flow.get('count1');","finalize":"","libs":[],"x":1285.8346099853516,"y":952.8860168457031,"wires":[["89d6ca25481c3c8b"]]},{"id":"89d6ca25481c3c8b","type":"debug","z":"6bd6b1f16707d706","name":"bar chart","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1456.8346099853516,"y":950.8860168457031,"wires":[]},{"id":"f6e258d37f015672","type":"change","z":"6bd6b1f16707d706","name":"Today's Data","rules":[{"t":"set","p":"payload.date","pt":"msg","to":" $moment().tz('America/Chicago').format('YYYY-MM-DD')\t","tot":"jsonata"},{"t":"set","p":"payload.count","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1078.6581115722656,"y":879.7958984375,"wires":[["7f9ec18312f3e6cd"]]},{"id":"9df607764821a4d8","type":"inject","z":"6bd6b1f16707d706","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"increment","x":902.8346252441406,"y":881.2389526367188,"wires":[["f6e258d37f015672"]]},{"id":"8a744b0faccd7185","type":"change","z":"6bd6b1f16707d706","name":"Today + 1","rules":[{"t":"set","p":"payload.date","pt":"msg","to":"$moment().tz(\"America/Chicago\").add(1, \"days\").format(\"YYYY-MM-DD\")","tot":"jsonata"},{"t":"set","p":"payload.count","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1085.5992584228516,"y":955.7959289550781,"wires":[["7f9ec18312f3e6cd"]]},{"id":"5d50daf8aca40e36","type":"inject","z":"6bd6b1f16707d706","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"increment","x":906.1875,"y":955.5919189453125,"wires":[["8a744b0faccd7185"]]},{"id":"53feb0d6a7f09b40","type":"change","z":"6bd6b1f16707d706","name":"Today + 2","rules":[{"t":"set","p":"payload.date","pt":"msg","to":"$moment().tz(\"America/Chicago\").add(2, \"days\").format(\"YYYY-MM-DD\")","tot":"jsonata"},{"t":"set","p":"payload.count","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1089.1875,"y":1035.5919189453125,"wires":[["7f9ec18312f3e6cd"]]},{"id":"e20d76aa56f7a30b","type":"inject","z":"6bd6b1f16707d706","name":"","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"increment","x":909.7757415771484,"y":1035.3879089355469,"wires":[["53feb0d6a7f09b40"]]}]
1 Like

As mentioned and referenced earlier, earlier, I have a function that solves the persistence over reboots.
Perhaps what I am asking for is more difficult and unusual than I thought.
Ideally I would want the daily bar chart to gradually build and then switch to a new bar at midnight and start adding to that. That would make a lot of sense from a GUI perspective.
Perhaps that is not viable.

That can be done, and I use the same principle but with a database (to avoid complicated (for me ) context storage).
It can be a dynamic chart.

1 Like

The sample that I posted above does that. Whenever the date changes, it creates a new element in the array otherwise it just adds it to the count for the day. You can connect the output of the function node to a ui-chart (needs to be configured to match the data or the data needs to be reordered to match what you want in the chart).

I took at look at the issue that you had logged in GitHub - my understanding is that you are writing the data out to the file system and then loading it back in at restart. Is that correct? If yes, then you could use the same approach and write the output of the function node (from my flow) to whatever you were using.

One other option is to use ui-template and chart.js but that has a much higher learning curve.

1 Like

Probably not but people are making suggestions without any knowledge of your function that maintains the data over reboots.
Perhaps this "function" is an instance of that contrib node you mentioned? (In which case you using the word function to describe it is less than helpful.)
You did not post a link to that node but since I am unfamiliar with it I did go to find it's page on flows.nodered.org.

It seems not to be a dashboard node, so doesn't the problem boil down to a reformatting of it's output for the dashboard2 chart node?

Indeed, if you posted an example of it's output data, someone might be interested enough to code the conversion for you.

ps My first thought, last reboot, was due to a misunderstanding of the nature of the machine, which you have now characterised as "for example an electric motor or such with a relay".

My second thought, a database, was because I foresaw difficulties with rotating the 30 days stored data every day. It would also retain the data in case you wanted to do longer term trend identification. However, installing a database just for this is surely overkill. Especially since you are confident that you already have the 30 days data storage.

I tried your flow and it creates a new bar for each payload for me. Will definitely try it some more.
Not sure what the three inputs should be wired to, they all say “increment” in the example inject node.

Yes, on your question, I am writing the data out to the file system and then loading it back in at restart. That part works as expected already. It is the summing or incrementing of the payloads that I still can not get to work. I am now simply sending a number:1 with a timestamp.

I appreciate your replies.

The 3 inputs were a sample only to generate the data - they would not be needed if the data was coming in msg.payload (you would wire that to the function node).

What do you have selected in “Action” in the chart configuration? If it is “Append” change that to “Replace”