1
2
3 __version__ = '$Revision: 8143 $'.split()[1]
4 __date__ = '$Date: 2008-01-07 19:19:20 -0500 (Mon, 07 Jan 2008) $'.split()[1]
5 __author__ = 'Kurt Schwehr'
6
7 __doc__='''
8 Normalize AIS messages so that each message takes exactly one line. Works
9 like a Queue. Messages must use the uscg format.
10
11 Rewrite from the command line only ais_normalize
12
13 @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3
14 @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>}
15
16 @author: U{'''+__author__+'''<http://schwehr.org/>}
17 @version: ''' + __version__ +'''
18 @var __date__: Date of last svn commit
19 @undocumented: __version__ __author__ __doc__ parser
20 @status: under development
21 @license: GPL v2
22 @since: 2008-Jan-30
23 @organization: U{CCOM<http://ccom.unh.edu/>}
24 @see: U{Queue<http://www.python.org/doc/current/lib/QueueObjects.html>}
25 '''
26
27
28 import Queue
29 import uscg
30 import ais.nmea
31
32
33
34
35
36
37
38
40 '''
41 Provide a channel that normalizes messages. Try to model it like a Queue.
42 '''
43 - def __init__(self,maxsize=0,ttl=30,verbose=False):
44 '''
45 param ttl: number of seconds that a message fragment can live
46 '''
47 Queue.Queue.__init__(self,maxsize)
48 self.mostRecentTime=0
49 self.ttl=ttl
50 self.stations={}
51 self.v=verbose
52
54 '''
55 Drop messages older than the ttl
56 '''
57 pass
58
59 - def put(self,uscgNmeaStr,block=True,timeout=None):
60
61 cgMsg = uscg.UscgNmea(uscgNmeaStr)
62 if self.mostRecentTime<cgMsg.cg_sec:
63 self.mostRecentTime = cgMsg.cg_sec
64
65
66
67 if 1 == cgMsg.totalSentences:
68 Queue.Queue.put(self,uscgNmeaStr,block,timeout)
69 return
70
71 if cgMsg.sentenceNum!=cgMsg.totalSentences:
72 station = cgMsg.station
73 if station not in self.stations:
74 self.stations[station] = [cgMsg,]
75 else:
76
77 self.stations[station].append(cgMsg)
78 self.cull()
79 return
80
81
82
83
84 if cgMsg.station not in self.stations:
85 sys.stderr.write('dropping dangling fragment\n')
86 return
87
88 cgMsgFinal = cgMsg
89 stationList = self.stations[cgMsgFinal.station]
90
91 parts=[]
92 payloads=[]
93
94 del cgMsg
95
96 for msg in stationList:
97 if (msg.aisChannel == cgMsgFinal.aisChannel
98 and msg.sequentialMsgId == cgMsgFinal.sequentialMsgId
99 ):
100 if msg.sentenceNum==1:
101 cgMsgFinal.cg_sec=msg.cg_sec
102 parts.append(msg)
103 payloads.append(msg.contents)
104 assert(msg.fillbits==0)
105
106
107
108
109 for cgMsg in parts:
110 stationList.remove(cgMsg)
111
112
113 if len(parts)!=cgMsgFinal.totalSentences-1:
114 if self.v: sys.stderr.write('partial message. Discarding\n')
115 return
116
117 payloads.append(cgMsgFinal.contents)
118
119
120
121
122 payload = ''.join(payloads)
123
124
125
126 cgMsgFinal.totalSentences=1
127 cgMsgFinal.sentenceNum=1
128 cgMsgFinal.contents = payload
129 cgMsgFinal.checksumStr = ais.nmea.checksumStr(payload)
130 newNmeaStr = cgMsgFinal.buildNmea()
131
132 Queue.Queue.put(self,newNmeaStr,block,timeout)
133