A Python interface to older Garmin GPS equipment
Project description
PyGarmin
The Pygarmin distribution provides a Python module and a command line application that implement the protocol used by Garmin GPS devices. It is based on the official protocol specification.
Documentation
For API documentation, usage and examples see the files in the docs directory. The documentation is also hosted on Read the Docs.
Installing
You can install Pygarmin with pip as follows:
$ pip install pygarmin
Or to upgrade to the most recent version:
$ pip install pygarmin --upgrade
To follow or contribute to pygarmin development, you can browse or clone the Git repository on Github:
$ git clone https://github.com/quentinsf/pygarmin.git
And install the requirements using the below command:
$ pip install -r requirements.txt
Pygarmin application
Description
Pygarmin is a command line application that can retrieve data from and transfer data to a Garmin GPS device connected by a serial or USB port.
The port is specified with the -p PORT option. To communicate with a Garmin GPS serially, use the name of that serial port such as /dev/ttyUSB0, /dev/cu.serial, or COM1. To communicate via USB use usb: as the port on all OSes. For this to work on GNU/Linux, you probably should remove and blacklist the garmin_gps kernel module. Some protocols won’t work at all with a serial connection, like the transfer of images and maps. So your best bet is to use the internal USB support.
The functionality is split into a number of sub-commands, like pygarmin info to return a product description, pygarmin get-waypoints to download the waypoints, and pygarmin put-map to upload a new map.
Examples
Show help message:
pygarmin --help
Show help on the get-almanac command:
pygarmin get-almanac -h
Show product description with debugging enabled:
pygarmin --debug info
Show information on the currently installed maps, use the serial port and be very verbose:
pygarmin -p /dev/ttyUSB0 -vv map
Download all waypoints in gpx format to the file waypoints.gpx:
pygarmin get-waypoints waypoints.gpx -t gpx
Upload all waypoints in the file waypoints.gpx:
pygarmin put-waypoints waypoints.gpx -t gpx
Download all activities in FIT format to the files activity001.fit to activityNNN.fit in the current directory:
pygarmin get-activities -t fit activity%03d.fit
Print real-time position, velocity, and time (PVT) to stdout:
pygarmin pvt -t tpv
List the images types:
pygarmin get-image-types
List all images:
pygarmin get-image-list
Download all images and save them according to the given filename pattern:
pygarmin get-image ~/icons/waypoint%03d.png
Download the images with index 1, 2, and 3 and save them as PNG files with the default filenames to the current directory:
pygarmin get-image -t png -i 1 2 3
Upload an image as a custom waypoint symbol with index 1, and don’t show the progress bar:
pygarmin --no-progress put-image Waypoint\ Symbol\ 000.bmp -i 1
Download the currently installed map from the device and save it as “gmapsupp.img” to the current directory:
pygarmin get-map
Upload the map “gmapsupp.img”:
pygarmin put-map gmapsupp.img
Garmin module
The garmin module is a set of Python classes which implement the protocol used by Garmin GPS receivers to talk to each other and to other machines. It is based on the official protocol specification. The project was started by Quentin Stafford-Fraser but several others have helped to make it what it is today.
PyGarmin has been used to transfer information to and from several different Garmin receivers, mostly under Linux, though there is some Windows support now and people have used it on Mac OS X as well. If you use PyGarmin, it will probably be much quicker than writing your own software from scratch.
Basics
Almost every model of Garmin receiver implements a slightly different protocol. They have many things in common, but there are minor differences. The class Garmin will create instances of the appropriate protocol classes and notes the datatype classes for each type of data used in the transmissions. It also has some friendly methods like get_waypoints(), which do what you would expect. What you get back when you call this is a list of objects, each of which is a child the Wpt class.
Example Code
Here’s a simple Python program:
#!/usr/bin/env python3
import logging
from pygarmin import garmin, link, logger
logger.log.addHandler(logging.StreamHandler())
logger.log.setLevel(logging.INFO)
# Create a 'physical layer' connection using serial port
phys = link.SerialLink('/dev/ttyUSB0')
# ...or using USB
phys = link.USBLink()
# Create a Garmin object using this connection
gps = garmin.Garmin(phys)
# Get the waypoints from the GPS
waypoints = gps.get_waypoints()
# Get the tracks from the GPS
tracks = gps.get_tracks()
# Print the waypoints
print("Waypoints:")
for waypoint in waypoints:
posn = waypoint.get_posn()
degrees = posn.as_degrees()
lat = degrees.lat
lon = degrees.lon
print(waypoint.ident, lat, lon, waypoint.cmnt)
# Print the tracks
print("Tracks:")
for track in tracks:
print(track)
# Put a new waypoint
print("Upload a new waypoint:")
waypoints = [{'ident': b'CHURCH',
'cmnt': b'LA SAGRADA FAMILIA',
'posn': [493961671, 25937164]}]
gps.put_waypoints(waypoints)
This should work for most models, because all waypoints will have an identity, a position (latitude and longitude), and a comment field. The latitude and longitude are transferred as ‘semicircle’ coordinates (basically degrees, but scaled to fill a signed long integer). The static method Position.to_degrees() converts a semicircle integer into a degree float and the as_degrees() method converts a Position into a DegreePosition data type.
License
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3.
In the past, it has been released under the GNU General Public License version 2, and some contributions have been made under that license. You may use it under the terms of the GPLv2 if you prefer.
Acknowledgements
Thanks are due to, amongst others:
James Skillen
Hyrum K. Wright
Cedric Dutoit
Folkert van der Beek (for a major rewrite in Dec 2022)
and probably others, to whom our apologies!
The logo was designed by Quentin Stafford-Fraser
Changelog
[2.0.1] 2024-06-08
Determine USB endpoints dynamically (fixes issue #9)
[2.0.0] 2024-06-06
Fix example code in README
Increase the major version number because of the breaking change in version 1.2.2
[1.2.2] 2024-06-05
Require Python version 3.9 (fixes issue #11)
[1.2.1] 2024-06-05
Fix uploading of routes
[1.2.0] 2024-03-17
Fix datetimes that were off by 12 hours
Localize datetimes
Fix name clashes of classes
Fix A201 route transfer protocol
Fix D104 waypoint datatype
Fix D304 track point datatype
Better layout of submodules
Support export to and import from JSON
Support import from GPX (export to GPX was already supported)
Add creator attribute to exported GPX
Support export to FIT
Use the same version for the module and the application
Various bugfixes
[1.1.2] 2023-12-27
Fix GPX export of Garmin Forerunner 305 tracks
[1.1.1] 2023-12-26
Use the same license (GPLv2 or later) for the package as the source
[1.1.0] 2023-12-26
Support Garmin Forerunner 305
Support images of different color depths
Various bugfixes
[1.0.5] 2023-11-22
Fix relative package import (PR #7)
[1.0.4] 2022-12-23
Improve documentation
Add usage of pygarmin application to project description
[1.0.3] 2022-12-23
Fix project description
[1.0.2] 2022-12-22
Host documentation on Read the Docs
[1.0.1] 2022-12-21
Made the pygarmin script a submodule
Improved docstrings
Switched from Markdown to ReStructuredText
Added documentation using Sphinx
[1.0]
Improved coding style to conform to the PEP8 style guide
Improved logging
Improved docstrings
Used a factory method to create objects
Used the new PyUSB 1.0 API
Used f-strings instead of %-formatting
Used the rawutil module instead of a customized struct
Implemented unit ID request
Added support for baudrate change
Added support for proximity waypoints transfer
Added support for waypoint category transfer
Added support for position initialization
Added support for maps
Added support for image transfer (screenshots and waypoint symbols)
Added support for screenshots
Removed test code (because I believe this belongs outside the main module)
Rewritten pygarmin to a fairly complete command-line program
[0.8]
Used pyserial for serial communication
Added debian package support
Added support for flightbook
Added support for laps
Added support for runs
Added support for USB devices
Migrated to python3
[0.7]
Fixed various bugs
Brought up to date with CVS (the tarball had become very dated)
Patches for recent pythons on Win32
JAHS’s mods - callback, debug etc
See CVS logs for more details
[0.6]
Fixed various bugs
Tidier SerialLink code
Runs under Python 1.5.2
More debugging available if wanted
[0.5]
Added a datum-conversion module.
Added Raymond Penners’ Win32SerialLink stuff and timeout stuff
A900 support
A800 support (for real-time data)
Waypoints now have repr, str and getDict methods
The ‘pygarmin’ app has some facilities to output XML, using the new xmlwriter module
[0.4]
Various bug fixes and minor changes. See CVS logs for details
[0.3]
Some changes to newstruct to fix bugs and make it work with Python 1.5.1
Added TrackHdr class to fix protocol D310
[0.2]
Incorporated James Skillen’s improvements to support protocol A001 for newer Garmin units
Updated the tables based on new spec
[0.1]
Initial release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file pygarmin-2.0.1-py3-none-any.whl
.
File metadata
- Download URL: pygarmin-2.0.1-py3-none-any.whl
- Upload date:
- Size: 96.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9a7953455f57515320b44e92b8a1d088982ac937d57833d5dde366775560e5b9 |
|
MD5 | 87c37462c6c64d9ffb857b518b915232 |
|
BLAKE2b-256 | 7db3ceaab242dfe580dade5932820889d31f3fa88565314aaf16c40fd9929f43 |