python-3.xgpsgpsd

Python gpsd client


All the previous answers to python code to connect to a gpsd daemon as a client either reference very old libraries or do not work.

I have tried the example code at the official website here - and that too do not work.

The code is:

import gps           

session = gps.gps(mode=gps.WATCH_ENABLE)

try:
    while 0 == session.read():
        if not (gps.MODE_SET & session.valid):
            # not useful, probably not a TPV message
            continue

        print('Mode: %s(%d) Time: ' %
              (("Invalid", "NO_FIX", "2D", "3D")[session.fix.mode],
               session.fix.mode), end="")
        # print time, if we have it
        if gps.TIME_SET & session.valid:
            print(session.fix.time, end="")
        else:
            print('n/a', end="")

        if ((gps.isfinite(session.fix.latitude) and
             gps.isfinite(session.fix.longitude))):
            print(" Lat %.6f Lon %.6f" %
                  (session.fix.latitude, session.fix.longitude))
        else:
            print(" Lat n/a Lon n/a")

except KeyboardInterrupt:
    # got a ^C.  Say bye
    print('')

# Got ^C, or fell out of the loop.  Cleanup, and leave.
session.close()
exit(0)

But the error when I try this code is : TypeError: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'

The full stack trace is :

TypeError Traceback (most recent call last) Cell In[11], line 6 3 session = gps.gps(mode=gps.WATCH_ENABLE) 5 try: ----> 6 while 0 == session.read(): 7 if not (gps.MODE_SET & session.valid): 8 # not useful, probably not a TPV message 9 continue

File ~/test_fft/venv/lib/python3.11/site-packages/gps/gps.py:285, in gps.read(self) 283 return status 284 if self.response.startswith("{") and self.response.endswith("}\r\n"): --> 285 self.unpack(self.response) 286 self.__oldstyle_shim() 287 self.valid |= PACKET_SET

File ~/test_fft/venv/lib/python3.11/site-packages/gps/client.py:199, in gpsjson.unpack(self, buf) 197 "Unpack a JSON string" 198 try: --> 199 self.data = dictwrapper(json.loads(buf.strip(), encoding="ascii")) 200 except ValueError as e: 201 raise json_error(buf, e.args[0])

File /usr/lib/python3.11/json/init.py:359, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw) 357 if parse_constant is not None: 358 kw['parse_constant'] = parse_constant --> 359 return cls(**kw).decode(s)

TypeError: JSONDecoder.init() got an unexpected keyword argument 'encoding'

There are a few other old answers on here: Using GPS library in Python 3 and gpsd python client

Is there a maintained python3 client for gpsd or does anyone know a way to poll for gps positions to gpsd from python?


Solution

  • One method that does work with python 3:

    import gpsd
    
    # Connect to the local gpsd
    gpsd.connect()
    # Get the current position
    packet = gpsd.get_current()
    # Get the latitude and longitude
    latitude = packet.lat
    longitude = packet.lon
    print("Latitude:", latitude)
    print("Longitude:", longitude)
    

    This uses : https://github.com/MartijnBraam/gpsd-py3 or there is a maintained forked version here : https://github.com/hatsunearu/py-gpsd2

    However the issue in my original post was that I was using a venv - so when I ran gpsd in the venv I was getting the default (and very old) version of gpsd (3.19 IIRC).

    The second part to solving this was to swap to the venv, elevate to root, install gpsd - and then the python code using the gps client was using the installed version for the venv.