This is most of the flow that does it.
Understand that the inject
node is from another thing which is basically a timed pulse happening every 'x' seconds. A sort of heart beat for the entire system.
The last function
node has 3 outputs.
The first one goes to a bit more stuff which looks at the true/false output.
If it is false
it creates a message (into a queue - not included) so I can see when it is happening.
You need some global, flow and context variables.
Code:
[{"id":"90849cb5.ea66d8","type":"function","z":"61a474ed.8f915c","name":"","func":"msg.payload = new Date().toLocaleString();\nreturn msg;","outputs":1,"noerr":0,"x":320,"y":580,"wires":[["324860a2.b6d818"]]},{"id":"e8a8a4dd.b000d","type":"exec","z":"61a474ed.8f915c","command":"sudo hwclock -r","addpay":false,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"HWC time","x":300,"y":630,"wires":[["7ea41cc2.48ec7c"],[],[]]},{"id":"324860a2.b6d818","type":"string","z":"61a474ed.8f915c","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":440,"y":580,"wires":[["80929a9.1c63968"]]},{"id":"7ea41cc2.48ec7c","type":"string","z":"61a474ed.8f915c","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":450,"y":660,"wires":[["fc070eae.6b31f8"]]},{"id":"fc070eae.6b31f8","type":"delay","z":"61a474ed.8f915c","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":450,"y":720,"wires":[["f7cbe7c7.3dea48"]]},{"id":"80929a9.1c63968","type":"string","z":"61a474ed.8f915c","name":"","methods":[{"name":"right","params":[{"type":"num","value":"8"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":640,"y":610,"wires":[["ce5d268.6ebb558"]]},{"id":"f7cbe7c7.3dea48","type":"string","z":"61a474ed.8f915c","name":"","methods":[{"name":"right","params":[{"type":"num","value":"8"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":640,"y":650,"wires":[["f6dee7f8.875228"]]},{"id":"ce5d268.6ebb558","type":"function","z":"61a474ed.8f915c","name":"","func":"var hour = parseInt(msg.payload.slice(0,2));\nvar minute = parseInt(msg.payload.slice(3,5));\nvar second = parseInt(msg.payload.slice(6,8));\n//node.warn(\"Hour \" + hour);\n//node.warn(\"Minute \" + minute);\n//node.warn(\"Second \" + second);\nvar time = hour*3600 + minute * 60 + second;\nmsg = {payload: time, topic: 'local'};\nreturn msg;","outputs":1,"noerr":0,"x":780,"y":610,"wires":[["a63629bf.4f1a58"]]},{"id":"f6dee7f8.875228","type":"function","z":"61a474ed.8f915c","name":"","func":"var hour = parseInt(msg.payload.slice(0,2));\nvar minute = parseInt(msg.payload.slice(3,5));\nvar second = parseInt(msg.payload.slice(6,8));\n//node.warn(hour);\n//node.warn(minute);\n//node.warn(second);\nvar time = hour*3600 + minute * 60 + second;\nmsg = {payload: time, topic: 'RTC'};\nreturn msg;","outputs":1,"noerr":0,"x":780,"y":650,"wires":[["a63629bf.4f1a58"]]},{"id":"a63629bf.4f1a58","type":"function","z":"61a474ed.8f915c","name":"","func":"var threshold = context.get('threshold')|| 60;\nvar a;\nvar b;\nvar r;\ncontext.set('threshold', threshold);\nmsg3 = {payload: threshold};\n\nif (msg.topic == 'Debug')\n{\n if (msg.payload === true)\n {\n context.set('db', 1);\n } else\n if (msg.payload === false)\n {\n context.set('db', 0);\n }\n}\nvar db = context.get('db');\n\n//---------------------\nif (msg.topic == 'slip')\n{\n if (db == 1)\n {\n node.warn(\"**************************\");\n node.warn(\"Threshold set to \" + msg.payload);\n }\n context.set('threshold', msg.payload);\n}\n//---------------------\nif (msg.topic == \"RTC\")\n{\n// context.set('RTC',msg.payload);\n flow.set(\"RTC\",msg.payload);\n //node.warn(\"RTC \" + context.get('RTC'));\n}\nif (msg.topic == \"local\")\n{\n// context.set('local', msg.payload);\n flow.set(\"local\", msg.payload);\n //node.warn(\"Local \" + context.get('local'));\n}\nif (db == 1)\n{\n// node.warn(\"Stored RTC value \" + context.get('RTC'));\n// node.warn(\"Stored RPI value \" + context.get('local'));\n node.warn(\"Stored RTC value \" + flow.get(\"RTC\"));\n node.warn(\"Stored RPI value \" + flow.get(\"local\"));\n node.warn(\"Stored threshold value \" + context.get('threshold'));\n}\n\n//if (context.get('RTC') !== 0)\nif (flow.get(\"RTC\") !== 0)\n{\n// if (context.get('local') !== 0)\n if (flow.get(\"local\") !== 0)\n {\n// a = context.get('RTC');\n// b = context.get('local');\n a = flow.get(\"RTC\");\n b = flow.get(\"local\");\n r = Math.abs(a - b);\n flow.set(\"Time_error\",r);\n }\n if (db == 1)\n {\n node.warn(\"Error is \" + r);\n }\n if (r > threshold)\n {\n // ** We have a problem! **\n if (db == 1)\n {\n node.warn(\"Part 1\");\n }\n node.status({fill:\"red\",shape:\"dot\",text:\"Time error\"});\n msg1 = {payload: false};\n msg2 = {payload: r};\n// flow.set(\"Time_error\",r);\n return [msg1, msg2, msg3];\n } \n// if (r < 0)\n// {\n// r = b - a;\n// if (r > threshold)\n// {\n// // ** We have a problem! **\n// if (db == 1)\n// {\n// node.warn(\"Part 2\");\n// }\n// node.status({fill:\"red\",shape:\"dot\",text:\"Time error\"});\n// msg1 = {payload: false};\n// msg2 = {payload: r};\n// flow.set(\"Time_error\",r);\n// return [msg1, msg2, msg3];\n// }\n// }\n else\n {\n // All Good!\n if (db == 1)\n {\n node.warn(\"Part 3\");\n }\n node.status({fill:\"green\",shape:\"dot\",text:\"Time good\"});\n msg1 = {payload: true};\n msg2 = {payload: r};\n return [msg1, msg2, msg3];\n }\n}\n","outputs":3,"noerr":0,"x":930,"y":630,"wires":[["b6a68b43.52e79"],[],[]],"outputLabels":["state","difference","threshold"]},{"id":"77bbc478.ba861c","type":"inject","z":"61a474ed.8f915c","name":"","topic":"","payload":"Trigger","payloadType":"str","repeat":"20","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":600,"wires":[["90849cb5.ea66d8","e8a8a4dd.b000d"]]},{"id":"b6a68b43.52e79","type":"switch","z":"61a474ed.8f915c","name":"","property":"payload","propertyType":"msg","rules":[{"t":"false"}],"checkall":"true","repair":false,"outputs":1,"x":800,"y":740,"wires":[["61fd8c0d.15249c"]]},{"id":"61fd8c0d.15249c","type":"function","z":"61a474ed.8f915c","name":"Time stamp","func":"msg.payload = flow.get(\"Time_error\");\nmsg.RTC = flow.get(\"RTC\");\nmsg.local = flow.get(\"local\");\nmsg.time = new Date().toLocaleString();\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":740,"wires":[[]]}]
As mentioned I have not (yet) caught any of those packets to see what the problem is and when it happens.
Though the ones I have seen are at mid-night.
Thus I added extra stuff on the last function
node to get the two time values and include them in the message.