Python gpsd client

118 views Asked by At

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?

2

There are 2 answers

0
Al Grant On BEST ANSWER

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.

1
JamesB192 On

TLDR: Python 3.9 removed the encoding argument from json.loads, so you'll need to remove the argument or downgrade to Python < 3.9 when using the unmaintained fork from PYPI.

gpsd upstream solved this on 2020 July 12, so when using the module that comes with gpsd, no changes are needed.

If you can not get/use the module that comes with gpsd, you may use the gps-pessimus module, which, in addition to being updated recently, also includes most of the Python clients from gpsd. But, please, to be reasonable, try to use the module that comes with gpsd.