Get Datetime from browser via ui_template-node and send it to output

Hello!

I use the following example-node to get the time from browser:

Node-red-dashboard clock in toolbar (flow) - Node-RED (nodered.org)

How can I send the time to its output-payload?

I tried to do it in the function upTime as following:

    function upTime() {
        var d = new Date();
        p.text(d.toLocaleString());
        //this.scope.action = function() { return d; }
        this.scope.send({payload: d);
    }

But the debug-node at output does not show anything.

The target is to use the browser-time to set the system-time of a Raspi without any necessary button-click. The Raspi does not have a connection to the internet or any other time servers.
There are several examples in forums but all are done by button-click.

You are missing a } after the d

However, try

msg.payload = d
scope.send(msg)

Ok, I added the } to the function call and tried the second way you suggested but nothing happens in both ways:

[{"id":"2561ec7c.770d74","type":"debug","z":"81eb9cd4.305328","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":550,"y":1480,"wires":[]},{"id":"4e3a4b7d.1c7134","type":"ui_template","z":"81eb9cd4.305328","group":"91102efd.f7884","name":"Clock Toolbar","order":2,"width":"0","height":"0","format":"<script id=\"titleScript\" type=\"text/javascript\">\n\n$(function() {\n    if($('.md-toolbar-tools').length != 0){\n        loadClock();\n    }else setTimeout(loadClock, 500)\n});\n\nfunction loadClock(){\n    $('#clock').remove();\n    var toolbar = $('.md-toolbar-tools');\n    \n    var div = $('<div/>');\n    var p = $('<p/ id=\"clock\">');\n    \n    div.append(p);\n    div[0].style.margin = '5px 5px 5px auto';\n    toolbar.append(div);\n\n    function displayTitle(lh) {\n        p.text(lh); \n    }\n    \n    function upTime() {\n        var d = new Date();\n        p.text(d.toLocaleString());\n        msg.payload = d;\n        scope.send(msg);\n    }\n\n    if(document.clockInterval){ \n            clearInterval(document.clockInterval);\n            document.clockInterval = null;\n    }\n        \n    document.clockInterval = setInterval(upTime,1000);\n}\n\n</script>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"global","x":380,"y":1480,"wires":[["2561ec7c.770d74"]]},{"id":"91102efd.f7884","type":"ui_group","z":"","name":"hidden_group","tab":"611f485a.b79e78","disp":false,"width":"6","collapse":false},{"id":"611f485a.b79e78","type":"ui_tab","z":"","name":"Zooland Sys","icon":"home","order":1,"disabled":false,"hidden":false}]

Am I right, that the Function "upTime" is called every 1000ms so the debug node should spit out a new entry every second?

I have to admit I am confused. The node you are using is designed to send the time (of the unit that node red is running on) to the title bar in the browser, it will not do what you are after. I do not know of anyway of getting the time of the unit running the browser into node red although there may be people more up on this that do.

In any event you should use a function node and inject node to send a time as a msg.

The best way to do this would be to set your PC up as a time server, then your Pi will automatically sync to it. There is no need to get node red involved.

That is possible as long as the computer, which is used to connect to the raspi is even the same. But in my way there are different computers in use which are not in my administrative control.

Yes I like to display the time in the currently used browser and set this time to the raspi in the same procedure.
Therefore I can be sure that the displayed time is used to do some timecritical processes in raspi.

The time shown in the browser IS the time as known by your Pi. As far as I am aware any Date object used in Javascript represents the time of the machine that the code is running on. As I said before 'as far as I am aware there is no easy way of setting the Pi to the time of the device running the code (unless of course the browser & the code are on the Pi)

To get the time in the Node red browser header use you original function (without the send) in a Dashboard Template node set to 'added to site (head) section'

There are several Forum entries on this. This is the code I use - taken from one of those entries

<script id="clockScript" type="text/javascript">

    let clockInterval

    $(function () {
        if (clockInterval) return;

        // Add logo if Required
        /*
        const divLogo = $('<div/>');
        let logo = new Image();
    
        logo.src = '/test'
        logo.height = 45;
        divLogo[0].style.margin = '10px auto';
    
        // Allow logo to be a hyperlink -----------------------------------------
        const a = $("<a />");                   // Create an anchor / hyperlink
        a.attr("href", "/ui");                  // Set HREF to dashboard homepage (or other relevant target)
        a.append(logo);                         // Add logo to anchor
        divLogo.append(a);                      // Add anchor to divLogo
        // ---------------------------------------------------------------------

        divLogo.append(logo);
        */

        // Add clock
        const divClock = $('<div/>');
        const p = $('<p/>');

        divClock.append(p);
        divClock[0].style.margin = '5px';
        divClock[0].style.width = "100%";
        divClock[0].style.textAlign = "right";

        function displayTime() {
            p.text(new Date().toLocaleString());

        }

        clockInterval = setInterval(displayTime, 1000);

        // Add to toolbar when it's available
        let addToToolbarTimer;
 
        function addToToolbar() {
            let toolbar = $('.md-toolbar-tools');
 
            // Exit if there is NO Toolbar
            if (!toolbar.length) return;
 
            //toolbar.append(divLogo);
            toolbar.append(divClock);
            clearInterval(addToToolbarTimer);
        
        } 

        addToToolbarTimer = setInterval(addToToolbar, 100);

    })()

</script>

I thought the OP wanted to get the browser time into the node-red server, rather than send the server time to the browser.
If new Date() were to be run in javascript in the browser would that get the browser time? Which could then be sent to the server.

So did I until I saw this. Now I am just confused

Perhaps you would confirm (or otherwise) whether it is possible to send the browser time to the server?

:slight_smile: Colins description is right.
I like to get the browser time to send it to node-red server. I still get the browser-time by new Date() in the ui_template. This time is still displayed in section of the browser. Now I only need to get it out of the ui-template-node to send it to the nod red server. E.g. this could be done by Exec node.

I am not at my computer now, but I think there is an example of how to send a message in the help text for the template node.

The scope.send only seems works in the tab, I presume it is not in scope in the <head>.
you could send a http get request from the head and pick up the time/date in a http endpoint.
e.g.

[{"id":"69c699a5.47f94","type":"http in","z":"b779de97.b1b46","name":"","url":"time_date","method":"get","upload":false,"swaggerDoc":"","x":200,"y":3680,"wires":[["a76897c9.a113f8","20ee4ea1.48b01a"]]},{"id":"a76897c9.a113f8","type":"debug","z":"b779de97.b1b46","name":"","active":true,"console":"false","complete":"false","x":899,"y":3740,"wires":[]},{"id":"20ee4ea1.48b01a","type":"http response","z":"b779de97.b1b46","name":"","statusCode":"","headers":{},"x":430,"y":3640,"wires":[]},{"id":"111e0e2b.e9acd2","type":"ui_template","z":"b779de97.b1b46","group":"b9d366f18ff7ae74","name":"","order":14,"width":0,"height":0,"format":"<script>\nconst Http = new XMLHttpRequest();\nconst url='http://192.168.1.25:1880/time_date?time=' + new Date().valueOf();\nHttp.open(\"GET\", url);\nHttp.send();\n</script>","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"global","className":"","x":630,"y":3720,"wires":[["a76897c9.a113f8"]]},{"id":"fb693ad8.0a795","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":420,"y":3760,"wires":[["111e0e2b.e9acd2"]]},{"id":"b9d366f18ff7ae74","type":"ui_group","name":"test","tab":"ffba43d73860d25d","order":1,"disp":true,"width":12,"collapse":false},{"id":"ffba43d73860d25d","type":"ui_tab","name":"Level","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

Here is my solution:

[{"id":"a021868d.5e1e98","type":"ui_template","z":"81eb9cd4.305328","group":"3a9c9a16.03509e","name":"","order":0,"width":0,"height":0,"format":"<script>\n(function(scope){\n scope.$watch('msg', function(msg) {\n  var Datum = new Date();\n scope.send({payload: Datum});\n });\n})(scope);\n</script>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":380,"y":1420,"wires":[["55004949.ec9588"]]},{"id":"6192928a.fa62fc","type":"inject","z":"81eb9cd4.305328","name":"","topic":"","payloadType":"date","repeat":"5","crontab":"","once":true,"onceDelay":"","x":230,"y":1420,"wires":[["a021868d.5e1e98"]]},{"id":"3a9c9a16.03509e","type":"ui_group","z":"","name":"Status","tab":"c485423e.969b4","order":3,"disp":true,"width":"6","collapse":false},{"id":"c485423e.969b4","type":"ui_tab","z":"","name":"Prozess","icon":"timeline","order":3}]

There I do not use the time from the head but I query Date() cyclically. I then send this on with scope.send().
As group for the template node I set one of my tabs. If this tab is opened, the time is send to the node red server.

Thank you for your support!

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