0
# pynmea2
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: pynmea2
7
- **Language**: Python
8
- **Installation**: `pip install pynmea2`
9
- **Version**: 1.19.0
10
- **License**: MIT
11
- **Compatibility**: Python 2.7 and Python 3.4+
12
13
## Core Imports
14
15
```python
16
import pynmea2
17
```
18
19
Import specific classes and functions:
20
21
```python
22
from pynmea2 import (
23
parse, NMEASentence, NMEAStreamReader, NMEAFile,
24
ParseError, ChecksumError, SentenceTypeError
25
)
26
```
27
28
Import specific sentence types:
29
30
```python
31
from pynmea2 import GGA, RMC, GSA, GSV # GPS sentence types
32
```
33
34
Access version information:
35
36
```python
37
import pynmea2
38
print(pynmea2.__version__) # '1.19.0'
39
print(pynmea2.version) # '1.19.0' (alias)
40
```
41
42
## Basic Usage
43
44
```python
45
import pynmea2
46
47
# Parse a single NMEA sentence
48
nmea_string = "$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D"
49
msg = pynmea2.parse(nmea_string)
50
51
# Access parsed data
52
print(f"Timestamp: {msg.timestamp}") # datetime.time(18, 43, 53)
53
print(f"Latitude: {msg.latitude}") # -19.4840833333 (decimal degrees)
54
print(f"Longitude: {msg.longitude}") # 24.1751 (decimal degrees)
55
print(f"GPS Quality: {msg.gps_qual}") # '1'
56
print(f"Satellites: {msg.num_sats}") # '04'
57
print(f"Altitude: {msg.altitude}") # 100.0
58
59
# Generate NMEA sentence from data
60
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'))
61
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
62
```
63
64
## Architecture
65
66
pynmea2 uses a class hierarchy with automatic sentence type detection and parsing:
67
68
- **NMEASentence**: Base class for all NMEA sentences with parsing/rendering capabilities
69
- **TalkerSentence**: Standard NMEA sentences (GPS, navigation, weather, etc.)
70
- **ProprietarySentence**: Manufacturer-specific sentence extensions
71
- **QuerySentence**: NMEA query sentences for requesting data
72
- **Utility Classes**: Stream readers, file handlers, and coordinate conversion mixins
73
74
## Capabilities
75
76
### Core Parsing and Generation
77
78
Parse individual NMEA sentences into structured objects and generate NMEA strings from data.
79
80
```python { .api }
81
def parse(line: str, check: bool = False) -> NMEASentence:
82
"""Parse NMEA sentence string into appropriate sentence object."""
83
```
84
85
```python { .api }
86
class NMEASentence:
87
def __init__(self):
88
"""Base class for all NMEA sentences."""
89
90
@staticmethod
91
def parse(line: str, check: bool = False) -> 'NMEASentence':
92
"""Parse NMEA sentence string."""
93
94
@staticmethod
95
def checksum(nmea_str: str) -> int:
96
"""Calculate XOR checksum for NMEA string."""
97
98
def render(self, checksum: bool = True, dollar: bool = True, newline: bool = False) -> str:
99
"""Render sentence as NMEA string."""
100
```
101
102
[Core Parsing and Generation](./core-parsing.md)
103
104
### GPS Positioning Sentences
105
106
Access GPS positioning data including latitude, longitude, altitude, and quality indicators.
107
108
```python { .api }
109
class GGA(TalkerSentence):
110
"""Global Positioning System Fix Data."""
111
timestamp: datetime.time
112
lat: str
113
lat_dir: str
114
lon: str
115
lon_dir: str
116
gps_qual: str
117
num_sats: str
118
horizontal_dil: str
119
altitude: float
120
altitude_units: str
121
122
@property
123
def latitude(self) -> float:
124
"""Latitude in decimal degrees."""
125
126
@property
127
def longitude(self) -> float:
128
"""Longitude in decimal degrees."""
129
130
@property
131
def is_valid(self) -> bool:
132
"""True if GPS quality indicates valid fix."""
133
```
134
135
```python { .api }
136
class RMC(TalkerSentence):
137
"""Recommended Minimum Specific GPS/TRANSIT Data."""
138
timestamp: datetime.time
139
status: str
140
lat: str
141
lat_dir: str
142
lon: str
143
lon_dir: str
144
spd_over_grnd: str
145
true_course: str
146
datestamp: datetime.date
147
148
@property
149
def latitude(self) -> float:
150
"""Latitude in decimal degrees."""
151
152
@property
153
def longitude(self) -> float:
154
"""Longitude in decimal degrees."""
155
156
@property
157
def datetime(self) -> datetime.datetime:
158
"""Combined date and time."""
159
160
@property
161
def is_valid(self) -> bool:
162
"""True if status and mode indicators are valid."""
163
```
164
165
[GPS Positioning Sentences](./gps-positioning.md)
166
167
### Navigation and Course Sentences
168
169
Access navigation data including headings, bearings, waypoints, and course information.
170
171
```python { .api }
172
class BWC(TalkerSentence):
173
"""Bearing & Distance to Waypoint - Great Circle."""
174
timestamp: datetime.time
175
lat_next: str
176
lat_next_direction: str
177
lon_next: str
178
lon_next_direction: str
179
true_track: str
180
mag_track: str
181
range_next: str
182
waypoint_name: str
183
```
184
185
```python { .api }
186
class HDG(TalkerSentence):
187
"""Heading, Deviation and Variation."""
188
heading: str
189
deviation: str
190
dev_dir: str
191
variation: str
192
var_dir: str
193
```
194
195
[Navigation and Course Sentences](./navigation-course.md)
196
197
### Wind and Weather Sentences
198
199
Access meteorological data including wind speed, direction, temperature, and atmospheric conditions.
200
201
```python { .api }
202
class MWV(TalkerSentence):
203
"""Wind Speed and Angle."""
204
wind_angle: str
205
reference: str
206
wind_speed: str
207
wind_speed_units: str
208
status: str
209
210
@property
211
def is_valid(self) -> bool:
212
"""True if status indicates valid data."""
213
```
214
215
```python { .api }
216
class MDA(TalkerSentence):
217
"""Meteorological Composite."""
218
b_pressure_inch: str
219
b_pressure_bar: str
220
air_temp: str
221
water_temp: str
222
rel_humidity: str
223
wind_speed_knots: str
224
wind_speed_meters: str
225
```
226
227
[Wind and Weather Sentences](./wind-weather.md)
228
229
### Depth and Sonar Sentences
230
231
Access depth measurement data from various sonar and depth finding equipment.
232
233
```python { .api }
234
class DBT(TalkerSentence):
235
"""Depth Below Transducer."""
236
depth_feet: str
237
unit_feet: str
238
depth_meters: str
239
unit_meters: str
240
depth_fathoms: str
241
unit_fathoms: str
242
```
243
244
```python { .api }
245
class DPT(TalkerSentence):
246
"""Depth of Water."""
247
depth: str
248
offset: str
249
range: str
250
```
251
252
[Depth and Sonar Sentences](./depth-sonar.md)
253
254
### Stream Processing
255
256
Process continuous streams of NMEA data from files or serial connections.
257
258
```python { .api }
259
class NMEAStreamReader:
260
"""Reads NMEA sentences from a stream."""
261
262
def __init__(self, stream=None, errors: str = 'raise'):
263
"""
264
Create NMEAStreamReader object.
265
266
Args:
267
stream: File-like object with readline() method
268
errors: Error handling - 'raise', 'yield', or 'ignore'
269
"""
270
271
def next(self, data: str = None) -> Iterator[NMEASentence]:
272
"""Parse data and yield NMEA sentence objects."""
273
274
def __iter__(self) -> Iterator[List[NMEASentence]]:
275
"""Iterator protocol support."""
276
```
277
278
```python { .api }
279
class NMEAFile:
280
"""File reader for NMEA sentences."""
281
282
def __init__(self, f, *args, **kwargs):
283
"""Open NMEA file for reading."""
284
285
def __iter__(self) -> Iterator[NMEASentence]:
286
"""Iterate through file yielding NMEA sentences."""
287
288
def read(self) -> List[NMEASentence]:
289
"""Read all sentences as list."""
290
291
def __enter__(self):
292
"""Context manager entry."""
293
294
def __exit__(self, exc_type, exc_val, exc_tb):
295
"""Context manager exit."""
296
```
297
298
[Stream Processing](./stream-processing.md)
299
300
### Proprietary Sentences
301
302
Support for manufacturer-specific NMEA sentence extensions from GPS and marine equipment manufacturers.
303
304
```python { .api }
305
class ProprietarySentence(NMEASentence):
306
"""Base class for proprietary manufacturer sentences."""
307
manufacturer: str
308
data: List[str]
309
```
310
311
Supported manufacturers include:
312
- **Ashtech (ASH)**: RT300 attitude, HPR heading/pitch/roll, position data
313
- **Garmin (GRM)**: Position error, map datum, waypoint information
314
- **u-blox (UBX)**: Position data, satellite status, time information
315
- **Trimble (TNL)**: AVR attitude, position fixes, VHD heading data
316
- **Nortek DVL (NOR)**: Bottom track, water track, current profile data
317
318
[Proprietary Sentences](./proprietary-sentences.md)
319
320
### Utility Functions and Mixins
321
322
Helper functions for coordinate conversion, timestamp parsing, and validation.
323
324
```python { .api }
325
def timestamp(s: str) -> datetime.time:
326
"""Convert HHMMSS[.ss] string to datetime.time object."""
327
328
def datestamp(s: str) -> datetime.date:
329
"""Convert DDMMYY string to datetime.date object."""
330
331
def dm_to_sd(dm: str) -> float:
332
"""Convert degrees/minutes format to signed decimal degrees."""
333
334
def valid(s: str) -> bool:
335
"""Check if status flag equals 'A' (active/valid)."""
336
```
337
338
```python { .api }
339
class LatLonFix:
340
"""Mixin adding latitude/longitude properties as signed decimals."""
341
342
@property
343
def latitude(self) -> float:
344
"""Latitude in signed decimal degrees."""
345
346
@property
347
def longitude(self) -> float:
348
"""Longitude in signed decimal degrees."""
349
350
@property
351
def latitude_minutes(self) -> float:
352
"""Latitude minutes component."""
353
354
@property
355
def longitude_minutes(self) -> float:
356
"""Longitude minutes component."""
357
```
358
359
[Utility Functions and Mixins](./utilities.md)
360
361
## Exception Handling
362
363
```python { .api }
364
class ParseError(ValueError):
365
"""
366
Base exception for NMEA parsing errors.
367
368
Args:
369
message: Error description
370
data: Raw data that caused the error
371
"""
372
def __init__(self, message: str, data: str):
373
"""Initialize with error message and raw data."""
374
375
class ChecksumError(ParseError):
376
"""
377
Raised when NMEA sentence checksum validation fails.
378
379
Inherits message and data parameters from ParseError.
380
"""
381
382
class SentenceTypeError(ParseError):
383
"""
384
Raised when sentence type is not recognized.
385
386
Inherits message and data parameters from ParseError.
387
"""
388
```
389
390
All parsing exceptions include the error message and the raw data that caused the error for debugging purposes.
391
392
## Types
393
394
```python { .api }
395
from typing import List, Optional, Union, Iterator
396
from datetime import time, date, datetime
397
398
# Sentence data is stored as list of strings
399
SentenceData = List[str]
400
401
# Parse function can accept optional checksum validation
402
ChecksumValidation = bool
403
```