or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-parsing.mddepth-sonar.mdgps-positioning.mdindex.mdnavigation-course.mdproprietary-sentences.mdstream-processing.mdutilities.mdwind-weather.md
tile.json

tessl/pypi-pynmea2

Python library for parsing and generating NMEA 0183 protocol messages used in GPS and marine navigation systems

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pynmea2@1.19.x

To install, run

npx @tessl/cli install tessl/pypi-pynmea2@1.19.0

index.mddocs/

pynmea2

A comprehensive Python library for parsing and generating NMEA 0183 protocol messages commonly used in GPS and marine navigation systems. The library provides a clean API for parsing individual NMEA sentences into structured Python objects with easy access to GPS coordinates, timestamps, and other navigation data.

Package Information

  • Package Name: pynmea2
  • Language: Python
  • Installation: pip install pynmea2
  • Version: 1.19.0
  • License: MIT
  • Compatibility: Python 2.7 and Python 3.4+

Core Imports

import pynmea2

Import specific classes and functions:

from pynmea2 import (
    parse, NMEASentence, NMEAStreamReader, NMEAFile,
    ParseError, ChecksumError, SentenceTypeError
)

Import specific sentence types:

from pynmea2 import GGA, RMC, GSA, GSV  # GPS sentence types

Access version information:

import pynmea2
print(pynmea2.__version__)  # '1.19.0'
print(pynmea2.version)      # '1.19.0' (alias)

Basic Usage

import pynmea2

# Parse a single NMEA sentence
nmea_string = "$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D"
msg = pynmea2.parse(nmea_string)

# Access parsed data
print(f"Timestamp: {msg.timestamp}")           # datetime.time(18, 43, 53)
print(f"Latitude: {msg.latitude}")             # -19.4840833333 (decimal degrees)
print(f"Longitude: {msg.longitude}")           # 24.1751 (decimal degrees)
print(f"GPS Quality: {msg.gps_qual}")          # '1'
print(f"Satellites: {msg.num_sats}")           # '04'
print(f"Altitude: {msg.altitude}")             # 100.0

# Generate NMEA sentence from data
new_msg = pynmea2.GGA('GP', 'GGA', ('184353.07', '1929.045', 'S', '02410.506', 'E', '1', '04', '2.6', '100.00', 'M', '-33.9', 'M', '', '0000'))
print(str(new_msg))  # $GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D

Architecture

pynmea2 uses a class hierarchy with automatic sentence type detection and parsing:

  • NMEASentence: Base class for all NMEA sentences with parsing/rendering capabilities
  • TalkerSentence: Standard NMEA sentences (GPS, navigation, weather, etc.)
  • ProprietarySentence: Manufacturer-specific sentence extensions
  • QuerySentence: NMEA query sentences for requesting data
  • Utility Classes: Stream readers, file handlers, and coordinate conversion mixins

Capabilities

Core Parsing and Generation

Parse individual NMEA sentences into structured objects and generate NMEA strings from data.

def parse(line: str, check: bool = False) -> NMEASentence:
    """Parse NMEA sentence string into appropriate sentence object."""
class NMEASentence:
    def __init__(self):
        """Base class for all NMEA sentences."""
    
    @staticmethod
    def parse(line: str, check: bool = False) -> 'NMEASentence':
        """Parse NMEA sentence string."""
    
    @staticmethod  
    def checksum(nmea_str: str) -> int:
        """Calculate XOR checksum for NMEA string."""
    
    def render(self, checksum: bool = True, dollar: bool = True, newline: bool = False) -> str:
        """Render sentence as NMEA string."""

Core Parsing and Generation

GPS Positioning Sentences

Access GPS positioning data including latitude, longitude, altitude, and quality indicators.

class GGA(TalkerSentence):
    """Global Positioning System Fix Data."""
    timestamp: datetime.time
    lat: str
    lat_dir: str
    lon: str  
    lon_dir: str
    gps_qual: str
    num_sats: str
    horizontal_dil: str
    altitude: float
    altitude_units: str
    
    @property
    def latitude(self) -> float:
        """Latitude in decimal degrees."""
    
    @property
    def longitude(self) -> float:
        """Longitude in decimal degrees."""
    
    @property
    def is_valid(self) -> bool:
        """True if GPS quality indicates valid fix."""
class RMC(TalkerSentence):
    """Recommended Minimum Specific GPS/TRANSIT Data."""
    timestamp: datetime.time
    status: str
    lat: str
    lat_dir: str
    lon: str
    lon_dir: str
    spd_over_grnd: str
    true_course: str
    datestamp: datetime.date
    
    @property
    def latitude(self) -> float:
        """Latitude in decimal degrees."""
    
    @property
    def longitude(self) -> float:
        """Longitude in decimal degrees."""
    
    @property
    def datetime(self) -> datetime.datetime:
        """Combined date and time."""
    
    @property
    def is_valid(self) -> bool:
        """True if status and mode indicators are valid."""

GPS Positioning Sentences

Navigation and Course Sentences

Access navigation data including headings, bearings, waypoints, and course information.

class BWC(TalkerSentence):
    """Bearing & Distance to Waypoint - Great Circle."""
    timestamp: datetime.time
    lat_next: str
    lat_next_direction: str
    lon_next: str
    lon_next_direction: str
    true_track: str
    mag_track: str
    range_next: str
    waypoint_name: str
class HDG(TalkerSentence):
    """Heading, Deviation and Variation."""
    heading: str
    deviation: str
    dev_dir: str
    variation: str
    var_dir: str

Navigation and Course Sentences

Wind and Weather Sentences

Access meteorological data including wind speed, direction, temperature, and atmospheric conditions.

class MWV(TalkerSentence):
    """Wind Speed and Angle."""
    wind_angle: str
    reference: str
    wind_speed: str
    wind_speed_units: str
    status: str
    
    @property
    def is_valid(self) -> bool:
        """True if status indicates valid data."""
class MDA(TalkerSentence):
    """Meteorological Composite."""
    b_pressure_inch: str
    b_pressure_bar: str
    air_temp: str
    water_temp: str
    rel_humidity: str
    wind_speed_knots: str
    wind_speed_meters: str

Wind and Weather Sentences

Depth and Sonar Sentences

Access depth measurement data from various sonar and depth finding equipment.

class DBT(TalkerSentence):
    """Depth Below Transducer."""
    depth_feet: str
    unit_feet: str
    depth_meters: str
    unit_meters: str
    depth_fathoms: str
    unit_fathoms: str
class DPT(TalkerSentence):
    """Depth of Water."""
    depth: str
    offset: str
    range: str

Depth and Sonar Sentences

Stream Processing

Process continuous streams of NMEA data from files or serial connections.

class NMEAStreamReader:
    """Reads NMEA sentences from a stream."""
    
    def __init__(self, stream=None, errors: str = 'raise'):
        """
        Create NMEAStreamReader object.
        
        Args:
            stream: File-like object with readline() method
            errors: Error handling - 'raise', 'yield', or 'ignore'
        """
    
    def next(self, data: str = None) -> Iterator[NMEASentence]:
        """Parse data and yield NMEA sentence objects."""
    
    def __iter__(self) -> Iterator[List[NMEASentence]]:
        """Iterator protocol support."""
class NMEAFile:
    """File reader for NMEA sentences."""
    
    def __init__(self, f, *args, **kwargs):
        """Open NMEA file for reading."""
    
    def __iter__(self) -> Iterator[NMEASentence]:
        """Iterate through file yielding NMEA sentences."""
    
    def read(self) -> List[NMEASentence]:
        """Read all sentences as list."""
    
    def __enter__(self):
        """Context manager entry."""
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """Context manager exit."""

Stream Processing

Proprietary Sentences

Support for manufacturer-specific NMEA sentence extensions from GPS and marine equipment manufacturers.

class ProprietarySentence(NMEASentence):
    """Base class for proprietary manufacturer sentences."""
    manufacturer: str
    data: List[str]

Supported manufacturers include:

  • Ashtech (ASH): RT300 attitude, HPR heading/pitch/roll, position data
  • Garmin (GRM): Position error, map datum, waypoint information
  • u-blox (UBX): Position data, satellite status, time information
  • Trimble (TNL): AVR attitude, position fixes, VHD heading data
  • Nortek DVL (NOR): Bottom track, water track, current profile data

Proprietary Sentences

Utility Functions and Mixins

Helper functions for coordinate conversion, timestamp parsing, and validation.

def timestamp(s: str) -> datetime.time:
    """Convert HHMMSS[.ss] string to datetime.time object."""

def datestamp(s: str) -> datetime.date:
    """Convert DDMMYY string to datetime.date object."""

def dm_to_sd(dm: str) -> float:
    """Convert degrees/minutes format to signed decimal degrees."""

def valid(s: str) -> bool:
    """Check if status flag equals 'A' (active/valid)."""
class LatLonFix:
    """Mixin adding latitude/longitude properties as signed decimals."""
    
    @property
    def latitude(self) -> float:
        """Latitude in signed decimal degrees."""
    
    @property
    def longitude(self) -> float:
        """Longitude in signed decimal degrees."""
    
    @property
    def latitude_minutes(self) -> float:
        """Latitude minutes component."""
    
    @property
    def longitude_minutes(self) -> float:
        """Longitude minutes component."""

Utility Functions and Mixins

Exception Handling

class ParseError(ValueError):
    """
    Base exception for NMEA parsing errors.
    
    Args:
        message: Error description
        data: Raw data that caused the error
    """
    def __init__(self, message: str, data: str):
        """Initialize with error message and raw data."""

class ChecksumError(ParseError):
    """
    Raised when NMEA sentence checksum validation fails.
    
    Inherits message and data parameters from ParseError.
    """

class SentenceTypeError(ParseError):
    """
    Raised when sentence type is not recognized.
    
    Inherits message and data parameters from ParseError.
    """

All parsing exceptions include the error message and the raw data that caused the error for debugging purposes.

Types

from typing import List, Optional, Union, Iterator
from datetime import time, date, datetime

# Sentence data is stored as list of strings
SentenceData = List[str]

# Parse function can accept optional checksum validation
ChecksumValidation = bool