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?
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.