Annotation of embedaddon/ntp/scripts/stats/clock.awk, revision 1.1
1.1 ! misho 1: # awk program to scan clockstat files and report errors/statistics
! 2: #
! 3: # usage: awk -f check.awk clockstats
! 4: #
! 5: # This program works for the following radios:
! 6: # PST/Traconex 1020 WWV reciever
! 7: # Arbiter 1088 GPS receiver
! 8: # Spectracom 8170/Netclock-2 WWVB receiver
! 9: # IRIG audio decoder
! 10: # Austron 2200A/2201A GPS receiver (see README.austron file)
! 11: #
! 12: BEGIN {
! 13: etf_min = osc_vmin = osc_tmin = 1e9
! 14: etf_max = osc_vmax = osc_tmax = -1e9
! 15: }
! 16: #
! 17: # scan all records in file
! 18: #
! 19: {
! 20: #
! 21: # select PST/Traconex WWV records
! 22: # 00:00:37.234 96/07/08/190 O6@0:5281825C07510394
! 23: #
! 24: if (NF >= 4 && $3 == "127.127.3.1") {
! 25: if (substr($6, 14, 4) > "0010")
! 26: wwv_sync++
! 27: if (substr($6, 13, 1) == "C")
! 28: wwv_wwv++
! 29: if (substr($6, 13, 1) == "H")
! 30: wwv_wwvh++
! 31: x = substr($6, 12, 1)
! 32: if (x == "1")
! 33: wwv_2.5++
! 34: else if (x == "2")
! 35: wwv_5++
! 36: else if (x == "3")
! 37: wwv_10++
! 38: else if (x == "4")
! 39: wwv_15++
! 40: else if (x == "5")
! 41: wwv_20++
! 42: continue
! 43: }
! 44: #
! 45: # select Arbiter GPS records
! 46: # 96 190 00:00:37.000 0 V=08 S=44 T=3 P=10.6 E=00
! 47: # N39:42:00.951 W075:46:54.880 210.55 2.50 0.00
! 48: #
! 49: if (NF >= 4 && $3 == "127.127.11.1") {
! 50: if (NF > 8) {
! 51: arb_count++
! 52: if ($7 != 0)
! 53: arb_sync++
! 54: x = substr($10, 3, 1)
! 55: if (x == "0")
! 56: arb_0++
! 57: else if (x == "1")
! 58: arb_1++
! 59: else if (x == "2")
! 60: arb_2++
! 61: else if (x == "3")
! 62: arb_3++
! 63: else if (x == "4")
! 64: arb_4++
! 65: else if (x == "5")
! 66: arb_5++
! 67: else if (x == "6")
! 68: arb_6++
! 69: } else if (NF == 8) {
! 70: arbn++
! 71: arb_mean += $7
! 72: arb_rms += $7 * $7
! 73: if (arbn > 0) {
! 74: x = $7 - arb_val
! 75: arb_var += x * x
! 76: }
! 77: arb_val = $7
! 78: }
! 79: continue
! 80: }
! 81: #
! 82: # select Spectracom WWVB records
! 83: # see summary for decode
! 84: # 96 189 23:59:32.248 D
! 85: #
! 86: if (NF >= 4 && $3 == "127.127.4.1") {
! 87: if ($4 == "SIGNAL" || NF > 7)
! 88: printf "%s\n", $0
! 89: else {
! 90: wwvb_count++
! 91: if ($4 ~ /\?/)
! 92: wwvb_x++
! 93: else if ($4 ~ /A/)
! 94: wwvb_a++
! 95: else if ($4 ~ /B/)
! 96: wwvb_b++
! 97: else if ($4 ~ /C/)
! 98: wwvb_c++
! 99: else if ($4 ~ /D/)
! 100: wwvb_d++
! 101: }
! 102: continue
! 103: }
! 104: #
! 105: # select IRIG audio decoder records
! 106: # see summary for decode
! 107: #
! 108: if (NF >= 4 && $3 == "127.127.6.0") {
! 109: irig_count++
! 110: if ($5 ~ /\?/)
! 111: irig_error++
! 112: continue
! 113: }
! 114: #
! 115: # select Austron GPS LORAN ENSEMBLE records
! 116: # see summary for decode
! 117: #
! 118: else if (NF >= 13 && $6 == "ENSEMBLE") {
! 119: ensemble_count++
! 120: if ($9 <= 0)
! 121: ensemble_badgps++
! 122: else if ($12 <= 0)
! 123: ensemble_badloran++
! 124: else {
! 125: if ($13 > 200e-9 || $13 < -200e-9)
! 126: ensemble_200++
! 127: else if ($13 > 100e-9 || $13 < -100e-9)
! 128: ensemble_100++
! 129: ensemble_mean += $13
! 130: ensemble_rms += $13 * $13
! 131: }
! 132: continue
! 133: }
! 134: #
! 135: # select Austron LORAN TDATA records
! 136: # see summary for decode; note that signal quality log is simply
! 137: # copied to output
! 138: #
! 139: else if (NF >= 7 && $6 == "TDATA") {
! 140: tdata_count++
! 141: for (i = 7; i < NF; i++) {
! 142: if ($i == "M" && $(i+1) == "OK") {
! 143: i += 5
! 144: m += $i
! 145: tdata_m++
! 146: }
! 147: else if ($i == "W" && $(i+1) == "OK") {
! 148: i += 5
! 149: w += $i
! 150: tdata_w++
! 151: }
! 152: else if ($i == "X" && $(i+1) == "OK") {
! 153: i += 5
! 154: x += $i
! 155: tdata_x++
! 156: }
! 157: else if ($i == "Y" && $(i+1) == "OK") {
! 158: i += 5
! 159: y += $i
! 160: tdata_y++
! 161: }
! 162: else if ($i == "Z" && $(i+1) == "OK") {
! 163: i += 5
! 164: z += $i
! 165: tdata_z++
! 166: }
! 167: }
! 168: continue
! 169: }
! 170: #
! 171: # select Austron ITF records
! 172: # see summary for decode
! 173: #
! 174: else if (NF >= 13 && $5 == "ITF" && $12 >= 100) {
! 175: itf_count++
! 176: if ($9 > 200e-9 || $9 < -200e-9)
! 177: itf_200++
! 178: else if ($9 > 100e-9 || $9 < -100e-9)
! 179: itf_100++
! 180: itf_mean += $9
! 181: itf_rms += $9 * $9
! 182: itf_var += $10 * $10
! 183: continue
! 184: }
! 185: #
! 186: # select Austron ETF records
! 187: # see summary for decode
! 188: #
! 189: else if (NF >= 13 && $5 == "ETF" && $13 >= 100) {
! 190: etf_count++
! 191: if ($6 > etf_max)
! 192: etf_max = $6
! 193: else if ($6 < etf_min)
! 194: etf_min = $6
! 195: etf_mean += $6
! 196: etf_rms += $6 * $6
! 197: etf_var += $9 * $9
! 198: continue
! 199: }
! 200: #
! 201: # select Austron TRSTAT records
! 202: # see summary for decode
! 203: #
! 204: else if (NF >= 5 && $5 == "TRSTAT") {
! 205: trstat_count++
! 206: j = 0
! 207: for (i = 6; i <= NF; i++)
! 208: if ($i == "T")
! 209: j++
! 210: trstat_sat[j]++
! 211: continue
! 212: }
! 213: #
! 214: # select Austron ID;OPT;VER records
! 215: #
! 216: # config GPS 2201A TTY1 TC1 LORAN IN OUT1 B.00 B.00 28-Apr-93
! 217: #
! 218: # GPS 2201A receiver model
! 219: # TTY1 rs232 moduel
! 220: # TC1 IRIG module
! 221: # LORAN LORAN assist module
! 222: # IN input module
! 223: # OUT1 output module
! 224: # B.00 B.00 firmware revision
! 225: # 28-Apr-9 firmware date3
! 226: #
! 227: else if (NF >= 5 && $5 == "ID;OPT;VER") {
! 228: id_count++
! 229: id_temp = ""
! 230: for (i = 6; i <= NF; i++)
! 231: id_temp = id_temp " " $i
! 232: if (id_string != id_temp)
! 233: printf "config%s\n", id_temp
! 234: id_string = id_temp
! 235: continue
! 236: }
! 237: #
! 238: # select Austron POS;PPS;PPSOFF records
! 239: #
! 240: # position +39:40:48.425 -075:45:02.392 +74.09 Stored UTC 0 200 0
! 241: #
! 242: # +39:40:48.425 position north latitude
! 243: # -075:45:02.392 position east longitude
! 244: # +74.09 elevation (meters)
! 245: # Stored position is stored
! 246: # UTC time is relative to UTC
! 247: # 0 200 0 PPS offsets
! 248: #
! 249: else if (NF >= 5 && $5 == "POS;PPS;PPSOFF") {
! 250: pos_count++
! 251: pos_temp = ""
! 252: for (i = 6; i <= NF; i++)
! 253: pos_temp = pos_temp " " $i
! 254: if (pos_string != pos_temp)
! 255: printf "position%s\n", pos_temp
! 256: pos_string = pos_temp
! 257: continue
! 258: }
! 259: #
! 260: # select Austron OSC;ET;TEMP records
! 261: #
! 262: # loop 1121 Software Control Locked
! 263: #
! 264: # 1121 oscillator type
! 265: # Software Control loop is under software control
! 266: # Locked loop is locked
! 267: #
! 268: else if (NF >= 5 && $5 == "OSC;ET;TEMP") {
! 269: osc_count++
! 270: osc_temp = $6 " " $7 " " $8 " " $9
! 271: if (osc_status != osc_temp)
! 272: printf "loop %s\n", osc_temp
! 273: osc_status = osc_temp
! 274: if ($10 > osc_vmax)
! 275: osc_vmax = $10
! 276: if ($10 < osc_vmin)
! 277: osc_vmin = $10
! 278: if ($11 > osc_tmax)
! 279: osc_tmax = $11
! 280: if ($11 < osc_tmin)
! 281: osc_tmin = $11
! 282: continue
! 283: }
! 284: #
! 285: # select Austron UTC records
! 286: # these ain't ready yet
! 287: #
! 288: else if (NF >= 5 && $5 == "UTC") {
! 289: utc_count++
! 290: utc_temp = ""
! 291: for (i = 6; i <= NF; i++)
! 292: utc_temp = utc_temp " " $i
! 293: if (utc_string != utc_temp)
! 294: # printf "utc%s\n", utc_temp
! 295: utc_string = utc_temp
! 296: continue
! 297: }
! 298: } END {
! 299: #
! 300: # PST/Traconex WWV summary data
! 301: #
! 302: if (wwv_wwv + wwv_wwvh > 0)
! 303: printf "wwv %d, wwvh %d, err %d, MHz (2.5) %d, (5) %d, (10) %d, (15) %d, (20) %d\n", wwv_wwv, wwv_wwvh, wwv_sync, wwv_2.5, wwv_5, wwv_10, wwv_15, wwv_20
! 304: #
! 305: # Arbiter 1088 summary data
! 306: #
! 307: # gps record count
! 308: # err error count
! 309: # sats(0-6) satellites tracked
! 310: # mean 1 PPS mean (us)
! 311: # rms 1 PPS rms error (us)
! 312: # var 1 PPS Allan variance
! 313: #
! 314: if (arb_count > 0) {
! 315: printf "gps %d, err %d, sats(0-6) %d %d %d %d %d %d %d", arb_count, arb_sync, arb_0, arb_1, arb_2, arb_3, arb_4, arb_5, arb_6
! 316: if (arbn > 1) {
! 317: arb_mean /= arbn
! 318: arb_rms = sqrt(arb_rms / arbn - arb_mean * arb_mean)
! 319: arb_var = sqrt(arb_var / (2 * (arbn - 1)))
! 320: printf ", mean %.2f, rms %.2f, var %.2e\n", arb_mean, arb_rms, arb_var * 1e-6
! 321: } else {
! 322: printf "\n"
! 323: }
! 324: }
! 325: #
! 326: # ensemble summary data
! 327: #
! 328: # ensemble record count
! 329: # badgps gps data unavailable
! 330: # badloran loran data unavailable
! 331: # rms ensemble rms error (ns)
! 332: # >200 ensemble error >200 ns
! 333: # >100 100 ns < ensemble error < 200 ns
! 334: #
! 335: if (ensemble_count > 0) {
! 336: ensemble_mean /= ensemble_count
! 337: ensemble_rms = sqrt(ensemble_rms / ensemble_count - ensemble_mean * ensemble_mean) * 1e9
! 338: printf "ensemble %d, badgps %d, badloran %d, rms %.1f, >200 %d, >100 %d\n", ensemble_count, ensemble_badgps, ensemble_badloran, ensemble_rms, ensemble_200, ensemble_100
! 339: }
! 340: #
! 341: # wwvb summary data
! 342: #
! 343: # wwvb record count
! 344: # ? unsynchronized
! 345: # >1 error > 1 ms
! 346: # >10 error > 10 ms
! 347: # >100 error > 100 ms
! 348: # >500 error > 500 ms
! 349: #
! 350: if (wwvb_count > 0)
! 351: printf "wwvb %d, ? %d, >1 %d, >10 %d, >100 %d, >500 %d\n", wwvb_count, wwvb_x, wwvb_a, wwvb_b, wwvb_c, wwvb_d
! 352: #
! 353: # irig summary data
! 354: #
! 355: # irig record count
! 356: # err error count
! 357: #
! 358: if (irig_count > 0)
! 359: printf "irig %d, err %d\n", irig_count, irig_error
! 360: #
! 361: # tdata summary data
! 362: #
! 363: # tdata record count
! 364: # m M master OK-count, mean level (dB)
! 365: # w W slave OK-count, mean level (dB)
! 366: # x X slave OK-count, mean level (dB)
! 367: # y Y slave OK-count, mean level (dB)
! 368: # z Z slave OK-count, mean level (dB)
! 369: #
! 370: if (tdata_count > 0 ) {
! 371: if (tdata_m > 0)
! 372: m /= tdata_count
! 373: if (tdata_x > 0)
! 374: w /= tdata_count
! 375: if (tdata_x > 0)
! 376: x /= tdata_count
! 377: if (tdata_y > 0)
! 378: y /= tdata_count
! 379: if (tdata_z > 0)
! 380: z /= tdata_count
! 381: printf "tdata %d, m %d %.1f, w %d %.1f, x %d %.1f, y %d %.1f, z %d %.1f\n", tdata_count, tdata_m, m, tdata_w, w, tdata_x, x, tdata_y, y, tdata_z, z
! 382: }
! 383: #
! 384: # itf summary data
! 385: #
! 386: # itf record count
! 387: # rms itf rms error (ns)
! 388: # >200 itf error > 200 ns
! 389: # >100 itf error > 100 ns
! 390: # var Allan variance
! 391: #
! 392: if (itf_count > 1) {
! 393: itf_mean /= itf_count
! 394: itf_rms = sqrt(itf_rms / itf_count - itf_mean * itf_mean) * 1e9
! 395: itf_var = sqrt(itf_var / (2 * (itf_count - 1)))
! 396: printf "itf %d, rms %.1f, >200 %d, >100 %d, var %.2e\n", itf_count, itf_rms, itf_200, itf_100, itf_var
! 397: }
! 398: #
! 399: # etf summary data
! 400: #
! 401: # etf record count
! 402: # mean etf mean (ns)
! 403: # rms etf rms error (ns)
! 404: # max etf maximum (ns)
! 405: # min etf minimum (ns)
! 406: # var Allan variance
! 407: #
! 408: if (etf_count > 0) {
! 409: etf_mean /= etf_count
! 410: etf_rms = sqrt(etf_rms / etf_count - etf_mean * etf_mean)
! 411: etf_var = sqrt(etf_var / (2 * (etf_count - 1)))
! 412: printf "etf %d, mean %.1f, rms %.1f, max %d, min %d, var %.2e\n", etf_count, etf_mean, etf_rms, etf_max, etf_min, etf_var
! 413: }
! 414: #
! 415: # trstat summary data
! 416: #
! 417: # trstat record count
! 418: # sat histogram of tracked satellites (0 - 7)
! 419: #
! 420: if (trstat_count > 0)
! 421: printf "trstat %d, sat %d %d %d %d %d %d %d %d\n", trstat_count, trstat_sat[0], trstat_sat[1], trstat_sat[2], trstat_sat[2], trstat_sat[3], trstat_sat[4], trstat_sat[5], trstat_sat[6], trstat_sat[7]
! 422: #
! 423: # osc summary data
! 424: #
! 425: # osc record count
! 426: # control control midrange (V) +/- deviation (mV)
! 427: # temp oven temperature midrange +/- deviation (deg C)
! 428: #
! 429: if (osc_count > 0)
! 430: printf "osc %d, control %.3f+/-%.3f, temp %.1f+/-%.2f\n", osc_count, (osc_vmax + osc_vmin) / 2, (osc_vmax - osc_vmin) / 2 * 1e3, (osc_tmax + osc_tmin) / 2, (osc_tmax - osc_tmin) / 2
! 431: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>