📄 garmin.py
字号:
MaxVer = 999.99ModelProtocols = {# Use a wide window for best viewing!## ID minver maxver Link Cmnd Wpt, Rte, Trk, Prx, Alm7: ( (None, L001, A010, (A100, D100), (A200, D200, D100), None, None, (A500, D500) ), ),13: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),14: ( (None, L001, A010, (A100, D100), (A200, D200, D100), None, (A400, D400), (A500, D500) ), ),15: ( (None, L001, A010, (A100, D151), (A200, D200, D151), None, (A400, D151), (A500, D500) ), ),18: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),20: ( (None, L002, A011, (A100, D150), (A200, D201, D150), None, (A400, D450), (A500, D550) ), ),22: ( (None, L001, A010, (A100, D152), (A200, D200, D152), (A300, D300), (A400, D152), (A500, D500) ), ),23: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),24: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),25: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),29: ( ((0.00, 4.00), L001, A010, (A100, D101), (A200, D201, D101), (A300, D300), (A400, D101), (A500, D500) ), ((4.00, MaxVer), L001, A010, (A100, D102), (A200, D201, D102), (A300, D300), (A400, D102), (A500, D500) ), ),31: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),33: ( (None, L002, A011, (A100, D150), (A200, D201, D150), None, (A400, D450), (A500, D550) ), ),34: ( (None, L002, A011, (A100, D150), (A200, D201, D150), None, (A400, D450), (A500, D550) ), ),35: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),36: ( ((0.00, 3.00), L001, A010, (A100, D152), (A200, D200, D152), (A300, D300), (A400, D152), (A500, D500) ), ((3.00, MaxVer), L001, A010, (A100, D152), (A200, D200, D152), (A300, D300), None, (A500, D500) ), ),39: ( (None, L001, A010, (A100, D151), (A200, D201, D151), (A300, D300), None, (A500, D500) ), ),41: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),42: ( (None, L001, A010, (A100, D100), (A200, D200, D100), (A300, D300), (A400, D400), (A500, D500) ), ),44: ( (None, L001, A010, (A100, D101), (A200, D201, D101), (A300, D300), (A400, D101), (A500, D500) ), ),45: ( (None, L001, A010, (A100, D152), (A200, D201, D152), (A300, D300), None, (A500, D500) ), ),47: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),48: ( (None, L001, A010, (A100, D154), (A200, D201, D154), (A300, D300), None, (A500, D501) ), ),49: ( (None, L001, A010, (A100, D102), (A200, D201, D102), (A300, D300), (A400, D102), (A500, D501) ), ),50: ( (None, L001, A010, (A100, D152), (A200, D201, D152), (A300, D300), None, (A500, D501) ), ),52: ( (None, L002, A011, (A100, D150), (A200, D201, D150), None, (A400, D450), (A500, D550) ), ),53: ( (None, L001, A010, (A100, D152), (A200, D201, D152), (A300, D300), None, (A500, D501) ), ),55: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),56: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),59: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),61: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),62: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),64: ( (None, L002, A011, (A100, D150), (A200, D201, D150), None, (A400, D450), (A500, D551) ), ),71: ( (None, L001, A010, (A100, D155), (A200, D201, D155), (A300, D300), None, (A500, D501) ), ),72: ( (None, L001, A010, (A100, D104), (A200, D201, D104), (A300, D300), None, (A500, D501) ), ),73: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), None, (A500, D501) ), ),74: ( (None, L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), None, (A500, D500) ), ),76: ( (None, L001, A010, (A100, D102), (A200, D201, D102), (A300, D300), (A400, D102), (A500, D501) ), ),77: ( ((0.00, 3.01), L001, A010, (A100, D100), (A200, D201, D100), (A300, D300), (A400, D400), (A500, D501) ), ((3.01, 3.50), L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ((3.50, 3.61), L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), None, (A500, D501) ), ((3.61, MaxVer), L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),87: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),88: ( (None, L001, A010, (A100, D102), (A200, D201, D102), (A300, D300), (A400, D102), (A500, D501) ), ),95: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),96: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),97: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), None, (A500, D501) ), ),98: ( (None, L002, A011, (A100, D150), (A200, D201, D150), None, (A400, D450), (A500, D551) ), ),100: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),105: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),106: ( (None, L001, A010, (A100, D103), (A200, D201, D103), (A300, D300), (A400, D403), (A500, D501) ), ),112: ( (None, L001, A010, (A100, D152), (A200, D201, D152), (A300, D300), None, (A500, D501) ), )}def GetProtocols(prod_id, soft_ver): bits = ModelProtocols[prod_id] for i in bits: vrange = i[0] if ( (vrange == None) or ((soft_ver >= vrange[0]) and (soft_ver < vrange[1]))): return i raise "No protocols known for this software version. Strange!"def FormatA001(protocols): """This is here to get the list of strings returned by A001 into the same format as used in the ModelProtocols dictionary""" try: phys = eval(protocols[0]) link = eval(protocols[1]) cmnd = eval(protocols[2]) tuples = {"1" : None, "2" : None, "3" : None, "4" : None, "5" : None, "6" : None, "7" : None, "8" : None, "9" : None} last_seen = None for i in range(3, len(protocols)): p = protocols[i] if p[0] == "A": pclass = p[1] if tuples[pclass] == None: tuples[pclass] = [] last_seen = tuples[pclass] last_seen.append(eval(p)) except NameError: print sys.exc_info()[2] raise NameError, "Protocol %s not supported yet!" % sys.exc_info()[1] return (None, link, cmnd, tuples["1"], tuples["2"], tuples["3"], tuples["4"], tuples["5"])# ====================================================================# Now some practical implementationsclass SerialLink(P000): """ A serial link will look something like this, though real implementations will probably override most of it. """ def __init__(self, f, timeout = 5): self.f = f self.initserial() self.settimeout(timeout) def initserial(self): "Set up baud rate, handshaking, etc" pass def read(self, n): """ Read n bytes and return them. Real implementations should raise a LinkException if there is a timeout > self.timeout """ return self.f.read(n) def write(self, data): self.f.write(data) def settimeout(self, secs): self.timeout = secs def __del__(self): """Should close down any opened resources""" passclass UnixSerialLink(SerialLink): def __init__(self, device): f = open(device, "w+", 0) SerialLink.__init__(self, f) def initserial(self): from tty import * fd = self.f.fileno() setraw(fd) mode = tcgetattr(fd) mode[ISPEED] = mode[OSPEED] = B9600 # mode[LFLAG] = mode[LFLAG] | ECHO tcsetattr(fd, TCSAFLUSH, mode) def read(self, n): import select i = 0 data = [] while i < n: iset,oset,eset = select.select([self.f.fileno()], [], [], self.timeout) if iset == []: raise LinkException, "time out" b = self.f.read(1) data.append(b) i = i + 1 return string.join(data,'') def __del__(self): self.f.close()# Win32 Serial Link ==================================================if os.name == 'nt': from win32file import * import win32conclass Win32SerialLink(SerialLink): def __init__(self, device): self.device = device handle = CreateFile(device, win32con.GENERIC_READ | win32con.GENERIC_WRITE, 0, # exclusive access None, # no security win32con.OPEN_EXISTING, 0, None) SerialLink.__init__(self, handle) def initserial(self): # Remove anything that was there PurgeComm(self.f, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) # Setup the connection info. dcb = GetCommState( self.f ) dcb.BaudRate = CBR_9600 dcb.ByteSize = 8 dcb.Parity = NOPARITY dcb.StopBits = ONESTOPBIT SetCommState(self.f, dcb) def read(self, n): buffer = AllocateReadBuffer(n) rc, data = ReadFile(self.f, buffer) if len(data) != n: raise LinkException, "time out"; return data def write(self, n): rc,n = WriteFile(self.f, n) if rc: raise LinkException, "WriteFile error"; def settimeout(self, secs): SerialLink.settimeout(self, secs) # Setup time-outs timeouts = 0xFFFFFFFF, 0, 1000*secs, 0, 1000*secs SetCommTimeouts(self.f, timeouts) def __del__(self): CloseHandle(self.f) class Garmin: """ A representation of the GPS device, which is connected via some physical connection, typically a SerialLink of some sort. """ def __init__(self, physicalLayer): self.link = L000(physicalLayer) # at least initially (self.prod_id, self.soft_ver, self.prod_descs) = A000(self.link).getProductData() if debug > 1: print "Get supported protocols" # Wait for the unit to announce its capabilities using A001. If # that doesn't happen, try reading the protocols supported by the # unit from the Big Table. physicalLayer.settimeout(2) try: self.protocols = A001(self.link).getProtocols() protos = FormatA001(self.protocols) except LinkException, e: if debug > 2: print "PCP not supported" try: protos = GetProtocols(self.prod_id, self.soft_ver) except KeyError: raise Exception, "Couldn't determine product capabilities" physicalLayer.settimeout(5) # protos = GetProtocols(self.prod_id, self.soft_ver) (versions, self.linkProto, self.cmdProto, wptProtos, rteProtos, trkProtos, prxProtos, almProtos) = protos self.link = self.linkProto(physicalLayer) # The datatypes we expect to receive self.wptType = wptProtos[1] self.rteTypes = rteProtos[1:] self.trkTypes = trkProtos[1:] # Now we set up 'links' through which we can get data of the # appropriate types self.wptLink = wptProtos[0](self.link, self.cmdProto, (self.wptType,)) self.rteLink = rteProtos[0](self.link, self.cmdProto, self.rteTypes) self.trkLink = trkProtos[0](self.link, self.cmdProto, self.trkTypes) if prxProtos != None: self.prxType = prxProtos[1] self.prxLink = prxProtos[0](self.link, self.cmdProto, (self.prxType,)) if almProtos != None: self.almType = almProtos[1] self.almLink = almProtos[0](self.link, self.cmdProto, (self.almType,)) self.timeLink = A600(self.link, self.cmdProto, D600) self.pvtLink = A800(self.link, self.cmdProto, D800) def getWaypoints(self): return self.wptLink.getData() def putWaypoints(self, data): return self.wptLink.putData(data) def getRoutes(self): return self.rteLink.getData() def getTracks(self): data = self.trkLink.getData() if isinstance(self.trkLink, SingleTransferProtocol): return [data] # for consistency- compare A300 with A301 else: return data def getProxPoints(self): return self.prxLink.getData() def getAlmanac(self): return self.almLink.getData() def getTime(self): return self.timeLink.getData() def pvtOn(self): return self.pvtLink.dataOn() def pvtOff(self): return self.pvtLink.dataOff() def getPvt(self): return self.pvtLink.getData()# =================================================================# The following is test code. See other included files for more# useful applications.def main(): if os.name == 'nt': serialDevice = "com1" phys = Win32SerialLink(serialDevice) else: serialDevice = "/dev/ttyS0" phys = UnixSerialLink(serialDevice) gps = Garmin(phys) print "GPS Product ID: %d Descriptions: %s Software version: %2.2f" % \ (gps.prod_id, gps.prod_descs, gps.soft_ver) if 1: # show waypoints wpts = gps.getWaypoints() for w in wpts: print w if 0: # show routes routes = gps.getRoutes() for r in routes: print r[0].route_num for p in r[1:]: print p if 0: # show proximity points print gps.getProxPoints() if 0: # show track tracks = gps.getTracks() for t in tracks: for p in t: print p if 0: # show almanac print gps.getAlmanac() if 0: # show time d = gps.getTime() print d.year, d.month, d.day, d.hour, d.min, d.sec if 0: # upload a waypoint w = gps.wptType( ident="01TEST", cmnt="A TEST POINT", slat=624447295, slon=-2529985 ) gps.putWaypoints([w]) print "Uploaded", w if 0: # show some real-time data print "Starting pvt" gps.pvtOn() try: for i in range(10): p = gps.getPvt() print p finally: print "Stopping pvt" gps.pvtOff() if __name__ == "__main__": main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -