Richard Kettlewell's log on stardate 10 vlj 2011 > Rewrites can help but they can also go badly wrong. Rewriting into a > language you don't yet know seems especially likely to fall into the > latter category!
Indeed. However, it seems to be quite "doable", as it took me from 0 knowledge of Python to come up with a solution that does only part of the thing (it's missing CRC check for GPS data and NMEA checksum, user control for changing device setup on the fly via web and few more details). Here's the code (ATTN: may wrap): #! /usr/bin/env python import asyncore import socket import string import MySQLdb import sys class Handler(asyncore.dispatcher_with_send): def handle_read(self): data = self.recv(128) #payload size data = string.lstrip(data,"\n") #sometimes a 0xOA stays data_len = len (data) #get payload length trackerID_hex = data[4:11] #tracker ID trackerID = "" #create empty string for i in trackerID_hex: trackerID += str('%02X'%ord(i)) #convert hex integer to string and append to trackerID trackerID = string.rstrip(trackerID,"F") #remove stuffed F's from tracker ID checksum = "" checksum_hex = data[data_len-4:data_len-1] #second part of command payload, checksum for i in checksum_hex: checksum += str('%02X'%ord(i)) #convert hex integer to string and append to trackerID GPSdata = data[13:data_len-4] #GPRMC - hhmmss.dd,S,xxmm.dddd,<N|S>,yyymm.dddd,<E|W>,s.s,h.h,ddmmyy l = list() l = string.split(GPSdata, ",") n = len(l) if n > 1: #hack! devices can mess the output, so just discard the data and go to another sample GPStime = l[0] GPStime = GPStime[0:2] + ":" + GPStime[2:4] + ":" + GPStime[4:6] GPSstatus = l[1] GPSlatitude = l[2] GPSlatitude = float(GPSlatitude[0:2]) + float(GPSlatitude[2:10]) / 60 GPSNS = l[3] GPSlongitude = l[4] GPSlongitude = float(GPSlongitude[0:3]) + float(GPSlongitude[3:11]) / 60 GPSEW = l[5] try: GPSspeed = float(l[6]) except ValueError: GPSspeed = 0 GPSspeed *= 1.852 try: GPSheading = float(l[7]) except ValueError: GPSheading = 0 GPSdate = l[8] GPSdate = "20" + GPSdate[4:6] + "-" + GPSdate[2:4] + "-" + GPSdate[0:2] try: conn = MySQLdb.connect (host = "localhost", user = "", passwd = "", db = "") #:p except MySQLdb.Error, e: print "Error %d: %s" % (e.args[0], e.args[1]) sys.exit (1) cursor = conn.cursor() query = "INSERT INTO data (trackerID, GPStime, GPSstatus, GPSlatitude, GPSNS, GPSlongitude, GPSEW, GPSspeed, GPSheading, GPSdate) VALUES ('" + trackerID + "', '" + GPStime + "', '" + GPSstatus + "', '" + str(GPSlatitude) + "', '" + GPSNS + "', '" + str(GPSlongitude) + "', '" + GPSEW + "', '" + str(GPSspeed) + "', '" + str(GPSheading) + "', '" + GPSdate + "')" cursor.execute (query) cursor.close () conn.commit() conn.close () class Server(asyncore.dispatcher): def __init__(self, host, port): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind((host, port)) self.listen(5) def handle_accept(self): pair = self.accept() if pair is None: pass else: sock, addr = pair print 'Incoming connection from %s' % repr(addr) handler = Handler(sock) server = Server('', 2020) asyncore.loop() C code did not parse data, but rather put the whole payload to SQL database, which would be parsed afterwards. This code takes almost twice LOC less that C code. I do, however, have some more questions (thus crosspost to comp.lang.python) - how many connections can this server handle without a problem? I'm using Asyncore module, as it can be seen. Is it necessary, due to the fact that it should serve more than thousand devices that send data every 10 seconds, to do threading (I believe that is already done with Asyncore for sockets, but what about SQL?) Any other general code suggestions (since this is the first time I write anything in Python)? TIA! -- "If you lie to the compiler, it will get its revenge." Henry Spencer 2.718281828459045235360287471352662497757247093699959574966967627.com -- http://mail.python.org/mailman/listinfo/python-list