pynmea2 NMEA 0183 Protocol Parser
pynmea2 is a Python library for parsing and creating NMEA 0183 sentences, commonly used in GPS and other GNSS receivers. It provides a flexible API for working with various NMEA sentence types, handling checksums, and accessing data fields. The current version is 1.19.0, with a release cadence of several updates per year, primarily for bug fixes and new sentence type support.
Common errors
-
pynmea2.ChecksumError: Checksum doesn't match
cause The NMEA sentence provided to `pynmea2.parse()` has an incorrect or missing checksum.fixVerify the integrity of your NMEA data source. If you're generating sentences, ensure the checksum is calculated correctly. For parsing, wrap `pynmea2.parse()` in a `try-except pynmea2.ChecksumError` block to handle bad data, or consider disabling checksum validation if data integrity is not paramount (e.g., `pynmea2.parse(data, checksum=False)`). -
pynmea2.ParseError: sentence did not start with '$' or '!'
cause The input string passed to `pynmea2.parse()` does not begin with the standard NMEA start character (`$` or `!`), indicating it's not a valid NMEA sentence or it's part of a larger string.fixPre-process your input data to extract only the raw NMEA sentence, ensuring it starts with `$` or `!` and includes the full sentence up to the checksum and newline. This often involves buffering and line-splitting when reading from a stream. -
AttributeError: 'RMC' object has no attribute 'some_invalid_field'
cause You are trying to access a field that does not exist for the specific NMEA sentence type (e.g., trying to get 'altitude' from an RMC sentence, which doesn't have it).fixConsult the NMEA 0183 specification or the `pynmea2` documentation for the fields available for each sentence type. Use `msg.sentence_type` to dynamically determine the type and access fields conditionally.
Warnings
- gotcha `pynmea2.parse()` performs checksum validation by default. If your NMEA sentences have invalid or missing checksums, it will raise a `pynmea2.ChecksumError`.
- gotcha When receiving NMEA data from a stream (e.g., serial port, socket), you often receive incomplete lines. `pynmea2.parse()` expects a complete NMEA sentence starting with `$` or `!` and ending with a newline, including the checksum.
- gotcha NMEA sentences have fixed fields, and attempting to access a non-existent field (e.g., `msg.speed` on a GGA sentence) will result in an `AttributeError`.
Install
-
pip install pynmea2
Imports
- parse
import pynmea2 msg = pynmea2.parse('$GPGGA,...') - GGA
from pynmea2.types.talker import GGA
from pynmea2 import GGA msg = GGA('GP', 'GGA', (...)) - ChecksumError
from pynmea2 import ChecksumError
- ParseError
from pynmea2 import ParseError
Quickstart
import pynmea2
import datetime
# Example 1: Parsing an NMEA sentence
raw_gga = '$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D'
try:
msg = pynmea2.parse(raw_gga)
print(f"Parsed sentence type: {msg.sentence_type}")
print(f"Timestamp: {msg.timestamp}")
print(f"Latitude: {msg.latitude}, Longitude: {msg.longitude}")
except pynmea2.ChecksumError as e:
print(f"Checksum error: {e}")
except pynmea2.ParseError as e:
print(f"Parse error: {e}")
# Example 2: Creating an NMEA sentence
# GGA fields: (timestamp, lat, lat_dir, lon, lon_dir, fix_quality, num_sats, hdop, alt, alt_units, geoid_sep, geoid_units, age_of_diff, diff_ref_id)
# Note: lat/lon can be floats, others mostly strings/ints
timestamp_val = datetime.time(12, 0, 0)
lat_val = '3404.70417'
lat_dir_val = 'N'
lon_val = '11808.66539'
lon_dir_val = 'W'
try:
new_gga = pynmea2.GGA('GP', 'GGA', (
timestamp_val, lat_val, lat_dir_val, lon_val, lon_dir_val,
1, 8, 0.9, 500.0, 'M', 25.0, 'M', '', ''
))
print(f"\nCreated NMEA sentence: {str(new_gga)}")
except ValueError as e:
print(f"Error creating GGA sentence: {e}")