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>