Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Diff: clock/http-clock-script.inc
- Revision:
- 94:d7226b2c14b6
- Parent:
- 77:4689596a2f3f
- Child:
- 95:8c9dda8a0caf
diff -r 8995561d995f -r d7226b2c14b6 clock/http-clock-script.inc
--- a/clock/http-clock-script.inc Fri Apr 12 14:12:02 2019 +0000
+++ b/clock/http-clock-script.inc Tue Apr 16 19:18:27 2019 +0000
@@ -1,224 +1,183 @@
+"//Clock script\n"
"'use strict';\n"
"\n"
-"var response = '';\n"
-"var headers = '';\n"
-"var msRtc = 0; //nibbles 0 to 3: 16 bits\n"
-"var msCountAtRtcSet = 0;\n"
-"var msDiff = 0;\n"
-"var rtcIsSet = false; //nibble 4 : bit 0\n"
-"var clockIsSet = false; //nibble 4 : bit 1\n"
-"var sourceIsOk = false; //nibble 4 : bit 2\n"
-"var rateIsLocked = false; //nibble 4 : bit 3\n"
-"var timeIsLocked = false; //nibble 5 : bit 0\n"
-"var leapEnable = false; //nibble 5 : bit 1\n"
-"var leapForward = false; //nibble 5 : bit 2\n"
-"var leapmonths1970 = 0; //nibbles 6 to 8: 12 bits\n"
-"var leapmonth = 0;\n"
-"var leapyear = 0;\n"
-"var leaps = 0; //nibbles 9 to 12: 16 bits\n"
-"var ppb = 0; //nibbles 13 to 20: 32 bits\n"
-"var scanavg = 0; //nibbles 21 to 28: 32 bits\n"
-"var scanmax = 0; //nibbles 29 to 36: 32 bits\n"
-"var scanmin = 0; //nibbles 37 to 44: 32 bits\n"
-"var msCount = 0;\n"
+"let pseudo = new Utc();\n"
+"let rtc = new Utc();\n"
+"\n"
+"let pseudoDisplay = false;\n"
+"let pseudoStartMs = 0;\n"
+"\n"
+"let diffMs = 0;\n"
+"let rtcIsSet = false;\n"
+"let clockIsSet = false;\n"
+"let sourceIsOk = false;\n"
+"let rateIsLocked = false;\n"
+"let timeIsLocked = false;\n"
+"let leapmonths1970 = 0;\n"
"\n"
-"const TICK_MS = 100;\n"
-"const AJAX_REFRESH_MS = 10000;\n"
-"const AJAX_QUIET_MS = 3000;\n"
+"let ppb = 0;\n"
+"let ppbdivisor = 0;\n"
+"let ppbmaxchange = 0;\n"
+"let syncedlimitppb = 0;\n"
+"let syncedhysppb = 0;\n"
+"let slewdivisor = 0;\n"
+"let slewmax = 0;\n"
+"let syncedlimitns = 0;\n"
+"let syncedhysns = 0;\n"
+"let maxoffsetsecs = 0;\n"
+"let govTrace = false;\n"
"\n"
-"function hexToBit(iChar, iBit)\n"
-"{\n"
-" var value = parseInt(response.charAt(iChar), 16);\n"
-" value >>= iBit;\n"
-" return value & 1;\n"
-"}\n"
-"function parseAjax()\n"
+"let ntpserver = '';\n"
+"let ntpinitial = 0;\n"
+"let ntpnormal = 0;\n"
+"let ntpretry = 0;\n"
+"let ntpoffset = 0;\n"
+"let ntpmaxdelay = 0;\n"
+"\n"
+"let scanavg = 0;\n"
+"let scanmax = 0;\n"
+"let scanmin = 0;\n"
+"\n"
+"const DISPLAY_LEAP_MS = 10000;\n"
+"const SERVER = '/clock-ajax';\n"
+"\n"
+"function parseDate()\n"
"{\n"
-" var iDateStart = headers.toLowerCase().indexOf('date:');\n"
-" var iDateEnd = headers.indexOf('\\r', iDateStart);\n"
-" var rtcDate = new Date(headers.slice(iDateStart + 5, iDateEnd));\n"
-" msRtc = parseInt(response.substr(0, 4), 16);\n"
-" msRtc += rtcDate.getTime();\n"
-" msDiff = msRtc - Date.now();\n"
-" msCountAtRtcSet = msCount;\n"
-" rtcIsSet = hexToBit(4, 0);\n"
-" clockIsSet = hexToBit(4, 1);\n"
-" sourceIsOk = hexToBit(4, 2);\n"
-" rateIsLocked = hexToBit(4, 3);\n"
-" timeIsLocked = hexToBit(5, 0);\n"
-" leapEnable = hexToBit(5, 1);\n"
-" leapForward = hexToBit(5, 2);\n"
-" leapmonths1970 = parseInt(response.substr(6, 3), 16);\n"
-" leapmonth = leapmonths1970 % 12;\n"
-" leapyear = (leapmonths1970 - leapmonth) / 12;\n"
-" leapmonth += 1;\n"
-" leapyear += 1970;\n"
-" leaps = parseInt(response.substr( 9, 4), 16);\n"
-" ppb = parseInt(response.substr(13, 8), 16);\n"
-" scanavg = parseInt(response.substr(21, 8), 16);\n"
-" scanmax = parseInt(response.substr(29, 8), 16);\n"
-" scanmin = parseInt(response.substr(37, 8), 16);\n"
-"}\n"
-"function displayGeneral()\n"
-"{\n"
-" var elem;\n"
-" elem = document.getElementById('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');\n"
-" elem = document.getElementById('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');\n"
-" elem = document.getElementById('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');\n"
-" elem = document.getElementById('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');\n"
-" elem = document.getElementById('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');\n"
-"\n"
-" elem = document.getElementById('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', leapEnable ? 'rtl' : 'ltr');\n"
-" elem = document.getElementById('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', leapForward ? 'rtl' : 'ltr');\n"
-"\n"
-" elem = document.getElementById('ajax-leap-year' ); if (elem) elem.value = leapmonths1970 ? leapyear : '';\n"
-" elem = document.getElementById('ajax-leap-month' ); if (elem) elem.value = leapmonths1970 ? leapmonth : '';\n"
-"\n"
-" elem = document.getElementById('ajax-leap-count' ); if (elem) elem.value = leaps;\n"
-"\n"
-" elem = document.getElementById('ajax-ppb' ); if (elem) elem.value = ppb;\n"
-"\n"
-" elem = document.getElementById('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;\n"
-" elem = document.getElementById('ajax-scan-max' ); if (elem) elem.textContent = scanmax;\n"
-" elem = document.getElementById('ajax-scan-min' ); if (elem) elem.textContent = scanmin;\n"
-"\n"
-" elem = document.getElementById('ajax-response' ); if (elem) elem.textContent = response;\n"
-" elem = document.getElementById('ajax-headers' ); if (elem) elem.textContent = headers;\n"
-" \n"
-" elem = document.getElementById('ajax-date-diff' ); if (elem) elem.textContent = msDiff;\n"
+" let iDateStart = BaseHeaders.toLowerCase().indexOf('date:');\n"
+" let iDateEnd = BaseHeaders.indexOf('\\r', iDateStart);\n"
+" let rtcDate = new Date(BaseHeaders.slice(iDateStart + 5, iDateEnd));\n"
+" rtc.ms = rtcDate.getTime();\n"
"}\n"
"\n"
-"function formatNumbers00(i)\n"
-"{\n"
-" if (i<10) i='0' + i;\n"
-" return i;\n"
-"}\n"
-"function formatDayOfWeek(wday)\n"
+"function parseLinesTime(text)\n"
"{\n"
-" switch(wday)\n"
-" {\n"
-" case 0: return 'Sun';\n"
-" case 1: return 'Mon';\n"
-" case 2: return 'Tue';\n"
-" case 3: return 'Wed';\n"
-" case 4: return 'Thu';\n"
-" case 5: return 'Fri';\n"
-" case 6: return 'Sat';\n"
-" default: return '---';\n"
-" }\n"
+" let lines = text.split('\\n');\n"
+" rtc.ms += parseInt(lines[0], 16);\n"
+" rtc.ms -= BaseMs;\n"
+" diffMs = rtc.ms + BaseMs - Date.now();\n"
+" rtcIsSet = hexToBit(lines[1], 0);\n"
+" clockIsSet = hexToBit(lines[1], 1);\n"
+" sourceIsOk = hexToBit(lines[1], 2);\n"
+" rateIsLocked = hexToBit(lines[1], 3);\n"
+" timeIsLocked = hexToBit(lines[1], 4);\n"
+" rtc.leapEnable = hexToBit(lines[1], 5);\n"
+" rtc.leapForward = hexToBit(lines[1], 6);\n"
+" govTrace = hexToBit(lines[1], 7);\n"
+" leapmonths1970 = parseInt(lines[2], 16);\n"
+" rtc.leapMonth = leapmonths1970 % 12;\n"
+" rtc.leapYear = (leapmonths1970 - rtc.leapMonth) / 12;\n"
+" rtc.leapMonth += 1;\n"
+" rtc.leapYear += 1970;\n"
+" rtc.leaps = parseInt(lines[3], 16);\n"
"}\n"
-"function adjustLeap()\n"
+"function parseLinesGov(text)\n"
"{\n"
-" if (msRtc == 0) return; //Don't attempt to adjust an invalid time\n"
-" \n"
-" if (!leapEnable) return; // Adjustment disabled\n"
-" \n"
-" //Get the calander date and time from the ms\n"
-" var now = msCount - msCountAtRtcSet + msRtc;\n"
-" var leapStart = Date.UTC(leapyear, leapmonth - 1, 1, 0, 0, leapForward ? 0: -1);\n"
-" \n"
-" if (now < leapStart) return; //Do nothing until reached the leap start\n"
-" \n"
-" if (leapForward) { msRtc -= 1000; leaps += 1; } //repeat 59\n"
-" else { msRtc += 1000; leaps -= 1; } //skip 59\n"
-" \n"
-" leapEnable = false;\n"
+" let lines = text.split('\\n');\n"
+" ppb = parseInt(lines[0], 16);\n"
+" ppbdivisor = parseInt(lines[1], 16);\n"
+" ppbmaxchange = parseInt(lines[2], 16);\n"
+" syncedlimitppb = parseInt(lines[3], 16);\n"
+" syncedhysppb = parseInt(lines[4], 16);\n"
+" slewdivisor = parseInt(lines[5], 16);\n"
+" slewmax = parseInt(lines[6], 16);\n"
+" syncedlimitns = parseInt(lines[7], 16);\n"
+" syncedhysns = parseInt(lines[8], 16);\n"
+" maxoffsetsecs = parseInt(lines[9], 16);\n"
"}\n"
-"function displayTime()\n"
+"function parseLinesNtp(text)\n"
+"{\n"
+" let lines = text.split('\\n');\n"
+" ntpserver = lines[0];\n"
+" ntpinitial = parseInt(lines[1], 16);\n"
+" ntpnormal = parseInt(lines[2], 16);\n"
+" ntpretry = parseInt(lines[3], 16);\n"
+" ntpoffset = parseInt(lines[4], 16);\n"
+" ntpmaxdelay = parseInt(lines[5], 16);\n"
+"}\n"
+"function parseLinesScan(text)\n"
"{\n"
-" if (msRtc == 0) return; //Don't attempt to display an invalid time\n"
+" let lines = text.split('\\n');\n"
+" scanavg = parseInt(lines[0], 16);\n"
+" scanmax = parseInt(lines[1], 16);\n"
+" scanmin = parseInt(lines[2], 16);\n"
+"}\n"
+"function DerivedParse()\n"
+"{\n"
+" let topics = BaseResponse.split('\\f');\n"
+" parseDate();\n"
+" parseLinesTime(topics[0]);\n"
+" parseLinesGov (topics[1]);\n"
+" parseLinesNtp (topics[2]);\n"
+" parseLinesScan(topics[3]);\n"
+"}\n"
+"function DerivedDisplay()\n"
+"{\n"
+" let elem;\n"
+" elem = getElementOrNull('ajax-rtc-set' ); if (elem) elem.setAttribute('dir', rtcIsSet ? 'rtl' : 'ltr');\n"
+" elem = getElementOrNull('ajax-clock-set' ); if (elem) elem.setAttribute('dir', clockIsSet ? 'rtl' : 'ltr');\n"
+" elem = getElementOrNull('ajax-source-ok' ); if (elem) elem.setAttribute('dir', sourceIsOk ? 'rtl' : 'ltr');\n"
+" elem = getElementOrNull('ajax-rate-locked' ); if (elem) elem.setAttribute('dir', rateIsLocked ? 'rtl' : 'ltr');\n"
+" elem = getElementOrNull('ajax-time-locked' ); if (elem) elem.setAttribute('dir', timeIsLocked ? 'rtl' : 'ltr');\n"
" \n"
-" //Get the calander date and time from the ms\n"
-" var now = new Date(msCount - msCountAtRtcSet + msRtc);\n"
-" var y = now.getUTCFullYear();\n"
-" var n = now.getUTCMonth () + 1;\n"
-" var d = now.getUTCDate ();\n"
-" var w = now.getUTCDay (); // 0 == Sunday\n"
-" var h = now.getUTCHours ();\n"
-" var m = now.getUTCMinutes ();\n"
-" var s = now.getUTCSeconds ();\n"
-" \n"
-" //Format time\n"
-" n = formatNumbers00(n);\n"
-" d = formatNumbers00(d);\n"
-" h = formatNumbers00(h);\n"
-" m = formatNumbers00(m);\n"
-" s = formatNumbers00(s);\n"
-" w = formatDayOfWeek(w);\n"
+" elem = getElementOrNull('ajax-leap-enable' ); if (elem) elem.setAttribute('dir', rtc.leapEnable ? 'rtl' : 'ltr');\n"
+" elem = getElementOrNull('ajax-leap-forward' ); if (elem) elem.setAttribute('dir', rtc.leapForward ? 'rtl' : 'ltr');\n"
" \n"
-" //Display time\n"
-" var elem;\n"
-" \n"
-" elem = document.getElementById('ajax-date-utc');\n"
-" if (elem) elem.textContent = y + '-' + n + '-' + d + ' ' + w + ' ' + h + ':' + m + ':' + s + ' TAI-UTC=' + leaps;\n"
-"\n"
-" elem = document.getElementById('ajax-date-pc');\n"
-" var options = \n"
-" {\n"
-" year: 'numeric',\n"
-" month: 'short',\n"
-" day: '2-digit',\n"
-" weekday: 'short',\n"
-" hour: '2-digit',\n"
-" minute: '2-digit',\n"
-" second: '2-digit',\n"
-" timeZoneName: 'short'\n"
-" };\n"
-" if (elem) elem.textContent = now.toLocaleString(undefined, options);\n"
+" elem = getElementOrNull('ajax-leap-year' ); if (elem) elem.value = leapmonths1970 ? rtc.leapYear : '';\n"
+" elem = getElementOrNull('ajax-leap-month' ); if (elem) elem.value = leapmonths1970 ? rtc.leapMonth : '';\n"
+" \n"
+" elem = getElementOrNull('ajax-leap-count' ); if (elem) elem.value = rtc.leaps;\n"
+" \n"
+" elem = getElementOrNull('ajax-ppb' ); if (elem) elem.value = ppb;\n"
+" elem = getElementOrNull('ajax-ppb-divisor' ); if (elem) elem.value = ppbdivisor;\n"
+" elem = getElementOrNull('ajax-ppb-max-chg' ); if (elem) elem.value = ppbmaxchange;\n"
+" elem = getElementOrNull('ajax-ppb-syn-lim' ); if (elem) elem.value = syncedlimitppb;\n"
+" elem = getElementOrNull('ajax-ppb-syn-hys' ); if (elem) elem.value = syncedhysppb;\n"
+" elem = getElementOrNull('ajax-off-divisor' ); if (elem) elem.value = slewdivisor;\n"
+" elem = getElementOrNull('ajax-off-max' ); if (elem) elem.value = slewmax;\n"
+" elem = getElementOrNull('ajax-off-syn-lim' ); if (elem) elem.value = syncedlimitns / 1000000;\n"
+" elem = getElementOrNull('ajax-off-syn-hys' ); if (elem) elem.value = syncedhysns / 1000000;\n"
+" elem = getElementOrNull('ajax-off-rst-lim' ); if (elem) elem.value = maxoffsetsecs;\n"
+" elem = getElementOrNull('ajax-gov-trace' ); if (elem) elem.setAttribute('dir', govTrace ? 'rtl' : 'ltr');\n"
+" \n"
+" elem = getElementOrNull('ajax-ntp-server' ); if (elem) elem.value = ntpserver;\n"
+" elem = getElementOrNull('ajax-ntp-initial' ); if (elem) elem.value = ntpinitial;\n"
+" elem = getElementOrNull('ajax-ntp-normal' ); if (elem) elem.value = ntpnormal / 60;\n"
+" elem = getElementOrNull('ajax-ntp-retry' ); if (elem) elem.value = ntpretry;\n"
+" elem = getElementOrNull('ajax-ntp-offset' ); if (elem) elem.value = ntpoffset;\n"
+" elem = getElementOrNull('ajax-ntp-max-delay'); if (elem) elem.value = ntpmaxdelay;\n"
+" \n"
+" elem = getElementOrNull('ajax-scan-avg' ); if (elem) elem.textContent = scanavg;\n"
+" elem = getElementOrNull('ajax-scan-max' ); if (elem) elem.textContent = scanmax;\n"
+" elem = getElementOrNull('ajax-scan-min' ); if (elem) elem.textContent = scanmin;\n"
+" \n"
+" elem = getElementOrNull('ajax-date-diff' ); if (elem) elem.textContent = diffMs;\n"
"}\n"
"\n"
-"var ajax;\n"
-"var msCountAtAjaxSend = 0;\n"
-"function AjaxRequest(request) //Used by this script and from HTML page\n"
-"{\n"
-" ajax=new XMLHttpRequest();\n"
-" ajax.onreadystatechange=handleAjaxResponse;\n"
-" if (request) ajax.open('GET', '/clock-ajax' + '?' + request, true);\n"
-" else ajax.open('GET', '/clock-ajax' , true);\n"
-" ajax.send();\n"
-"}\n"
-"function requestAjax() //Used in this script\n"
-"{\n"
-" \n"
-" AjaxRequest('');\n"
-" msCountAtAjaxSend = msCount;\n"
-"}\n"
-"\n"
-"function counter()\n"
+"function DerivedTick() //This typically called every 100ms\n"
"{\n"
-" msCount += TICK_MS; //Don't use Date.now() as we don't know when its clock will be updated around a leap second\n"
-" adjustLeap();\n"
-" displayTime();\n"
-" if (msCount >= msCountAtRtcSet + AJAX_REFRESH_MS && //Wait until time to refresh\n"
-" msCount >= msCountAtAjaxSend + AJAX_QUIET_MS) //Don't repeat during quiet period\n"
+" if (pseudoDisplay)\n"
" {\n"
-" requestAjax(); //RequestAjax will set msRtc and reset msCount\n"
+" pseudo.adjustLeap (BaseMs);\n"
+" pseudo.displayTime(BaseMs);\n"
+" if (BaseMs >= pseudoStartMs + DISPLAY_LEAP_MS + 500) pseudoDisplay = false;\n"
" }\n"
-"}\n"
-"\n"
-"function handleAjaxResponse()\n"
-"{\n"
-" if (ajax.readyState==4 && ajax.status==200)\n"
-" {\n"
-" response = ajax.responseText;\n"
-" headers = ajax.getAllResponseHeaders();\n"
-" parseAjax();\n"
-" displayGeneral();\n"
-" }\n"
+" else\n"
+" {\n"
+" rtc.adjustLeap (BaseMs);\n"
+" rtc.displayTime(BaseMs);\n"
+" }\n"
"}\n"
"\n"
"function DisplayLeap() //Called by display leap button in HTML\n"
"{\n"
-" leapEnable = true;\n"
-" msRtc = Date.UTC(leapyear, leapmonth - 1, 1) - AJAX_REFRESH_MS / 2; //displays the refresh period around the latest leap second\n"
-" msCountAtRtcSet = msCount;\n"
+" pseudoDisplay = true;\n"
+" pseudoStartMs = BaseMs;\n"
+" \n"
+" pseudo.leapEnable = true;\n"
+" pseudo.leapForward = rtc.leapForward;\n"
+" pseudo.leaps = rtc.leaps;\n"
+" pseudo.leapMonth = rtc.leapMonth;\n"
+" pseudo.leapYear = rtc.leapYear;\n"
+" pseudo.ms = Date.UTC(rtc.leapYear, rtc.leapMonth - 1, 1) - DISPLAY_LEAP_MS / 2 - BaseMs;\n"
"}\n"
-"\n"
-"function init()\n"
-"{\n"
-" setInterval(counter, TICK_MS);\n"
-" requestAjax();\n"
-"}\n"
-"if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init ); // Loading hasn't finished yet\n"
-"else init(); //`DOMContentLoaded` has already fired\n"
""
\ No newline at end of file