PageRenderTime 35ms CodeModel.GetById 15ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/ntp/scripts/stats/clock.awk

https://bitbucket.org/freebsd/freebsd-head/
AWK | 431 lines | 257 code | 0 blank | 174 comment | 0 complexity | bd4ebb0b8cd436341b5cd1795f5e5323 MD5 | raw file
  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#
 12BEGIN {
 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}