Compute countdown timer value via Node-RED and then use in Grafana

I currently have a simple javascript countdown timer script running in a Grafana Text panel:

image

Here is what the Text panel looks like:

I realize using Node-RED dashboard would be a logical place to use a countdown timer (esp. since there are many excellent ones available), but in my case Grafana is widely used and in the interest of keeping everything on a single dashboard, I would like to try to use Grafana for this purpose.

I can use Node-RED to compute the var countDownDate since it's a simple calculation using some values that I already have in Node-RED, but once the math is done and I have a "future" date/time that I wish to count down to, could I use Node-RED to make that value "visible" on our local network, which the above Text panel could then reference / point to?

1 Like

To make a value available externally I make use of http-in + http-response nodes (this will create an http end-point, extemely useful to create api's), not sure if the following completely fits your request, but you can apply the gist of it.

Then you can open the http://<node-red-ip>:1880/countdown in a browser and the countdown date will be displayed (first click the inject node to set the flow variable).

In the grafana panel javascript use the fetch api to retrieve the same page.

<script>
fetch('http://<node-red-ip>:1880/countdown')
  .then((response) => response.text()
  .then(countdown))

function countdown(input) { 
	var countDownDate = new Date(input).getTime()
	var x = setInterval(()=>{ ... })
}
</script>

Example flow:

[{"id":"1349549af1259dbe","type":"http in","z":"d1354c2d336c9ebc","name":"","url":"/countdown","method":"get","upload":false,"swaggerDoc":"","x":350,"y":200,"wires":[["9b6390b07e6d525a"]]},{"id":"132b0428e9d2e51e","type":"http response","z":"d1354c2d336c9ebc","name":"","statusCode":"","headers":{},"x":710,"y":200,"wires":[]},{"id":"c0e9e9c8d46e2f59","type":"inject","z":"d1354c2d336c9ebc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":420,"y":280,"wires":[["a3c2bd895b4eb2db"]]},{"id":"a3c2bd895b4eb2db","type":"change","z":"d1354c2d336c9ebc","name":"","rules":[{"t":"set","p":"countdown","pt":"flow","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":280,"wires":[[]]},{"id":"9b6390b07e6d525a","type":"function","z":"d1354c2d336c9ebc","name":"","func":"msg.payload = new Date(flow.get(\"countdown\")).toISOString()\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":550,"y":200,"wires":[["132b0428e9d2e51e"]]}]
1 Like

Thank you. I think I have it almost working using the flow you provided. I see this in the browser after injecting the timestamp:
image

In Grafana, I pasted this (the first part coming from you, the second part from the W3 schools example):

<script>
fetch('http://192.168.10.25:1880/countdown')
  .then((response) => response.text()
  .then(countdown))

function countdown(input) { 
	var countDownDate = new Date(input).getTime()
// Update the count down every 1 second
var x = setInterval(function() {

  // Get today's date and time
  var now = new Date().getTime();

  // Find the distance between now and the count down date
  var distance = countDownDate - now;

  // Time calculations for days, hours, minutes and seconds
  var days = Math.floor(distance / (1000 * 60 * 60 * 24));
  var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  var seconds = Math.floor((distance % (1000 * 60)) / 1000);

  // Display the result in the element with id="demo"
  document.getElementById("demo").innerHTML = days + "d " + hours + "h "
  + minutes + "m " + seconds + "s ";

  // If the count down is finished, write some text
  if (distance < 0) {
    clearInterval(x);
    document.getElementById("demo").innerHTML = "EXPIRED";
  }
}, 1000);
</script>

Nothing appears in Grafana, but also no error messages. I believe I am missing something obvious?

Is the outcome of this calculation <0 ?

Correct, that value is < 0 (and it's embarrassing to miss that).

But even changing the javascript code to:

  var distance = (countDownDate + 10000) - now;

still does not make anything appear in Grafana.

Did you update the flow variable ? 10000 is nothing in millis

Yes, I injected the flow again in Node-RED and confirmed the updated value is displayed at http://192.168.10.25:1880/countdown

But even after expanding the +value from 10000 to 10000000000, I still cannot get anything to appear in the Grafana text panel. I think there must be an error in my javascript code above.