#!/usr/lib/python3
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 fileencoding=utf-8 :
import datetime, operator, functools, pprint, serial
class InvalidSentence(Exception):
pass
class InvalidChecksum(Exception):
pass
class Nmea:
nmeadict = {}
nmeadict['sat'] = []
def __init__(self):
pass
def getchecksum(self, message):
return(functools
.reduce
(operator
.xor
, map
(ord, message
)))
def parse(self, nmeastring):
if not nmeastring.startswith('$'):
raise InvalidSentence
message
, checksum
= nmeastring
[1:].strip
().split('*')
calculated_checksum = self.getchecksum(message)
checksum = int(checksum, 16)
if checksum != calculated_checksum:
raise InvalidChecksum("Transmitted checksum {} doesn't match "
"calculated checksum {}".format(checksum,
calculated_checksum))
elems
= message
.split(',')
nmeatype = elems[0]
if nmeatype == 'GPGGA':
fields = [
'time',
'latitude',
'lat_dir',
'longitude',
'lon_dir',
'quality',
'satcount',
'hdop',
'altitude',
'altitude_unit',
'geoid_height',
'geoid_height_unit',
'dgps_timedelta',
'dgps_stationid',
]
elif nmeatype == 'GPGSA':
fields = None
self.nmeadict['manual_auto'] = elems[1]
self.nmeadict['2D_3D'] = elems[2]
self.nmeadict['pdop'] = elems[15]
self.nmeadict['vdop'] = elems[16]
self.nmeadict['hdop'] = elems[17]
self.nmeadict['sat_ids'] = []
for e in elems[2:15]:
self.nmeadict['sat_ids'].append(e)
elif nmeatype == 'GPGLL':
fields = [
'latitude',
'lat_dir',
'longitude',
'lon_dir',
'time',
'validity',
]
elif nmeatype == 'GPZDA':
fields = [
'utc',
'day',
'month',
'year',
'timezone_h',
'timezone_min'
]
elif nmeatype == 'GPRMC':
fields = [
'time',
'validity',
'latitude',
'lat_dir',
'longitude',
'lon_dir',
'speed',
'course',
'date',
'magnetic_var',
'magnetic_var_dir',
]
elif nmeatype == 'GPGSV':
# Beware, dragons ahead!
fields = None # We don't want this to be parsed the default way
self.nmeadict['total_sv'] = elems[3] # Total sats in view
i = int(elems[2])-1 # message id (0..n)
if i == 0: # first message
self.nmeadict['sat'] = [] # clear the old SVs
# 3 global elements, after that 4 per satelite
sv_cnt = (len(elems) - 3) // 4
for sv_num in
range(0, sv_cnt
-1): # for each sat in the msg
satdict = {
'sv_prn': elems[4+(sv_num*4)], # Fields 4/8/12/16
'elevation': elems[5+(sv_num*4)], # Fields 5/9/13/17
'azimuth': elems[6+(sv_num*4)], # Fields 6/10/14/18
'snr': elems[7+(sv_num*4)], # Fields 7/11/15/19
}
# Append the sats to the nmeadict
self.nmeadict['sat'].append(satdict)
else:
fields = None
if fields is not None:
for elem in enumerate(elems[1:]):
i = elem[0]
if len(fields) > i:
fieldname = fields[i]
self.nmeadict[fieldname] = elem[1]
ser = serial.Serial("/dev/ttyACM0")
foo = Nmea()
pp = pprint.PrettyPrinter()
while True:
line = ser.readline()
try:
line = line.decode('ASCII')
except UnicodeDecodeError:
pass
else:
foo.parse(line)
print(chr(27) + "[2J") # Clear screen
print("\x1b[2J\x1b[H") # Return cursor
# pp.pprint(foo.nmeadict)
pprint.pprint(foo.nmeadict)
{"text":"text","html5":"html","css":"css","javascript":"javascript","php":"php","python":"python","ruby":"ruby","lua":"lua","bash":"sh","erlang":"erlang","go":"golang","c":"c_cpp","cpp":"c_cpp","diff":"diff","latex":"latex","sql":"sql","xml":"xml","0":"text","abap":"abap","actionscript":"actionscript","actionscript3":"actionscript","ada":"ada","apache":"apache_conf","applescript":"applescript","asm":"assembly_x86","autohotkey":"autohotkey","closure":"closure","cobol":"cobol","coffeescript":"coffee","cpp-winapi":"c_cpp","c_loadrunner":"c_cpp","c_mac":"c_cpp","c_winapi":"c_cpp","csharp":"csharp","d":"d","dart":"dart","dot":"dot","eiffel":"eiffel","fortran":"fortran","groovy":"groovy","haskell":"haskell","haxe":"haxe","ini":"ini","io":"io","java":"java","java5":"java","make":"makefile","matlab":"matlab","mysql":"mysql","objc":"objectivec","ocaml":"ocaml","pascal":"pascal","perl":"perl","perl6":"perl","postgresql":"pgsql","powershell":"powershell","prolog":"prolog","properties":"properties","rails":"ruby","rust":"rust","scala":"scala","scheme":"scheme","smarty":"smarty","tcl":"tcl","vala":"vala","vb":"vbscript","verilog":"verilog","vhdl":"vhdl","yaml":"yaml"}