gpsd python客户端

我正在尝试为Gpsd编写一个非常简单的python客户端,但我有 执行脚本一段时间后出现此错误:
Traceback (most recent call last):
 File "gps_cap.py", line 13, in <module>
   g.stream()
 File "/usr/lib/python2.6/site-packages/gps/gps.py", line 348, in stream
   gpsjson.stream(self, flags)
 File "/usr/lib/python2.6/site-packages/gps/client.py", line 176, in stream
   return self.send(arg + "}")
 File "/usr/lib/python2.6/site-packages/gps/client.py", line 111, in send
   self.sock.send(commands)
socket.error: [Errno 104] Connection reset by peer
这是我的python代码:
import os
from gps import *
from time import *

g = gps(mode=WATCH_ENABLE)
while 1:
      os.system('clear')
       g.poll()
       if PACKET_SET:
               g.stream()

       print
       print ' GPS reading'
       print '----------------------------------------'
       print 'latitude    ' , g.fix.latitude
       print 'longitude   ' , g.fix.longitude
       print 'time utc    ' , g.utc,' + ', g.fix.time
       print 'altitude    ' , g.fix.altitude
       print 'epc         ' , g.fix.epc
       print 'epd         ' , g.fix.epd
       print 'eps         ' , g.fix.eps
       print 'epx         ' , g.fix.epx
       print 'epv         ' , g.fix.epv
       print 'ept         ' , g.fix.ept
       print 'speed       ' , g.fix.speed
       print 'climb       ' , g.fix.climb
       print 'track       ' , g.fix.track
       print 'mode        ' , g.fix.mode
       print
       print 'sats        ' , g.satellites

       sleep(1)
也许有人可以帮忙解决这个问题?我在ArchLinux框中运行Gpsd 2.95。 谢谢!     
已邀请:

bab

我知道这个问题已经很老了,但我仍然会在这里放弃我的答案以防将来有人需要它:
#! /usr/bin/python
# Written by Dan Mandle http://dan.mandle.me September 2012
# License: GPL 2.0 
import os
from gps import *
from time import *
import time
import threading

gpsd = None #seting the global variable

os.system('clear') #clear the terminal (optional)

class GpsPoller(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self)
    global gpsd #bring it in scope
    gpsd = gps(mode=WATCH_ENABLE) #starting the stream of info
    self.current_value = None
    self.running = True #setting the thread running to true

  def run(self):
    global gpsd
    while gpsp.running:
      gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer

if __name__ == '__main__':
  gpsp = GpsPoller() # create the thread
  try:
    gpsp.start() # start it up
    while True:
      #It may take a second or two to get good data
      #print gpsd.fix.latitude,', ',gpsd.fix.longitude,'  Time: ',gpsd.utc

      os.system('clear')

      print
      print ' GPS reading'
      print '----------------------------------------'
      print 'latitude    ' , gpsd.fix.latitude
      print 'longitude   ' , gpsd.fix.longitude
      print 'time utc    ' , gpsd.utc,' + ', gpsd.fix.time
      print 'altitude (m)' , gpsd.fix.altitude
      print 'eps         ' , gpsd.fix.eps
      print 'epx         ' , gpsd.fix.epx
      print 'epv         ' , gpsd.fix.epv
      print 'ept         ' , gpsd.fix.ept
      print 'speed (m/s) ' , gpsd.fix.speed
      print 'climb       ' , gpsd.fix.climb
      print 'track       ' , gpsd.fix.track
      print 'mode        ' , gpsd.fix.mode
      print
      print 'sats        ' , gpsd.satellites

      time.sleep(5) #set to whatever

  except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
    print "nKilling Thread..."
    gpsp.running = False
    gpsp.join() # wait for the thread to finish what it's doing
  print "Done.nExiting."
此代码与线程一起使用,并将gpsd数据输出到屏幕。它可以用Ctrl + C终止。 所有学分都转到http://www.danmandle.com/blog/getting-gpsd-to-work-with-python/     
我会从gpsd的这个snippit上点钱怎么翻页;还有,谢谢你的bootstrap代码。 http://gpsd.berlios.de/client-howto.html   如果你是一个聪明的排序,你已经想知道如果客户端套接字另一端的应用程序没有像gpsd向上发送它那样快地读取数据,守护程序会做什么。答案是这样的:最终套接字缓冲区填满,来自守护进程的写入抛出错误,守护进程关闭该客户端套接字。      只要您的应用程序检查和读取套接字数据的频率不低于每秒一次,您就不会 - 而且第二次是大量时间回到主循环。     
为了保持旧问题的存在,下面粘贴的是GPS3的当前状态,这是一个Python 2.7-3.5 gpsd客户端,位于https://github.com/wadda/gps3。 GPS3有两个组成部分; GPSDSocket类和Fix类。 GPSD在许多“类”,TPV,SKY等中提供JSON数据。连接到GPSD后,GPS3将这些JSON对象解压缩到字典中(
Fix.TPV['lat']
Fix.SKY['satellites']
等) 常用将创建一个实例,例如
fix = gps3.Fix()
,并且所有可用数据都将从本机JSON对象的名称派生(例如,
fix.TPV['speed']
fix.TPV['alt']
等) 与演示应用程序gegps3.py一起使用,创建一个
kml
文件(
/tmp/gps3_live.kml
),以便在Google Earth中查看。
#!/usr/bin/env python3
# coding=utf-8
"""
GPS3 (gps3.py) is a Python 2.7-3.5 GPSD interface (http://www.catb.org/gpsd)
Defaults host='127.0.0.1', port=2947, gpsd_protocol='json'

GPS3 has two classes.
1) 'GPSDSocket' to create a GPSD socket connection and request/retreive GPSD output.
2) 'Fix' unpacks the streamed gpsd data into python dictionaries.

These dictionaries are literated from the JSON data packet sent from the GPSD.

Import           import gps3
Instantiate      gps_connection = gps3.GPSDSocket(host='192.168.0.4')
                 gps_fix = gps3.Fix()
Iterate          for new_data in gps_connection:
                     if new_data:
                        gps_fix.refresh(new_data)
Use                     print('Altitude = ',gps_fix.TPV['alt'])
                        print('Latitude = ',gps_fix.TPV['lat'])

Consult Lines 152-ff for Attribute/Key possibilities.
or http://www.catb.org/gpsd/gpsd_json.html

Run human.py; python[X] human.py [arguments] for a human experience.
"""
from __future__ import print_function

import json
import select
import socket
import sys

__author__ = 'Moe'
__copyright__ = 'Copyright 2015-2016  Moe'
__license__ = 'MIT'
__version__ = '0.2'

HOST = '127.0.0.1'  # gpsd
GPSD_PORT = 2947  # defaults
PROTOCOL = 'json'  # "


class GPSDSocket(object):
    """Establish a socket with gpsd, by which to send commands and receive data."""

    def __init__(self, host=HOST, port=GPSD_PORT, gpsd_protocol=PROTOCOL, devicepath=None):
        self.devicepath_alternate = devicepath
        self.response = None
        self.protocol = gpsd_protocol
        self.streamSock = None

        if host:
            self.connect(host, port)

    def connect(self, host, port):
        """Connect to a host on a given port.
        Arguments:
            port: default port=2947
            host: default host='127.0.0.1'
        """
        for alotta_stuff in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
            family, socktype, proto, _canonname, host_port = alotta_stuff
            try:
                self.streamSock = socket.socket(family, socktype, proto)
                self.streamSock.connect(host_port)
                self.streamSock.setblocking(False)
                self.watch(gpsd_protocol=self.protocol)
            except OSError as error:
                sys.stderr.write('nGPSDSocket.connect OSError is-->', error)
                sys.stderr.write('nAttempt to connect to a gpsd at {0} on port '{1}' failed:n'.format(host, port))
                sys.exit(1)  # TODO: gpsd existence check and start

    def watch(self, enable=True, gpsd_protocol='json', devicepath=None):
        """watch gpsd in various gpsd_protocols or devices.
        Arguments:
            self:
            enable: (bool) stream data to socket
            gpsd_protocol: (str) 'json' | 'nmea' | 'rare' | 'raw' | 'scaled' | 'split24' | 'pps'
            devicepath: (str) device path - '/dev/ttyUSBn' for some number n or '/dev/whatever_works'
        Returns:
            command: (str) e.g., '?WATCH={"enable":true,"json":true};'
        """
        # N.B.: 'timing' requires special attention, as it is undocumented and lives with dragons.
        command = '?WATCH={{"enable":true,"{0}":true}}'.format(gpsd_protocol)

        if gpsd_protocol == 'rare':  # 1 for a channel, gpsd reports the unprocessed NMEA or AIVDM data stream
            command = command.replace('"rare":true', '"raw":1')
        if gpsd_protocol == 'raw':  # 2 channel that processes binary data, received data verbatim without hex-dumping.
            command = command.replace('"raw":true', '"raw",2')
        if not enable:
            command = command.replace('true', 'false')  # sets -all- command values false .
        if devicepath:
            command = command.replace('}', ',"device":"') + devicepath + '"}'

        return self.send(command)

    def send(self, commands):
        """Ship commands to the daemon
        Arguments:
            commands: e.g., '?WATCH={{'enable':true,'json':true}}'|'?VERSION;'|'?DEVICES;'|'?DEVICE;'|'?POLL;'
        """
        # The POLL command requests data from the last-seen fixes on all active GPS devices.
        # Devices must previously have been activated by ?WATCH to be pollable.
        if sys.version_info[0] < 3:  # Not less than 3, but 'broken hearted' because
            self.streamSock.send(commands)  # 2.7 chokes on 'bytes' and 'encoding='
        else:
            self.streamSock.send(bytes(commands, encoding='utf-8'))  # It craps out here when there is no gpsd running
            # TODO: Add recovery, check gpsd existence, re/start, etc..

    def __iter__(self):
        """banana"""  # <------- for scale
        return self

    def next(self, timeout=0):
        """Return empty unless new data is ready for the client.
        Arguments:
            timeout: Default timeout=0  range zero to float specifies a time-out as a floating point
        number in seconds.  Will sit and wait for timeout seconds.  When the timeout argument is omitted
        the function blocks until at least one file descriptor is ready. A time-out value of zero specifies
        a poll and never blocks.
        """
        try:
            waitin, _waitout, _waiterror = select.select((self.streamSock,), (), (), timeout)
            if not waitin: return
            else:
                gpsd_response = self.streamSock.makefile()  # '.makefile(buffering=4096)' In strictly Python3
                self.response = gpsd_response.readline()
            return self.response

        except OSError as error:
            sys.stderr.write('The readline OSError in GPSDSocket.next is this: ', error)

    __next__ = next  # Workaround for changes in iterating between Python 2.7 and 3

    def close(self):
        """turn off stream and close socket"""
        if self.streamSock:
            self.watch(enable=False)
            self.streamSock.close()
        self.streamSock = None


class Fix(object):
    """Retrieve JSON Object(s) from GPSDSocket and unpack it into respective
    gpsd 'class' dictionaries, TPV, SKY, etc. yielding hours of fun and entertainment.
    """

    def __init__(self):
        """Potential data packages from gpsd for a generator of class attribute dictionaries"""

        packages = {'VERSION': {'release', 'proto_major', 'proto_minor', 'remote', 'rev'},
                    'TPV': {'alt', 'climb', 'device', 'epc', 'epd', 'eps', 'ept', 'epv', 'epx', 'epy', 'lat', 'lon', 'mode', 'speed', 'tag', 'time', 'track'},
                    'SKY': {'satellites', 'gdop', 'hdop', 'pdop', 'tdop', 'vdop', 'xdop', 'ydop'},
                    # Subset of SKY: 'satellites': {'PRN', 'ss', 'el', 'az', 'used'}  # is always present.
                    'GST': {'alt', 'device', 'lat', 'lon', 'major', 'minor', 'orient', 'rms', 'time'},
                    'ATT': {'acc_len', 'acc_x', 'acc_y', 'acc_z', 'depth', 'device', 'dip', 'gyro_x', 'gyro_y', 'heading', 'mag_len', 'mag_st', 'mag_x',
                            'mag_y', 'mag_z', 'pitch', 'pitch_st', 'roll', 'roll_st', 'temperature', 'time', 'yaw', 'yaw_st'},
                    # 'POLL': {'active', 'tpv', 'sky', 'time'},
                    'PPS': {'device', 'clock_sec', 'clock_nsec', 'real_sec', 'real_nsec', 'precision'},
                    'TOFF': {'device', 'clock_sec', 'clock_nsec','real_sec', 'real_nsec' },
                    'DEVICES': {'devices', 'remote'},
                    'DEVICE': {'activated', 'bps', 'cycle', 'mincycle', 'driver', 'flags', 'native', 'parity', 'path', 'stopbits', 'subtype'},
                    # 'AIS': {}  # see: http://catb.org/gpsd/AIVDM.html
                    'ERROR': {'message'}}  # TODO: Full suite of possible GPSD output

        for package_name, dataset in packages.items():
            _emptydict = {key: 'n/a' for key in dataset}
            setattr(self, package_name, _emptydict)

        self.DEVICES['devices'] = {key: 'n/a' for key in packages['DEVICE']}  # How does multiple listed devices work?
        # self.POLL = {'tpv': self.TPV, 'sky': self.SKY, 'time': 'n/a', 'active': 'n/a'}

    def refresh(self, gpsd_data_package):
        """Sets new socket data as Fix attributes in those initialied dictionaries
        Arguments:
            self:
            gpsd_data_package (json object):
        Provides:
        self attribute dictionaries, e.g., self.TPV['lat'], self.SKY['gdop']
        Raises:
        AttributeError: 'str' object has no attribute 'keys' when the device falls out of the system
        ValueError, KeyError: most likely extra, or mangled JSON data, should not happen, but that
        applies to a lot of things.
        """
        try:
            fresh_data = json.loads(gpsd_data_package)  # The reserved word 'class' is popped from JSON object class
            package_name = fresh_data.pop('class', 'ERROR')  # gpsd data package errors are also 'ERROR'.
            package = getattr(self, package_name, package_name)  # packages are named for JSON object class
            for key in package.keys():  # TODO: Rollover and retry.  It fails here when device disappears
                package[key] = fresh_data.get(key, 'n/a')  # Updates and restores 'n/a' if key is absent in the socket
                # response, present --> 'key: 'n/a'' instead.'
        except AttributeError:  # 'str' object has no attribute 'keys'
            print('No Data')
            return

        except (ValueError, KeyError) as error:
            sys.stderr.write(str(error))  # Look for extra data in stream
            return


if __name__ == '__main__':
    print('n', __doc__)

#
# Someday a cleaner Python interface will live here
#
# End
    

要回复问题请先登录注册