Annotation of embedaddon/ntp/scripts/stats/clock.awk, revision 1.1.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>