Build (potentially useless) NMEA data from MOTOACTV downloaded CSV file:
Acknowledgement: thanks to Beni Hess' comment on a Python Recipe post for saving me days of trying to figure out the XORs for the checksums.
Also, this NMEA reference from Robosoft proved helpful in building the sentences.
Updated below, now that all the calculations are set up as functions. Final version is posted here.
Also, this NMEA reference from Robosoft proved helpful in building the sentences.
Updated below, now that all the calculations are set up as functions. Final version is posted here.
#!/usr/bin/env pythonimport csv, time, math, operatorfilename = "rawDataCsv.csv"# filename = "miniDataCsv.csv"# Recorded epoch is GMT, staticly setting this to CDT for nowTZoffset_hours = int(-5)# Living without minute offsets and assuming zeroTZoffset_string = str(TZoffset_hours) + ",00"# Function to generate time (to the second, with truncated hundredths -- close enough) and date from the recorded timestampdef Epoch2DateTimeStrings(epoch):noms_epoch = str(epoch)[:-3]just_ms = str(epoch)[-3:]cut_epoch = float(noms_epoch)HHMMSS = time.strftime("%H%M%S",time.gmtime(cut_epoch))DDMMYYYY = time.strftime("%d,%m,%Y",time.gmtime(cut_epoch))hundredths = str(just_ms)[:2]time_string = str(HHMMSS) + "." + hundredthsdate_string = str(DDMMYYYY)return (date_string, time_string)# Function to determine the cardinality of a coordinate (lat/long), based on its sign (+/-)def Cardinality(coordinate, latlong):if latlong == "longitude":if coordinate < 0: cardinality = "W"else: cardinality = "E"elif latlong == "latitude":if coordinate < 0: cardinality = "S"else: cardinality = "N"return cardinality# Function to convert a coordinate (lat/long) from decimal degrees to degrees and decimal minutesdef Deg2DegMin(coordinate):coord = math.modf(math.fabs(coordinate))coord_deg = int(coord[1])coord_min = float(coord[0] * 60)return (coord_deg, coord_min)# Function to convert Latitude and Longitude to NMEA GLL formatdef LatLong2Strings (latitude, longitude):latitude_direction = Cardinality(latitude, "latitude")longitude_direction = Cardinality(longitude, "longitude")# Latitudedeg_lat, min_lat = Deg2DegMin(latitude)deg_lat = str(deg_lat)min_lat = str("%.4f" % min_lat)lat_string = deg_lat + min_lat + "," + latitude_direction + ","# Longitudedeg_long, min_long = Deg2DegMin(longitude_decdeg)deg_long = str(deg_long)min_long = str("%.4f" % min_long)long_string = deg_long + min_long + "," + longitude_direction + ","# Return the stringsreturn (lat_string, long_string)def BuildNMEA(lat_string, long_string, time_string, date_string, TZoffset_string):# Concatenate the pieces into the sections of the NMEA GLL and ZDA sentences that get checksummed (omit the leading $ and trailing *ck)gpgll_string = str("GPGLL," + lat_string + long_string + time_string + ",A")gpzda_string = str("GPZDA," + time_string + "," + date_string + "," + TZoffset_string)# Calculate the checksums (just in case)GLL_checksum = reduce(operator.xor, (ord(c) for c in gpgll_string), 0)ZDA_checksum = reduce(operator.xor, (ord(c) for c in gpzda_string), 0)# Convert to Hex (no 0x) and pad a leading zero if neededGLL_hex = ("%X" % GLL_checksum).zfill(2)ZDA_hex = ("%X" % ZDA_checksum).zfill(2)# Now, put it all together into a full NMEA GLL and ZDA sentences and render themNMEA_GLL_sentence = str("$" + gpgll_string + "*" + GLL_hex)NMEA_ZDA_sentence = str("$" + gpzda_string + "*" + ZDA_hex)# Return the sentencesreturn (NMEA_ZDA_sentence, NMEA_GLL_sentence)ACTVdatafile = open(filename,"rb")ACTVdata = csv.reader(ACTVdatafile)rowindex = 0for row in ACTVdata:# Don't try to grok the heading row from the CSV fileif rowindex == 0: pass# Build NMEA sentences from every other rowelse:latitude_decdeg = float(row[5])ms_epoch = row[9]longitude_decdeg = float(row[15])date_string, time_string = Epoch2DateTimeStrings(ms_epoch)lat_string, long_string = LatLong2Strings(latitude_decdeg, longitude_decdeg)NMEA_ZDA, NMEA_GLL = BuildNMEA(lat_string, long_string, time_string, date_string, TZoffset_string)print NMEA_ZDAprint NMEA_GLLrowindex += 1ACTVdatafile.close()