How to compare two message - times and see if they are different?

I am not really sure what I am doing, but to keep the hamster happy upstairs, I am just asking this.

I have a RasPi that is MY NTP server. All my devices use it.
It has a RTC also. Not sure how that is important just now. But I'll mention it here/now.

I know there are NTP nodes out there but they seem to be overkill for what I want to do - I think.
Basically I want a daily NTP check that the clock isn't wonky.

A machine - not sure if it will be THAT one, or another one on the network.
The other machine will get it's time - which I now see is not going to work too well given the scenario I want to test.
I know there is a problem here with what I am about to say/ask.
Ok, two problems. (ARGH!)

I don't get/understand the background workings of NTP, HW and SW clocks and who is taking to whom to get their times.

So I am already in heavy fog for what I am doing.

I have 3 clocks: NTP, HW and SW.
If one of them goes off on an excursion I want to be informed.

So say every 6 hours it looks at the 3 clocks and hope they all match - within a given margin.
If one is wrong, it tells me (sends a message).

The NTP node I have won't poll that slowly.
So I have a command I use:
timedatectl status | grep Local
and I get the local time given to me.
Put that through a string node and it looks nice:
"Sat 2023-07-01 08:35:49 AEST"
Local time. I know that is no nice, but to establish a base line, I'll talk local for now.
Excuse me for now if this is not THE WAY.

I then read the HW and SW clocks and see if the new reading is within 30 minutes of the last time.
If it was a timestamp I got back would be a lot easier I know.

Any thoughts on how I can make it easier?
Oh, the exciting code I use to check the NTP side is working:

[{"id":"ce5ac6a3c140825d","type":"exec","z":"675e227d.d158b4","command":"timedatectl status | grep Local","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":530,"y":3000,"wires":[["dff7cbdba175c41a","b1e36e2fa2775905"],[],[]]},{"id":"994fd43d97ac2b98","type":"inject","z":"675e227d.d158b4","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":310,"y":3000,"wires":[["ce5ac6a3c140825d"]]},{"id":"dff7cbdba175c41a","type":"debug","z":"675e227d.d158b4","name":"debug 271","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":470,"y":2960,"wires":[]},{"id":"b1e36e2fa2775905","type":"string","z":"675e227d.d158b4","name":"","methods":[{"name":"collapseWhitespace","params":[]},{"name":"delLeftMost","params":[{"type":"str","value":": "}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":350,"y":3070,"wires":[["62557d9dbcb19e34"]]},{"id":"62557d9dbcb19e34","type":"debug","z":"675e227d.d158b4","name":"debug 272","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":370,"y":3110,"wires":[]}]

(Subflow and gate nodes in here)
And this is how I read the SW and HW clocks.
I send a pulse in and get the two times sent out to the debug nodes here. They are really text nodes, but to reduce the junk I am posting....

[{"id":"8d34d18c.a5c1d8","type":"subflow","name":"Time Stamp","info":"","category":"","in":[{"x":80,"y":100,"wires":[{"id":"e238745c.805ad"}]}],"out":[{"x":780,"y":180,"wires":[{"id":"e238745c.805ad","port":0},{"id":"f4d2e3a6.04b528","port":0}]},{"x":780,"y":230,"wires":[{"id":"e238745c.805ad","port":0},{"id":"f24c822.a42738","port":0}]},{"x":780,"y":280,"wires":[{"id":"5da44411.ed02ac","port":0},{"id":"e238745c.805ad","port":0}]}],"env":[],"color":"#FF8888","outputLabels":["For logging use","msg.time","For filename use"],"icon":"node-red/timer.svg"},{"id":"f4d2e3a6.04b528","type":"moment","z":"8d34d18c.a5c1d8","name":"","topic":"","input":"","inputType":"msg","inTz":"Australia/Sydney","adjAmount":0,"adjType":"days","adjDir":"add","format":"YYYY-MM-DD HH:mm:ss","locale":"en_AU","output":"","outputType":"msg","outTz":"Australia/Sydney","x":400,"y":180,"wires":[["5da44411.ed02ac","3a4de0cb.6235d"]]},{"id":"5da44411.ed02ac","type":"string","z":"8d34d18c.a5c1d8","name":"","methods":[{"name":"replaceAll","params":[{"type":"str","value":":"},{"type":"str","value":""}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":450,"y":280,"wires":[[]]},{"id":"3a4de0cb.6235d","type":"change","z":"8d34d18c.a5c1d8","name":"TOPIC","rules":[{"t":"move","p":"payload","pt":"msg","to":"time","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":230,"wires":[["f24c822.a42738"]]},{"id":"e584e350.1d8a48","type":"change","z":"8d34d18c.a5c1d8","name":"Save","rules":[{"t":"set","p":"origPayload","pt":"msg","to":"payload","tot":"msg","dc":true}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":140,"wires":[["3411b340.b65a04"]]},{"id":"f24c822.a42738","type":"change","z":"8d34d18c.a5c1d8","name":"Get","rules":[{"t":"set","p":"payload","pt":"msg","to":"origPayload","tot":"msg","dc":true}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":230,"wires":[[]]},{"id":"e238745c.805ad","type":"switch","z":"8d34d18c.a5c1d8","name":"check topic","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"TIMESTAMP","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":210,"y":100,"wires":[[],["e584e350.1d8a48"]]},{"id":"3411b340.b65a04","type":"change","z":"8d34d18c.a5c1d8","name":"TimeStamp","rules":[{"t":"set","p":"payload","pt":"msg","to":"","tot":"date"}],"action":"","property":"","from":"","to":"","reg":false,"x":210,"y":180,"wires":[["f4d2e3a6.04b528"]]},{"id":"596dfbde.39bc6c","type":"exec","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","command":"sudo hwclock -r","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"HWC time","x":630,"y":2240,"wires":[["f90ccbc3.25a8b","8601b654.799c6"],[],[]]},{"id":"f90ccbc3.25a8b","type":"string","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"","methods":[{"name":"replaceAll","params":[{"type":"str","value":"-"},{"type":"str","value":"/"}]},{"name":"left","params":[{"type":"num","value":"19"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":800,"y":2300,"wires":[["478e7ad6.3b69fc"]]},{"id":"29b57fb9.8ba4f","type":"subflow:8d34d18c.a5c1d8","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"","x":630,"y":2190,"wires":[["e53ec78c.5d5ce8","8532dba.67d7e28"],[],[]]},{"id":"8532dba.67d7e28","type":"string","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"","methods":[{"name":"left","params":[{"type":"num","value":"19"}]},{"name":"replaceAll","params":[{"type":"str","value":"-"},{"type":"str","value":"/"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":800,"y":2220,"wires":[["539fda71.578aa4"]]},{"id":"539fda71.578aa4","type":"gate","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"","controlTopic":"control","defaultState":"open","openCmd":"go","closeCmd":"stop","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":930,"y":2220,"wires":[["c10d8191.fe707","e582752f.3763f","edb7d713.13151","f205ad3c.2c3aa8"]]},{"id":"478e7ad6.3b69fc","type":"gate","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"","controlTopic":"control","defaultState":"open","openCmd":"go","closeCmd":"stop","toggleCmd":"toggle","defaultCmd":"default","persist":false,"x":930,"y":2300,"wires":[["fb254740.543b38","789410be.8b6d78","ffff48cd.81dd","6fc84240.f1f1dc"]]},{"id":"e582752f.3763f","type":"debug","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"Real Time (Now) with /","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1160,"y":2200,"wires":[]},{"id":"789410be.8b6d78","type":"debug","z":"e2bd5a4e.5597e8","g":"9e69bb336a453bf0","name":"HWC Time (Now) with /","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1170,"y":2280,"wires":[]}]

NTP servers are the backbone of the internet. They are within milliseconds of "the time" which is the atomic clock in the US. All clocks reference this time, or they used to. That said there are dozens of NTP servers you can interrogate. There are lists of these servers on the web. Hardware clocks especially in electronic devices such as pc's are a dedicated chip that goes out and talks to a NTP server. Software clocks are a piece of software that does the same thing as a hardware clock.
What I don't understand is why you are using three clocks. Is there no way to MQTT or something to send the time to your devices? I use a Nodemcu to talk to a NTP server and send the time to my devices. If you have a pi in your mass of devices it will automatically ping the NTP server. You wouldn't need a NTP node simply use a function node to get system time. Apparently your devices talk to each other, I'm not understanding your angst. You mention a 30 minute difference, my systems are within milliseconds of each other. Perhaps I am not getting your point.

Hi @gerry

(longish story)

Way back when I first got into the RasPi, I had NO internet.
Each time the machine was turned on I had to set the time.
After a while this became painfiul.
I THINK the RTC came next. Saved a lot of grief in that part.
My network then grew and it got things that were done at/on a time schedule.
The RTC was great as if a reboot or power failure happened things wouldn't happen at the wrong time/s.

Slowly I got an internet connection. (Woo hoo!) And I joined here.

The intricacies of the structure of the TIME is still beyond me.
All/most of this is done from curiosity.

But for the sake of explaining my theory:
The RTC is THE clock. It will survive a reboot/power failure etc.
The SW clock gets it's time from it and is used on THAT machine.
Other devices on my network have their NTP server set to the afore mentioned machine.

(after rethink)
The system boots (MY NTP server) it gets its time from the HWC.
SYSTEM TIME is set from that and the NTP server broadcasts that time.
My network is SINGLE SITED and I don't need absolute millisecond accuracy..
But it is important that 05:00 is 05:00 and not 13:00! Or vice versa.

System running and the power goes.
Comes back.
Machines boot.
MY (LOCAL) NTP server broadcasts (or has ready) it's time and all devices get its time.
All is good.
Every hour or so it would be nice that my local NTP server talk back to a T2 (or 1) server and fixes any problems.
But I do NOT want the EXTERNAL NTP to be THE GO TO as if the internet is down, all bets are off to what time the devices think it is.

Is that clearer?

I guess I have a background task that every now and then syncs the RTC (Hardware) clock on my RasPi to the external L2 (or 1) NTP sever.

If there is a difference, it adjusts my local time accordingly.

Doesn't the output of timedatectl status "System clock synchronized: yes/no" confirm if a device is synchronised with your NTP server without the need to compare time strings?

1 Like

Do you now have internet? If so then get rid of your local NTP server and let the OS sort it out for you using public servers.

Thanks for that idea.

I wasn't seeing that because I was filtering for the local time, rather than a This time is good flag.

So to check that I would just do something like:
timedatectl | grep syncronized and act on the output being yes or no. (Sorry my mistake on the first post)
(All the tricks I missed)


In a perfect world maybe. I live in Oz and it is far from.

I had (sorry side story) an old electronic lock that would wake me up to go to work of a morning.
It was old and destined for scrap, but was still working.

Winter, cold dark.
ALARM goes off.
I struggle up. Gee it IS dark.
Look at my watch. (#!&*&($!
Alarm set for 05:15. It is 02:xx! The alarm clock says 05:15
Rest the time, go back to bed and sleep.

Next day: Same thing happened.
This happened for abut 4 days and the alarm clock was consigned to the bin.
I guess 30 years of service is pretty good.
Had to use my phone for a few weeks while I learnt how to program Arduinos.

Relying on having an internet connection is not a good idea for me to get the time.
If I have a local RTC - yes, which can fail - is better than hoping the internet is working after a power failure and setting system scheduled tasks.

I've been down a similar rabbit hole where things were getting incorrectly scheduled. But that is a WHOLE OTHER story.
Having my RasPi as my local NTP server is/should be more reliable than expecting the internet to be there when I REALLY need it.

Back in the day clocks drifted a lot. But today even cheap clocks hold the time pretty well. If you can get the pi to sync up to NTP once I'd say it would be within seconds over a year running on it's internal clock. I'm in north America so we have WWV, Does Europe not have something similar? Do you have any kind of UPS for your pi? Even if it only syncs to NTP every month I would think it would be far more accurate than you'd need.

The Raspberry pi doesn’t have an onboard rtc so has to sync to something on every boot.

Which is why I said if you can get it to sync once then if you have a ups to get past the power failure you should be able to get stable time. The Pi will keep time on its own, it just won't survive a boot up.
It doesn't have an rtc as such but it does have a counter per say so it keeps track of how much time has elapsed and it does it fairly accurately.

For completely offline use, if you have visibility of the sky, then you can use a cheap GPS dongle to feed a local time service. (Nothing to do with Node-RED of course) - How to Add a GPS Time Source to ntpd | Rapid7 Blog


For clarity:
There IS a RTC in/on THIS RasPi.

And I shall take it as being a good time source.

So as @gerry said: It only should need syncing every month or so.
(Or say daily - just for the fun of it to help prevent any confusion when Daylight Savings kicks in)

Not every 10 minutes.


Thanks for the help.

This has given me more than enough to go through and work on.

I'll close it now because I think it has kind of been resolved.

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