Question

I am working on nmea processing for gps trackers, where I am processing it as a list of values on this way

"""
information package exmaple
41719.285,A,1623.5136,S,07132.9184,W,017.8,203.5,040613,,,A*6B|1.6|2375|1010|0000,0000|02CC000A138E96D6|11|0029560C
"""
gprmc, hdop, altitude, state, ad, baseid, csq, journey = information.split('|')
ptime, gpsindicator, lttd, ns, lgtd, ew, speed, course, pdate, dd, checksum = gprmc.split(',')

Then, sometimes data packages are bigger, however are well formed, it is because some customers re-configure devices with extra data than they need and make my program crash, so I am looking for a way that my code doesn't crash in these cases.

Was it helpful?

Solution

use slices

gprmc, hdop, altitude, state, ad, baseid, csq, journey = information.split('|')[:8]
data = gprmc.split(',')
ptime, gpsindicator, lttd, ns, lgtd, ew, speed, course, pdate, dd = data[:10] 
checksum = data[-1] 

in python 3.x You can use wildcard

gprmc, hdop, altitude, state, ad, baseid, csq, journey, *_ = information.split('|')
(ptime, gpsindicator, lttd, ns, lgtd, 
 ew, speed, course, pdate, dd, *_, checksum) = gprmc.split(',')

OTHER TIPS

Your parser is to simple. If there is a "", after the last expected attribute then read exactly 2 characters after the "", which is the checksum. Correct it to read exactly 2 characters after "*".

Genereally NMEA is the only norm, but its is not well specified. Each GPS manuifacturer interpretes it in his own manner. Its very difficult to write a universal NMEA parser, you may look at GPSBable source code, and see what huge number of special cases for special receievers they consider.

Further the example you have given is invalid. A valid NMEA sentence starts with "$" as first character. e.g $GPRMC

A quick fix:

"""
information package exmaple
41719.285,A,1623.5136,S,07132.9184,W,017.8,203.5,040613,,,A*6B|1.6|2375|1010|0000,0000|02CC000A138E96D6|11|0029560C
"""
# Unpack only the eight first values to the eight variables
gprmc, hdop, altitude, state, ad, baseid, csq, journey = information.split('|')[:8]
# Unpack only the eleven first values to the eleven variables
ptime, gpsindicator, lttd, ns, lgtd, ew, speed, course, pdate, dd, checksum = gprmc.split(',')[:11] 

Of course a better approach is to check the validity of the informations and their count beforehand.

A bit of a side-answer, as I am somewhat wont to give...

If you are interested in effective GPS data (particularly NMEA 0183) parsing using Python, you may be interested in twisted.positioning: a branch I'm trying to land in twisted, which handles all the seriously gnarly stuff you need to do to get useful data out of a GPS device.

Alternatively, you may be interested in gpsd, to fill the same role. Eventually, twisted.positioning will get a gpsd provider, so that you can write the same code but have it fed data through gpsd. Or, if you're so inclined, you could get positioning data from other places -- the interface is quite general.

You could reference fields in a fixed manner such as:

inputStr = "a,b,c";
mylist = inputStr.split(',');
print mylist[0];

a

print mylist[len(mylist) - 1];

c

The "len(mylist) - 1" could pick off the checksum from the last field.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top