2

I have some hacks to ensure that my USB GPS devices continues spitting data if disconnected, then reconnected. The devices are so flaky that they need restarting so as to continue transmitting data.

My hack is to have a cron job that runs every minute (I want quick recovery), invoking a script that keeps asking gpsd to continue WATCHing all configured devices every minute.

So, I added this line in /etc/crontab:

* * * * * username /usr/bin/python /usr/local/bin/keepalive.py

And the content of /usr/local/bin/keepalive.py:

import socket
from syslog import syslog, openlog

CMD = '?WATCH={"class":"WATCH","json":true}'

def main():
   openlog(__file__)
   syslog('connecting to gpsd socket')
   try:
       sock = socket.create_connection(('localhost', 2947))
   except socket.error as e:
       syslog('connection failure: {0}'.format(e))
   else:
       syslog('CMD: ' + CMD)
       sock.sendall(CMD)
       syslog('success')
   finally:
       if sock:
          sock.close()

if __name__ == '__main__':
   main()

I also added this line to /etc/udev/rules.d/custom.rules:

ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", SYMLINK+="flaky%n"

That's because I can have more than one of those devices connected at the same time.

Is there some udev / gpsd magic I can do to avoid this hack?

tshepang
  • 64,472
  • 86
  • 223
  • 290
  • You have not said what the problem with your udev+script solution is. – goldilocks Feb 19 '13 at 07:44
  • My solution works very well, but it's still a hack... sending the WATCH command every minute? Can **gpsd** recover by itself, without a hack like this. – tshepang Feb 19 '13 at 08:39
  • I see your point. I don't use *gpsd*, but daemons usually have more polished methods for checking if they are running or not (check the docs). I don't use python either, but a quick google revealed that gpsd has a python interface: http://gpsd.berlios.de/client-howto.html Interesting that Eric. S. Raymond appears to be the gpsd dev. – goldilocks Feb 19 '13 at 12:54
  • The **gpsd** daemon is running well. My question is more how to let it resume with the command it was given before the disconnect. Also, the data given by the devices is consumed by some other app (C++), and would be too painful to change that to do the poking ("you haven't given me data in a while sir **gpsd**")... at least as compared to this simple hack. – tshepang Feb 19 '13 at 15:44
  • 1
    Ah, I see. You are using the gpsd protocol via a python socket. I glanced at it and thought you were just testing the socket to see if the daemon is running. In that case, if you've read the protocol documentation and you can't find anything better, then probably there's your answer. For what it's worth, IMO you are doing it the right way *except* I would try and use the gpsd python bindings instead (`gps_stream()`?). Also, I would make the python script an independent background process of its own to do the poll every minute, rather than using cron. – goldilocks Feb 19 '13 at 16:21
  • Are you averse to the cron way due to it being expensive (run a new process; re-open the socket), or is there any other reason? – tshepang Feb 19 '13 at 16:52
  • Yeah, that was it. Also seems tidier. Not a big deal either way. – goldilocks Feb 19 '13 at 17:17
  • It still would be nice to determine the proper way to handle the case when GPS device is re-connected. When I unplug the device while my program is running, nothing explicit happens - only the `.next()` keeps returning the same (outdated) value. Thus, I need something to check connection integrity. I noticed, that the USB port changes from `ttyUSB0` to `ttyUSB1` after re-connection - which creates another problem: restarting the gpds does not help, because its config file says to connect to `ttyUSB0`. How do we bump your question to the homepage so it could be answered? – Nazar Mar 18 '18 at 20:54

0 Answers0