socketref,再见!高德

https://github.com/adoggie

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用链接

留言簿(54)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

  1 # -- coding:utf-8 --
  2 #TK102 解码器定义
  3 #这个设备没有包头包尾格式定义,假定一次读取一个完整数据包
  4 
  5 #from aobject import *
  6 import os,os.path,sys,time,datetime,copy,struct,array,traceback
  7 #import codec
  8 
  9 #MediaCodecType = MediaDataType
 10 class MediaDataType:    
 11     GPS   = 1<<0
 12     AUDIO = 1<<1
 13     VIDEO = 1<<2
 14     IMAGE = 1<<3
 15     TEXT =  1<<4
 16     IODATA = 1<<5
 17     RAWBLOB = 1<<6    
 18     COMMAND = 1<<7    #通用命令
 19     ALARM =  1<<8  #报警信息
 20     UNDEFINED = 0xff
 21     
 22 
 23 AOCTRL_CMD_SHAKE_ACK =1     #应答握手信号信息
 24 AOCTRL_CMD_REG_ACK= 2    #终端注册响应消息
 25 AOCTRL_CMD_SAMPLING_TIMESET = 3     #等时连续回传设置
 26 AOCTRL_CMD_ALARM_ACK = 4    #应答报警消息
 27 AOCTRL_CMD_NAMED = 5     #一次点名消息
 28 AOCTRL_CMD_SPEEDSET = 6 #设置车速上下限
 29 AOCTRL_CMD_POWER_ONOFF = 7 #电路控制信号
 30 AOCTRL_CMD_OIL_ONOFF = 8  #油路控制信号
 31 AOCTRL_CMD_REBOOT = 9         #控制设备重启消息
 32 AOCTRL_CMD_ACC_ON_TIME = 10 #设置ACC开发送数据间隔
 33 AOCTRL_CMD_ACC_OFF_TIME = 11 #设置ACC关发送数据间隔
 34 AOCTRL_CMD_BARRIER_SET = 12     #设置电子围栏消息
 35 AOCTRL_CMD_GETLOCATION = 13         #应答获取终端所在位置消息
 36 AOCTRL_CMD_LISTEN_START = 14         #监听命令
 37 AOCTRL_CMD_COMMADDR_SET = 15     #设置终端IP地址和端口
 38 AOCTRL_CMD_APN_SET = 16            # 设置APN消息
 39 AOCTRL_CMD_GET_VERSION = 17     # 读取终端版本消息
 40 AOCTRL_CMD_CLEAR_ALARMS = 18     #取消所有报警消息
 41 AOCTRL_CMD_CLEAR_MILES = 19     #里程清零消息
 42 AOCTRL_CMD_INIT_MILES = 20         #里程初始化消息
 43 AOCTRL_CMD_UPDATING = 21         #启动升级消息
 44 
 45 AOCTRL_CMD_SHACK_REQ =31 #握手信号消息
 46 AOCTRL_CMD_REG_REQ =32     #终端注册信息
 47 AOCTRL_CMD_SAMPLING_TIMESET_ACK = 32 #应答等时连续回传设置
 48 AOCTRL_CMD_ALARM_REQ = 33         #警报消息
 49 AOCTRL_CMD_NAMED_ACK = 34         #应答点名信息
 50 AOCTRL_CMD_SIMPLING_GPSDATA = 35         #等时连续回传消息
 51 AOCTRL_CMD_SIMPLING_END = 36     #连续回传结束消息
 52 AOCTRL_CMD_SPEEDSET_ACK = 37     #应答设置车速上下限
 53 AOCTRL_CMD_POWERCTRL_ACK = 38   #应答电路控制
 54 AOCTRL_CMD_OILCTRL_ACK = 39     #应答油路控制
 55 AOCTRL_CMD_REBOOT_ACK = 40         #应答设备重启消息
 56 AOCTRL_CMD_ACCON_TIMESET_ACK = 41 #应答设置ACC开发送数据间隔
 57 AOCTRL_CMD_ACCOFF_TIMESET_ACK=42 #应答设置ACC关发送数据间隔
 58 AOCTRL_CMD_BARRIER_SET_ACK =  43 #应答设置电子围栏消息
 59 AOCTRL_CMD_GETLOCATION_ACK = 44  #获取终端所在位置消息
 60 AOCTRL_CMD_LISTEN_ACK = 45         #应答监听命令
 61 AOCTRL_CMD_COMMADDR_SET_ACK=46    #应答设置终端IP地址和端口
 62 AOCTRL_CMD_APN_SET_ACK=47        #应答设置APN消息
 63 AOCTRL_CMD_GETVERSION_ACK=48    #应答读取终端版本消息
 64 AOCTRL_CMD_CLEAR_ALARMS_ACK=49    #应答取消所有报警消息
 65 AOCTRL_CMD_CLEAR_MILES_ACK=50     #应答里程清零消息
 66 AOCTRL_CMD_UPDATING_ACK = 61     #应答启动升级消息
 67 AOCTRL_CMD_INIT_MILES_ACK = 62    #应答初始化里程消息    
 68 
 69 AOCTRL_CMD_LIST={
 70     AOCTRL_CMD_SHAKE_ACK:u'应答握手信号信息',
 71     AOCTRL_CMD_REG_ACK:u'终端注册响应消息',
 72     AOCTRL_CMD_SAMPLING_TIMESET:u'等时连续回传设置',
 73     AOCTRL_CMD_ALARM_ACK:u'应答报警消息',
 74     AOCTRL_CMD_NAMED:u'一次点名消息',
 75     AOCTRL_CMD_SPEEDSET:u'设置车速上下限',
 76     
 77     AOCTRL_CMD_POWER_ONOFF:u'电路控制信号',
 78     AOCTRL_CMD_OIL_ONOFF:u'油路控制信号',
 79     AOCTRL_CMD_REBOOT:u'控制设备重启消息',
 80     AOCTRL_CMD_ACC_ON_TIME :u'设置ACC开发送数据间隔',
 81     AOCTRL_CMD_ACC_OFF_TIME :u'设置ACC关发送数据间隔',
 82     AOCTRL_CMD_BARRIER_SET :u'设置电子围栏消息',
 83     AOCTRL_CMD_GETLOCATION :u'应答获取终端所在位置消息',
 84     AOCTRL_CMD_LISTEN_START :u'监听命令',
 85     AOCTRL_CMD_COMMADDR_SET :u'设置终端IP地址和端口',
 86     AOCTRL_CMD_APN_SET :u'设置APN消息',
 87     AOCTRL_CMD_GET_VERSION :u'读取终端版本消息',
 88     AOCTRL_CMD_CLEAR_ALARMS :u'取消所有报警消息',
 89     AOCTRL_CMD_CLEAR_MILES :u'里程清零消息',
 90     AOCTRL_CMD_INIT_MILES :u'里程初始化消息',
 91     AOCTRL_CMD_UPDATING :u'启动升级消息',
 92     
 93     AOCTRL_CMD_SHACK_REQ :u'握手信号消息',
 94     AOCTRL_CMD_REG_REQ :u'终端注册信息',
 95     AOCTRL_CMD_SAMPLING_TIMESET_ACK :u'应答等时连续回传设置',
 96     AOCTRL_CMD_ALARM_REQ :u'警报消息',
 97     AOCTRL_CMD_NAMED_ACK :u'应答点名信息',
 98     AOCTRL_CMD_SIMPLING_GPSDATA :u'等时连续回传消息',
 99     AOCTRL_CMD_SIMPLING_END :u'连续回传结束消息',
100     AOCTRL_CMD_SPEEDSET_ACK :u'应答设置车速上下限',
101     AOCTRL_CMD_POWERCTRL_ACK :u'应答电路控制',
102     AOCTRL_CMD_OILCTRL_ACK :u'应答油路控制',
103     AOCTRL_CMD_REBOOT_ACK :u'应答设备重启消息',
104     AOCTRL_CMD_ACCON_TIMESET_ACK :u'应答设置ACC开发送数据间隔',
105     AOCTRL_CMD_ACCOFF_TIMESET_ACK:u'应答设置ACC关发送数据间隔',
106     AOCTRL_CMD_BARRIER_SET_ACK :u'应答设置电子围栏消息',
107     AOCTRL_CMD_GETLOCATION_ACK :u'获取终端所在位置消息',
108     AOCTRL_CMD_LISTEN_ACK :u'应答监听命令',
109     AOCTRL_CMD_COMMADDR_SET_ACK:u'应答设置终端IP地址和端口',
110     AOCTRL_CMD_APN_SET_ACK:u'应答设置APN消息',
111     AOCTRL_CMD_GETVERSION_ACK:u'应答读取终端版本消息',
112     AOCTRL_CMD_CLEAR_ALARMS_ACK:u'应答取消所有报警消息',
113     AOCTRL_CMD_CLEAR_MILES_ACK:u'应答里程清零消息',
114     AOCTRL_CMD_UPDATING_ACK :u'应答启动升级消息',
115     AOCTRL_CMD_INIT_MILES_ACK :u'应答初始化里程消息',    
116 }
117     
118     
119 ALARM_TYPELIST={
120     0:u'车辆断电',
121     1:u'电子围栏入界报警',
122     2:u'车辆劫警(SOS求助)',
123     3:u'车辆防盗器警报',
124     4:u'车辆低速报警',
125     5:u'车辆超速报警',
126     6:u'电子围栏出界报警'
127 }
128 
129 
130 def parseTime(dmy,hms):
131     d,mon,y = map(int, map(float,[dmy[:2],dmy[2:4],dmy[4:]]) )
132     h,min,s = map(int, map(float,[hms[:2],hms[2:4],hms[4:]]) )
133     print d,mon,y,h,min,s
134     return time.mktime((2000+y,mon,d,h,min,s,0,0,0))
135 
136 def parseDegree(v):
137     pp = v.split('.')
138     mm1 = pp[0][-2:]
139     mm2 = '0'
140     if len(pp)>1:
141         mm2 = pp[1]
142     dd = pp[0][:-2]
143     mm = mm1 + "." + mm2
144     degree = float(dd)+ float(mm)/60.0
145     return degree
146 
147 #1节等于每小时 1海里,也就是每小时行驶1.852千米(公里)
148 def parseSpeed(s):
149     km =0
150     km = float(s)*1.852
151     return km
152 
153 
154 #简单的模拟gps接收解码器
155 #gps接收程序解析之后连接本地的TcpService端口,并传送过来
156 #只有简单的gps数据,模拟端口打开
157 class MediaCodec_KS102:
158     def __init__(self):
159         self.buf =''
160         self.conn = None
161         self.errtimes=0    #解析出错次数达到指定数则断开连接
162     
163 
164     
165     # parse - codec 必须实现
166     #对于某些设备的请求消息,这里必须进行默认的应答
167     #如果出现大量数据包的要发送回设备的情况,考虑建立队列,用工作线程
168     # 慢慢发送,因为parse还在socket接收线程中
169     def parse(self,aom,d):
170         pass 
171 
172     def crc_16_result(self,d):
173         #struct.unpack('I')
174         print d
175         i=0
176         j=0
177         c=0
178         treat =0
179         bcrc = 0
180         crc =0
181         s =array.array('B')
182         s.fromstring(d)
183         #print len(s)
184         for i in range(len(s)):            
185             c = s[i]
186             for j in range(8):
187                 treat = c&0x80
188                 c = (c<<1)&0xff
189                 
190                 bcrc = ( crc >>8 )&0xff
191                 bcrc = bcrc&0x80
192                 #print crc
193                 crc = (crc << 1& 0xffff
194                 #print crc
195                 if treat != bcrc:
196                     crc = (crc^0x1021&0xffff
197                     #print '..',crc            
198             
199         return crc
200     
201      
202     def decode(self,s,conn):            
203         #@return:     packets,retry        
204         #解码出多个消息包,并返回是否
205         # imei 视为设备唯一编号 mid
206         self.conn = conn        
207         msglist=[]
208         retry = True
209         try:
210             p = s.find(',')
211             d = s[p+1:-2]
212             crc = s[-2:]
213             sum, = struct.unpack('H',crc)            
214             if self.crc_16_result(d) != sum:
215                 print 'crc error'
216                 return (),True
217             #13145826175,GPRMC,022011.000,A,2234.0200,N,11403.0754,E,0.00,189.47,040310,,,A*6F,F, battery,imei:354776030402512,114
218             print d
219             #print d.split(',')[-1]
220             #tel,gprmc,hms,av,lat,ns,lon,ew,speed,angle,dmy,p1,p2,mode,FL,battery,imei,msglen, = d.split(',')
221             tel,gprmc,hms,av,lat,ns,lon,ew,speed,angle,dmy,p1,p2,mode,FL,imei,msglen, = d.split(',')
222             imei = imei.split(':')[1]            
223             angle = float(angle)
224             speed = float(speed)*1.852 # 节到km转换
225             lon = parseDegree(lon)
226             lat = parseDegree(lat)
227             time = parseTime(dmy,hms)+3600*8    #时间加上GMT8
228             gps = {
229                 'time':time,
230                 'lon':lon,
231                 'lat':lat,
232                 'speed':speed,
233                 'angle':angle
234             }
235             msg = {
236                 'mid':imei,
237                 'cmd':AOCTRL_CMD_SIMPLING_GPSDATA,
238                 'gps':gps,                
239             }
240             msglist.append(msg)
241         except:
242             traceback.print_exc()
243             msglist=()
244             retry = True
245             self.errtimes+=1
246             if self.errtimes > 4#解析错误次数过多,断开连接
247                 return (),False
248         return msglist,retry
249 
250 
251     
252     #执行设备命令
253     def command(self,aom,msg):
254         # cmd - object (json decoded)
255         #@return:  返回命令控制消息
256         cmd = msg['cmd']
257         code=''
258         params=''
259         if not msg.has_key('seq'):
260             msg['seq'= '0'*12
261             
262         if cmd == AOCTRL_CMD_REG_ACK: #注册响应
263             code = "(%sAP05)"%(msg['seq'])
264 
265         #save to ctrl log         
266         log = aom.gm.AO_CtrlLog()
267         log.ao = aom.ao.dbobj
268         log.cmd = cmd
269         log.time = datetime.datetime.now()
270         text = "%s: %s"%(AOCTRL_CMD_LIST[log.cmd],params)
271         log.comment = text[:200]
272         log.save()
273         
274         return code
275     
276     #将d数据写入db中
277     # 根据不同的数据进行hash分派 目前之后gps和告警信息进行分派
278     def save(self,aom,d):        
279         #log = aom.gm.AO_CtrlLog()
280         #log.ao = aom.ao.dbobj
281         #log.cmd = d['cmd']
282         #log.time = datetime.datetime.now()
283         #text = "%s: %s"%(AOCTRL_CMD_LIST[log.cmd],d['params'])
284         #log.comment = text[:200]
285         #log.save()
286         #以下存储gps数据和设备状态数据        
287         if True:
288             # save to db
289             timestamp = gps['time']
290             g = aom.gm.AOMData_Gps()
291             g.ao = aom.ao.dbobj
292             g.savetime = datetime.datetime.fromtimestamp(timestamp)
293             g.lon = gps['lon']
294             g.lat = gps['lat']
295             g.speed = gps['speed']
296             g.angle = gps['angle']
297             g.power = 0
298             g.acc = 0
299             g.miles = 0
300             g.save()
301             #for dispatch
302             t = timestamp  #time.mktime(g.savetime.timetuple())
303             s = {'type':MediaDataType.GPS,'hwid':aom.id,
304              'lon':g.lon,'lat':g.lat,
305              'speed':g.speed,'angle':g.angle,
306              'satenum':0,'sateused':0,
307              'time':t,
308              'power':g.power,
309              'acc':g.acc,
310              'miles':g.miles}    
311             aom.dispatch(s) #分派到 cached server
312     
313     
314 '''
315 TK102方案GPRS通讯协议
316 上传数据
317 “1003040220,13145826175,GPRMC,022011.000,A,2234.0200,N,11403.0754,E,0.00,189.47,040310,,,A*6F,F, battery,imei:354776030402512,114迁”
318 
319 19个,分隔数据段
320 
321 数据解析
322 “1003040220”        
323 时间流水号:  2010年03月04日02时22分
324 
325 “13145826175”      
326 手机号码:授权情况下为授权号码,否则为最后操作tracker的手机号码,或则为空.
327 “GPRMC,022011.000,A,2234.0200,N,11403.0754,E,0.00,189.47,040310,,,A*
328 6F”    
329 GPRMC数据:GPS模块数据完整数据,单片机没有对其进行修改.
330     
331 “F”                当前GPS是否有信号:   F,表示有,L表示没有
332 “battery”          报警信息:【SOS报警:”help me”;电子砸烂报警:” Stockade”;移位报警:” move”;超速报警;” speed”;低电报警;” bat:”】,非报警数据此位置为空.
333 “imei:354776030402512”   GPRS 模块IMEI号
334 “114”                                     数据长度【13145826175,GPRMC,022011.000,A,2234.0200,N,11403.0754,E,0.00,189.47,040310,,,A*6F,F, battery,imei:354776030402512,】,括号内部的数据的长度,单位字节.
335 “迁”                CRC检验:这是两个字节的十六进制数据,有时显示为乱码,又是显示为空,因为他是十六进制。
336                                                                               计算范围【13145826175,GPRMC,022011.000,A,2234.0200,N,11403.0754,E,0.00,189.47,040310,,,A*6F,F, battery,imei:354776030402512,114】
337                                   算法如下:
338 注意:此系统unsigned int  为16bits,对于PC软件,需要对结果做 &0XFFFF运算。
339 unsigned int CRC_16(unsigned char *buf, unsigned int datalen)
340 {
341     unsigned int i;
342     unsigned char j;
343     unsigned char c, treat, bcrc;
344     unsigned int crc = 0;
345 
346     for (i = 0; i < datalen; i++)
347     {
348         c = buf[i];
349         for (j = 0; j < 8; j++)
350         {
351             treat = c & 0x80;
352             c <<= 1;
353             bcrc = (crc >> 8);
354             bcrc &= 0x80;
355             crc <<= 1;
356             if (treat != bcrc)
357                 crc ^= 0x1021;
358         }
359     }
360     return crc;
361 }
362 
363 附:GPS模块数据解释说明:
364 
365   $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh 
366   <1> UTC时间,hhmmss.sss(时分秒.毫秒)格式 
367   <2> 定位状态,A=有效定位,V=无效定位 
368   <3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输) 
369   <4> 纬度半球N(北半球)或S(南半球) 
370   <5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输) 
371   <6> 经度半球E(东经)或W(西经) 
372   <7> 地面速率(000.0~999.9节,前面的0也将被传输) 
373   <8> 地面航向(000.0~359.9度,以正北为参考基准,前面的0也将被传输) 
374   <9> UTC日期,ddmmyy(日月年)格式 
375   <10> 磁偏角(000.0~180.0度,前面的0也将被传输) 
376   <11> 磁偏角方向,E(东)或W(西) 
377   <12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
378 
379 '''
380 = MediaCodec_KS102()
381 d="1106160039,13916624477,GPRMC,163905.000,A,3104.2062,N,12130.0542,E,0.33,347.69,150611,,,D*6C,F,imei:354779033883985,105"
382 d="13916624477,GPRMC,163905.000,A,3104.2062,N,12130.0542,E,0.33,347.69,150611,,,D*6C,F,imei:354779033883985,105"
383 #print len(d)
384 #a = c.crc_16_result(d)
385 log = open('ks102_data.txt','rb')
386 = log.read()
387 print c.decode(s,None)
388 
389 
posted on 2011-06-16 21:56 放屁阿狗 阅读(625) 评论(0)  编辑 收藏 引用 所属分类: perl/python/php/lua/tcl

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理