[Git][NTPsec/ntpsec][master] 2 commits: Add gps-log to log gpsd tdop and nSats. --local-gps to plot it.
Gary E. Miller
gitlab at mg.gitlab.com
Sat Sep 24 04:38:00 UTC 2016
Gary E. Miller pushed to branch master at NTPsec / ntpsec
Commits:
b4371828 by Gary E. Miller at 2016-09-23T19:52:35-07:00
Add gps-log to log gpsd tdop and nSats. --local-gps to plot it.
Not quite done, but working for me. gps-log logs the gpsd data for
tdop and nSats to a file. If the gpsd file exists then ntpviz
plots the data.
- - - - -
2bd0a3eb by Gary E. Miller at 2016-09-23T21:37:15-07:00
tdop is a bit more stable than I expected.
- - - - -
5 changed files:
- contrib/README
- + contrib/gps-log
- docs/includes/ntpviz-body.txt
- ntpstats/ntpviz
- pylib/statfiles.py
Changes:
=====================================
contrib/README
=====================================
--- a/contrib/README
+++ b/contrib/README
@@ -6,6 +6,9 @@ cpu-temp-log is a tool to use the output of 'sensors -u' and write the
motherboard temperatures to stdout. Useful to create a log that can be used
by 'ntpviz --local-temps'
+gps-log is a tool to log gpsd data and write the data to stdout. Useful
+to create a log that can be used by 'ntpviz --local-gps'
+
pi-temp-log for the Raspberry Pi. It is a tool to read a magic /sys file
to get the CPU temperature and write the temperatures to stdout. Useful
to create a log that can be used by 'ntpviz --local-temps'
=====================================
contrib/gps-log
=====================================
--- /dev/null
+++ b/contrib/gps-log
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+import os
+from gps import *
+import time
+from datetime import datetime
+import threading
+
+gpsd = None #seting the global variable
+
+class GpsPoller(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ global gpsd #bring it in scope
+ gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
+ self.current_value = None
+ self.running = True
+
+ def run(self):
+ global gpsd
+ while gpsp.running:
+ gpsd.next() # loop and grab each set of gpsd info
+
+if __name__ == '__main__':
+ gpsp = GpsPoller() # create the thread
+ try:
+ gpsp.start() # start it up
+ last_time = 0
+ print("# Time Device tdop nSat")
+ while True:
+ #It may take a second or two to get good data
+ #print gpsd.fix.latitude,', ',gpsd.fix.longitude,' Time: ',gpsd.utc
+
+ try:
+ if 'nan' != gpsd.fix.time and not isnan(gpsd.fix.time):
+ if last_time != gpsd.fix.time:
+ # new fix, log it.
+ print( '%s %s %f %d' % \
+ (isotime(gpsd.fix.time),
+ gpsd.device,
+ gpsd.tdop,
+ gpsd.satellites_used)
+ )
+ last_time = gpsd.fix.time
+ except AttributeError as e:
+ print( 'parse error\n')
+
+ sys.stdout.flush()
+ time.sleep(5) #set to whatever
+
+ except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
+ print "\nKilling Thread..."
+ except Exception as e: # any error, signal
+ print( e )
+
+ gpsp.running = False
+ gpsp.join() # wait for the thread to finish what it's doing
+ print "Done.\nExiting."
=====================================
docs/includes/ntpviz-body.txt
=====================================
--- a/docs/includes/ntpviz-body.txt
+++ b/docs/includes/ntpviz-body.txt
@@ -8,8 +8,9 @@
{ntpviz} [-d statsdir] [-g] [-n name] [-p period]
[-s starttime] [-e endtime]
[--local-offset | --local-error | --local-jitter | --local-stability]
- [ --all-peer-jitters
+ [ --all-peer-jitters
| --all-peer-offsets
+ | --local-gps
| --local-offset-histogram
| --local-offset-multiplot
| --local-temps
@@ -70,6 +71,11 @@ The following plots are available:
--local-jitter::
Clock time-jitter plot from the loop statistics (field 5).
+--local-gps::
+ Plot GPS Time Dilution of Precision (tdop) and Number of Sats Used
+ (nSats). This plot is only generated if there is a log file named
+ gpsd in the log file directory.
+
--local-offset::
Clock time and clock frequency offsets from the loop statistics
(fields 3 and 4).
=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -10,6 +10,7 @@ Usage: ntpviz [-d statsdir] [-g] [-n name] [-p days]
| --peer-offsets=hosts | --all-peer-offsets
| --peer-jitters=hosts | --all-peer-jitters
| --local-temps
+ | --local-gps
| --local-offset-multiplot]
[-o outdir]
[-D N]
@@ -190,6 +191,45 @@ plot \\
plot_template += plot_data
return plot_template
+ def local_gps_gnuplot(self):
+ "Generate GNUPLOT code graphing local gps statistics"
+ sitename = self.sitename
+ gpsmap = self.gpssplit()
+ gpslist = list(gpsmap.keys())
+ gpslist.sort()
+
+ if not len( gpsmap) or not len( gpslist):
+ sys.stderr.write("ntpviz: WARNING: no gps data to graph\n")
+ return ''
+
+ gps_data = ()
+ plot_data = ""
+ for key in gpslist:
+ d = "\n".join(gpsmap[key])
+ plot_data += d + "\ne\n" + d + "\ne\n"
+ # remove trailing "e\n"
+ plot_data = plot_data[:-2]
+
+ plot_template = NTPViz.Common + """\
+set title "%(sitename)s: Local GPS
+set ytics format "%%1.3f tdop" nomirror textcolor rgb '#0060ad'
+set y2tics format "%%2.0f nSat" nomirror textcolor rgb '#dd181f'
+set style line 1 lc rgb '#0060ad' lt 1 lw 1 pt 7 ps 0 # --- blue
+set style line 2 lc rgb '#dd181f' lt 1 lw 1 pt 5 ps 0 # --- red
+plot \\
+""" % locals()
+
+ for key in gpslist:
+ plot_template += """\
+'-' using 1:3 title '%(key)s tdop' with line, \\
+'-' using 1:4 title '%(key)s nSat' with line axis x1y2, \\
+""" % locals()
+
+ # strip the trailing ", \\n"
+ plot_template = plot_template[:-4] + "\n"
+ plot_template += plot_data
+ return plot_template
+
def local_error_gnuplot(self):
"Plot the local clock frequency error."
if not len( self.loopstats):
@@ -622,6 +662,7 @@ if __name__ == '__main__':
"all-peer-offsets", "peer-offsets=",
"all-peer-jitters", "peer-jitters=",
"local-temps",
+ "local-gps",
"local-offset-multiplot",
])
except getopt.GetoptError as err:
@@ -633,7 +674,7 @@ if __name__ == '__main__':
generate = False
show_local_offset = show_local_error = show_local_jitter = False
show_local_stability = show_local_offset_histogram = show_temps = False
- show_local_offset_multiplot = False
+ show_local_offset_multiplot = show_gps = False
show_peer_offsets = show_peer_jitters = None
outdir = "ntpgraphs"
debug_level = 0
@@ -677,6 +718,8 @@ if __name__ == '__main__':
show_peer_jitters = []
elif switch == "--local-temps":
show_temps = True
+ elif switch == "--local-gps":
+ show_gps = True
elif switch == "--local-offset-multiplot":
show_local_offset_multiplot = True
if 0 < debug_level:
@@ -773,6 +816,17 @@ if __name__ == '__main__':
sys.stdout.write(plot)
raise SystemExit(0)
+ if show_gps:
+ if not len( stats.gpsd):
+ sys.stderr.write("ntpviz: ERROR: missing gps data\n")
+ raise SystemExit(1)
+ plot = stats.local_gps_gnuplot()
+ if generate:
+ gnuplot(plot)
+ else:
+ sys.stdout.write(plot)
+ raise SystemExit(0)
+
if show_local_offset_multiplot:
plot = local_offset_multiplot(statlist)
if generate:
@@ -835,6 +889,10 @@ frequency. In other words, how fast it the local clock changes freqency.
This is field 6 in the loopstats log file.</p>
<p>Lower is better. An ideal clock would be a horizontal line at 0ppm.</p>
""",
+ "local-gps": """\
+<p>Local GPS. These will be site specific. It depends on running
+a local gpsd daemon, and logging the data using gps-log.py.</p>
+""",
"local-jitter": """\
<p>This shows the jitter of the local clock offset. In other words,
how fast the local clock offset is changing. This is field 5 in the
@@ -1037,6 +1095,7 @@ ntpviz</a>, part of the <a href="https://www.ntpsec.org/">NTPsec project</a>
("local-stability", stats.local_offset_stability_gnuplot()),
("local-offset-histogram", stats.local_offset_histogram_gnuplot()),
("local-temps", stats.local_temps_gnuplot()),
+ ("local-gps", stats.local_gps_gnuplot()),
("peer-offsets", stats.peer_offsets_gnuplot()),
]
=====================================
pylib/statfiles.py
=====================================
--- a/pylib/statfiles.py
+++ b/pylib/statfiles.py
@@ -63,7 +63,7 @@ class NTPStats:
raise SystemExit(1)
for stem in ("clockstats", "peerstats", "loopstats", "rawstats", \
- "temps"):
+ "temps", "gpsd"):
lines = []
try:
for logpart in glob.glob(os.path.join(statsdir, stem) + "*"):
@@ -80,14 +80,21 @@ class NTPStats:
pass
lines1 = []
- if stem == "temps":
- # temps is already in UNIX time
+ if stem == "temps" or stem == "gpsd":
+ # temps and gpsd are already in UNIX time
for line in lines:
line = line.strip(' \0\r\n\t')
if line is not None:
+ if 0 == len(line):
+ continue;
split = line.split(None, 2)
- if int(split[0]) >= starttime and \
- int(split[0]) <= endtime:
+ try:
+ t = int(float(split[0]))
+ except:
+ # ignore comment lines, lines with no time
+ continue
+
+ if starttime <= t <= endtime:
lines1.append( line)
else:
# Morph first field into Unix time with fractional seconds
@@ -153,6 +160,16 @@ class NTPStats:
self.peermap[ip].append(line)
return self.peermap
+ def gpssplit(self):
+ "Return a dictionary mapping gps sources to entry subsets."
+ gpsmap = {}
+ for line in self.gpsd:
+ source = line.split()[1]
+ if source not in gpsmap:
+ gpsmap[source] = []
+ gpsmap[source].append(line)
+ return gpsmap
+
def tempssplit(self):
"Return a dictionary mapping temperature sources to entry subsets."
tempsmap = {}
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/d776b0fad5809476e271386d8ddbfdeee4da852e...2bd0a3eb9d49f3ba33ef2a47ef6817d27c96150c
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20160924/0a7b25dc/attachment.html>
More information about the vc
mailing list