May 27 2007
Python gpsd bindings
If you want to get a linux/unix machine talking to your GPS unit, most likely you’ll be using gpsd. There are many great apps that build off of gpsd such as kismet and gpsdrive.
Installing gpsd on debian/ubuntu systems is as simple as
sudo apt-get install gpsd gpsd-clients
You should be able to connect your gps via serial port and start a gpsd server
sudo gpsd /dev/ttyS0
The gpsd server reads NMEA sentences from the gps unit and is accessed on port 2947. You can test if everything is working by running a pre-built gpsd client such as xgps.
This is very useful for situations where you need lower-level access to the gps data; for logging your position to a postgres database for example. The debian packages (and most others I’m assuming) come with gps.py, a python interface to gpsd allowing you to pull your lat/long from the gps in real time. This opens the door for all sorts of neat real-time gps apps.
import gps, os, time
session = gps.gps()
while 1:
os.system('clear')
session.query('admosy')
# a = altitude, d = date/time, m=mode,
# o=postion/fix, s=status, y=satellites
print
print ' GPS reading'
print '----------------------------------------'
print 'latitude ' , session.fix.latitude
print 'longitude ' , session.fix.longitude
print 'time utc ' , session.utc, session.fix.time
print 'altitude ' , session.fix.altitude
print 'eph ' , session.fix.eph
print 'epv ' , session.fix.epv
print 'ept ' , session.fix.ept
print 'speed ' , session.fix.speed
print 'climb ' , session.fix.climb
print
print ' Satellites (total of', len(session.satellites) , ' in view)'
for i in session.satellites:
print '\t', i
time.sleep(3)
… which gives you a simple readout to the terminal every 3 seconds.

Obviously there are much more interesting applications for this ( logging data to postgis, displaying real-time tracking data in QGIS via a python plugin, etc). But this is a good start for any python based app.
Hi Matt, nice article! Here is a way to get differential corection on-the-fly to a gpsd application.
1. Get and install dgpsip
2. attach gps, set IO to RTCM/NMEA
3. start gpsd
4. run dgpsip: sudo dgpsip -o /dev/ttyS0 -s 9600 -v 2
5. ???
6. i noticed that my garmin GPS12 shows a “3D DIFF” message about 5 seconds after dgpsip has been started, and the EPE goes down to about 3 meters. I find that averaging waypoint locations gets the accuracy down to about 2.7 meters!! not bad for a GPS from 2000, and an old laptop with a wireless card. This only really works if you have an internet connection.
Apparently it is also possible to differentially correct data from a garmin using some tools. Haven’t tried this yet. If it works it would be a heck of a lot simpler than using our trimble and their crappy software.
Cheers,
Dylan
great article, I love your style. All the best green this commentary comes out of England.
Hi Matt, I’m new to Linux and trying to learn how I can interface my notebook (running Mepis Linux), my Holux GR-213 USB GPS and Google Earth to give me real-time posits while mobile.
Running XP, I interfaced the three with Earthbridge and it worked fine. I plugged in by GPS, fired up Earthbridge to get the satellite fixes and then started Google Earth to get plots on GE’s maps.
What is your recommendation for a newbie to do the same using Linux? How do I get gpsd to I/F with GE? Would I be better off using another program that has a GUI that would be easier for me to use?
Thanks much,
Ron
Izmir, Turkey
Hi, We are using gps.py to test some rail road signals We would like to know what session.fix.speed is out putting; miles, kilometers or knots per hour? NMEA uses knots, but I noticed that the positioning is not standard NMEA. Thanks! Harry
@harry
Not sure what the units are on session.fix.speed… it’s been a while since I read up on it. I’m sure its in the gpsd docs somewhere.
Hi Matt,
So, I’m Brazilian and here is so difficult to see gps oem hardwares.
So, do you suggest any hardware to use at freebsd(preferred) or linux with less work as possible?
thanks in advance!
Bilouro
Thanks for this nice example, however I have a problem running your code, when trying to execute it on Ubuntu 8.10 Python Version 2.5.2 I only get
Traceback (most recent call last):
File “./gps.py”, line 2, in
import gps, os, time
File “/home/niklas/maps/gps.py”, line 4, in
session = gps.gps()
TypeError: ‘module’ object is not callable
session.fix.speed looks like metres per second.
[…] to gpsd with python simple class to interface with gpsd: outch!: perhaps this is a better […]
@Niklas I know it’s late, but in case other people run into this page and are having the same problem:
Make sure you have the gps.py file that is distributed from your version of gpsd. You can download the full tarball from http://gpsd.berlios.de/ Simply copy gpsd.py to your working directory, and re-run the script.
cheers!
@Niklas
Change the name of the file you’ve saved it to. It’s trying to import itself.
Hi there,
thanks a lot for your PYTHON/GPSD tutorial !
I am a beginner to Python and need to count the number of sattelites used.
Therefore, I would like to read out the last character of each “session.satellites[n]” line, which is either “y” or “n”.
s = session.satellites[i] # where i is the actual number of the satellite
print s[-1] # this should give me the first sign from the right = last sign of string, which is either y or n
The example above does not work, I get the following error:
AttributeError: satellite instance has no attribute ‘__getitem__’
As I understand it, it must be some mistake related to object-oriented programming, which I haven’t learned yet.
Could you please help me ?
Thanks a lot in advance,
Jens
ROFL !
I just found it out all by myself…
It just has to be
s = str(session.satellites[i])
and then
print s[-1]
works as intended and gives me either “y” or “n”.
I did not expect it to be THAT simple !
Now I feel a little bit ashamed… *smile*
Hi there,
I get an error when running this:
Traceback (most recent call last):
File “”, line 7, in
AttributeError: gps instance has no attribute ‘query’
Has query() been removed from gps.py?
What needs to be done to fix the above script so it works?
Thanks
Micheal,
The gpsd python bindings appear to have changed significantly. The best bet would be to introspect/experiment with the gps object with python, consult the gpsd python source or contact the gpsd developers.
Thanks for the prompt reply
Appreciated.
Hi,
Thank you for all information of gps.py.
Though you may know very well, I found how to connect
to the other gpsd server over network. It is just to start
an application program by
import gps
session = gps.gps(host=hostname, port=’2947′)
hostname should be text of the hostname or of the IP address.
To connect to the local server, hostname=’localhost’.
By copying the gps.py to my WINDOWS PC, my PC can read
data from the LINUX gpsd server over network.
Thanks for very easy programming with gps.py
I have one question. Now it is announced that the gpsd
command interface will be changed soon. What will be
the change of the gps.py interface? Explanation of the JASON
command interface is not very clear to me. I am sorry.
Even some suggestions are useful. Thanks for your help.
Mamoru Yamamoto
Kyoto University, JAPAN
Mamoru,
You should contact the gpsd developers list for more information .. I am not personally involved in the project so I cant answer your questions about how the interface may change.
Dear all,
In case you arrived in the year 2010, things have indeed changed!
For the good:
eep ;import gps
session = gps.gps()
print session
I leave it to you to “implement” the while loop and the sleep
Also I had to check some terminology on the original script:
eph == Precision horizontal
epv == Precision vertical
ept == Precision total
in case you want to use the above script, it IS possible just delete the query line:
session.query(’admosy’)
and amend eph to epx:
print ‘epx ‘ , session.fix.epx
In full:
import gps, os, time
session = gps.gps()
while 1:
os.system('clear')
# a = altitude, d = date/time, m=mode,
# o=postion/fix, s=status, y=satellites
print
print ' GPS reading'
print '----------------------------------------'
print 'latitude ' , session.fix.latitude
print 'longitude ' , session.fix.longitude
print 'time utc ' , session.utc, session.fix.time
print 'altitude ' , session.fix.altitude
print 'epx ' , session.fix.epx
print 'epv ' , session.fix.epv
print 'ept ' , session.fix.ept
print 'speed ' , session.fix.speed
print 'climb ' , session.fix.climb
print
print ' Satellites (total of', len(session.satellites) , ' in view)'
for i in session.satellites:
print '\t', i
time.sleep(3)
Hack on!
Steve Clemenet
For some reason all my data comes out empty (i.e. longitude is 0, latitude is 0, no satellites) even though xgps tells me i’m connected perfectly.
is there something i’m missing?
It appears that the session object has to have streaming turned on, and that it must be polled in order for it to obtain the GPS data:
#!/usr/bin/python
import gps, os, time
session = gps.gps()
session.poll()
session.stream()
while 1:
os.system(’clear’)
session.poll()
# a = altitude, d = date/time, m=mode,
# o=postion/fix, s=status, y=satellites
print
print ‘ GPS reading’
print ‘—————————————-’
print ‘latitude ‘ , session.fix.latitude
print ‘longitude ‘ , session.fix.longitude
print ‘time utc ‘ , session.utc, session.fix.time
print ‘altitude ‘ , session.fix.altitude
print ‘epx ‘ , session.fix.epx
print ‘epv ‘ , session.fix.epv
print ‘ept ‘ , session.fix.ept
print ’speed ‘ , session.fix.speed
print ‘climb ‘ , session.fix.climb
print
print ‘ Satellites (total of’, len(session.satellites) , ‘ in view)’
for i in session.satellites:
print ‘\t’, i
time.sleep(3)