Petrichor-Labs / nmea_data_convert

Convert NMEA data to CSV files, or import NMEA data to PostgreSQL database
13 stars 3 forks source link
csv csv-export database gps gps-data nmea nmea-0183 nmea-csv nmea-parser nmea-parsing-library nmea-postgres nmea-postgresql nmea-sentences nmea0183 postgres postgresql pynmea pynmea2

This library makes use of pynmea2 to parse through input NMEA 0183 data, organize it, and output it to CSV files or to a PostgreSQL database.

Table of Contents

  1. Terminology
  2. Setup
  3. Usage
  4. Examples
  5. Development Notes and Oddities
  6. Helpful References
  7. Grafana
  8. Discussion

Support

If you find this tool useful, please consider supporting its development and the development of other tools like it. You can support us financially using the Sponsor button at the top of the GitHub page.

Terminology

Setup

Input data files can contain either sentences having all the same talker+sentence_type, like that of test_data/test_data_0_GLGSV.nmea, test_data_0_GNGGA.nmea, etc., or cycles of sentences like that of test_data/test_data_0_all.nmea. Your input file should have a format similiar to those under test_data.

To have your data datetime stamped, it must be in a format like that of test_data/test_data_0_all.nmea, with RMC sentences containing date and time stamps proceeding other sentences in the same cycle.

Usage of the cycle_start (cs), num_sentences_per_cycle (spc), and backfill_datetimes (bfdt) parameters will depend on the format of your data, and some combination of them is required. See below for examples. See the Usage section for explanations of the parameters.

To import data to a Postgres database, have the database server installed and running where desired. The database access information/credentials must be setup in db_creds.py.

Usage

$ cd nmea_data_convert/
$ pip install -r requirements.txt 
...
$ python nmea_data_convert.py --help
usage: nmea_data_convert.py [-h] [--cycle_start CYCLE_START] [--num_sentences_per_cycle NUM_SENTENCES_PER_CYCLE] [--backfill_datetimes] [--drop_previous_db_tables] filepath {csv,db,both}

positional arguments:
  filepath              file system path to file containing NMEA data
  {csv,db,both}         where to output data: CSV files, database, or both

optional arguments:
  -h, --help            show this help message and exit
  --cycle_start CYCLE_START, -cs CYCLE_START
                        talker+sentence_type, e.g. 'GNRMC'; used to key off of for sentence merging, and more; must appear once and only once in each cycle, and must be at the beginning of each cycle; must contain date and time information for sentences to be datetime
                        stamped
  --num_sentences_per_cycle NUM_SENTENCES_PER_CYCLE, -spc NUM_SENTENCES_PER_CYCLE
                        If the cycle_start argument is not provided, and sentences are not all of type GSV, cycles will be inferred from this argument. Every num_sentences_per_cycle will be given the same cycle_id starting with the first sentence. Sentence merging is
                        based on cycle_id.
  --backfill_datetimes, -bfdt
                        backfill datetimes where missing by extrapolating from messages with datetime information
  --drop_previous_db_tables, -dropt
                        drop all previous DB tables before importing new data; only applies when output_method is 'db' or 'both'

Examples

Example 1

Output cycles of NMEA sentences to CSV files using GNRMC sentences as the cycle start:

$ ls -l *.csv
ls: *.csv: No such file or directory
$ python nmea_data_convert.py test_data/test_data_0_all.nmea csv -cs GNRMC

Reading in data... done.

Processing data... done.

Writing data to CSVs... data from logfile 'test_data/test_data_0_all.nmea' written to:
  test_data_0_all_GNRMC.csv
  test_data_0_all_GNVTG.csv
  test_data_0_all_GNGGA.csv
  test_data_0_all_GNGSA.csv
  test_data_0_all_GPGSV.csv
  test_data_0_all_GLGSV.csv
  test_data_0_all_GNGLL.csv
done.

All done. Exiting.

MacBook-Pro-4:nmea_data_convert Thomas$ ls -l *.csv
-rw-r--r--  1 Thomas  staff  16166 Jan 17 16:55 test_data_0_all_GLGSV.csv
-rw-r--r--  1 Thomas  staff  12067 Jan 17 16:55 test_data_0_all_GNGGA.csv
-rw-r--r--  1 Thomas  staff   9401 Jan 17 16:55 test_data_0_all_GNGLL.csv
-rw-r--r--  1 Thomas  staff  14136 Jan 17 16:55 test_data_0_all_GNGSA.csv
-rw-r--r--  1 Thomas  staff  12536 Jan 17 16:55 test_data_0_all_GNRMC.csv
-rw-r--r--  1 Thomas  staff   8344 Jan 17 16:55 test_data_0_all_GNVTG.csv
-rw-r--r--  1 Thomas  staff  20698 Jan 17 16:55 test_data_0_all_GPGSV.csv

Example 2

Output cycles of NMEA sentences to both CSV files and database using GNRMC sentences as the cycle start, backfill datetimes, and drop previous tables from database:

$ python nmea_data_convert.py test_data/test_data_0_all.nmea both -bfdt -dropt -cs GNRMC

Reading in data... done.

Processing data... done.

Writing data to CSVs... data from logfile 'test_data/test_data_0_all.nmea' written to:
  test_data_0_all_GNRMC.csv
  test_data_0_all_GNVTG.csv
  test_data_0_all_GNGGA.csv
  test_data_0_all_GNGSA.csv
  test_data_0_all_GPGSV.csv
  test_data_0_all_GLGSV.csv
  test_data_0_all_GNGLL.csv
done.

Dropping database table nmea_gl_gsv (and any dependent objects) if it exists.
Dropping database table nmea_gn_gga (and any dependent objects) if it exists.
Dropping database table nmea_gn_gll (and any dependent objects) if it exists.
Dropping database table nmea_gn_gsa (and any dependent objects) if it exists.
Dropping database table nmea_gn_rmc (and any dependent objects) if it exists.
Dropping database table nmea_gn_vtg (and any dependent objects) if it exists.
Dropping database table nmea_gp_gsv (and any dependent objects) if it exists.

Writing data to database... data from logfile 'test_data/test_data_0_all.nmea' written to:
  'nmea_gn_rmc' table in 'nmea_data' database
  'nmea_gn_vtg' table in 'nmea_data' database
  'nmea_gn_gga' table in 'nmea_data' database
  'nmea_gn_gsa' table in 'nmea_data' database
  'nmea_gp_gsv' table in 'nmea_data' database
  'nmea_gl_gsv' table in 'nmea_data' database
  'nmea_gn_gll' table in 'nmea_data' database
done.

All done. Exiting.

Example 3

Convert sentences, all of the same talker+sentence_type, to database:

$ python nmea_data_convert.py test_data/test_data_0_GNVTG.nmea db -spc 1

Reading in data... done.

Processing data... done.

Writing data to database... data from logfile 'test_data/test_data_0_GNVTG.nmea' written to:
  'nmea_gn_vtg' table in 'nmea_data' database
done.

All done. Exiting.

Example 4

Convert GSV sentences, all of the same talker, to database, where there may sometimes be multiple messages from the same cycle. In this case, cycles must start with the sentence having the msg_num field equal to 1 (see test_data/test_data_0_GPGSV.nmea:

$ python nmea_data_convert.py test_data/test_data_0_GPGSV.nmea db
[output excluded for brevity]

Example 5

Convert GSA sentences, all of the same talker, to database, where each sentence is part of a cycle containing two GSA sentences. Cycles may contain a GSA sentence for each constellation (see test_data/test_data_0_GNGSA.nmea:

$ python nmea_data_convert.py test_data/test_data_0_GNGSA.nmea db -spc 2
[output excluded for brevity]

Development Notes and Oddities

Helpful References

Grafana

One of the great advantages of importing this data into a database is that you can use a system like Grafana to visualize it. Below are screenshots of the included Grafana dashboards showing the data parsed from test_data/test_data_4.nmea using this tool. These dashboards have been found to work in Grafana v7.5.7, but not in v8.0.4.

Discussion

For any questions, feedback, or other discussion items, please feel free to post in the Discussions tab on the GitHub page.