1
2
3 __version__ = '$Revision: 4791 $'.split()[1]
4 __date__ = '$Date: 2007-01-18 $'.split()[1]
5 __author__ = 'xmlbinmsg'
6
7 __doc__='''
8
9 Autogenerated python functions to serialize/deserialize binary messages.
10
11 Generated by: ./aisxmlbinmsg2py.py
12
13 Need to then wrap these functions with the outer AIS packet and then
14 convert the whole binary blob to a NMEA string. Those functions are
15 not currently provided in this file.
16
17 serialize: python to ais binary
18 deserialize: ais binary to python
19
20 The generated code uses translators.py, binary.py, and aisstring.py
21 which should be packaged with the resulting files.
22
23
24 @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3
25 @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>}
26
27 @author: '''+__author__+'''
28 @version: ''' + __version__ +'''
29 @var __date__: Date of last svn commit
30 @undocumented: __version__ __author__ __doc__ parser
31 @status: under development
32 @license: Generated code has no license
33 '''
34
35 import sys
36 from decimal import Decimal
37 from BitVector import BitVector
38
39 import binary, aisstring
40
41
42 TrueBV = BitVector(bitstring="1")
43 "Why always rebuild the True bit? This should speed things up a bunch"
44 FalseBV = BitVector(bitstring="0")
45 "Why always rebuild the False bit? This should speed things up a bunch"
46
47
48 fieldList = [
49 'vessel',
50 'direction',
51 'ETA_month',
52 'ETA_day',
53 'ETA_hour',
54 'ETA_min',
55 'reserved',
56 ]
57
58 -def encode(params, validate=False):
59 '''Create a sls_lockorder binary message payload to pack into an AIS Msg sls_lockorder.
60
61 Fields in params:
62 - vessel(aisstr6): Vessel Name
63 - direction(bool): Up bound/Down bound
64 - ETA_month(uint): Estimated time of arrival month 1..12
65 - ETA_day(uint): Estimated time of arrival day of the month 1..31
66 - ETA_hour(uint): Estimated time of arrival UTC hours 0..23
67 - ETA_min(uint): Estimated time of arrival minutes
68 - reserved(uint): Reserved bits for future use (field automatically set to "0")
69 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing
70 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
71 @rtype: BitVector
72 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8
73 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits.
74 '''
75
76 bvList = []
77 if 'vessel' in params:
78 bvList.append(aisstring.encode(params['vessel'],90))
79 else:
80 bvList.append(aisstring.encode('@@@@@@@@@@@@@@@',90))
81 if params["direction"]: bvList.append(TrueBV)
82 else: bvList.append(FalseBV)
83 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['ETA_month']),4))
84 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['ETA_day']),5))
85 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['ETA_hour']),5))
86 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['ETA_min']),6))
87 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),19))
88
89 return binary.joinBV(bvList)
90
91 -def decode(bv, validate=False):
92 '''Unpack a sls_lockorder message
93
94 Fields in params:
95 - vessel(aisstr6): Vessel Name
96 - direction(bool): Up bound/Down bound
97 - ETA_month(uint): Estimated time of arrival month 1..12
98 - ETA_day(uint): Estimated time of arrival day of the month 1..31
99 - ETA_hour(uint): Estimated time of arrival UTC hours 0..23
100 - ETA_min(uint): Estimated time of arrival minutes
101 - reserved(uint): Reserved bits for future use (field automatically set to "0")
102 @type bv: BitVector
103 @param bv: Bits defining a message
104 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
105 @rtype: dict
106 @return: params
107 '''
108
109
110
111
112 r = {}
113 r['vessel']=aisstring.decode(bv[0:90])
114 r['direction']=bool(int(bv[90:91]))
115 r['ETA_month']=int(bv[91:95])
116 r['ETA_day']=int(bv[95:100])
117 r['ETA_hour']=int(bv[100:105])
118 r['ETA_min']=int(bv[105:111])
119 r['reserved']=0
120 return r
121
124
126 return bool(int(bv[90:91]))
127
129 return int(bv[91:95])
130
132 return int(bv[95:100])
133
135 return int(bv[100:105])
136
138 return int(bv[105:111])
139
141 return 0
142
143
145 out.write("<h3>sls_lockorder<h3>\n")
146 out.write("<table border=\"1\">\n")
147 out.write("<tr bgcolor=\"orange\">\n")
148 out.write("<th align=\"left\">Field Name</th>\n")
149 out.write("<th align=\"left\">Type</th>\n")
150 out.write("<th align=\"left\">Value</th>\n")
151 out.write("<th align=\"left\">Value in Lookup Table</th>\n")
152 out.write("<th align=\"left\">Units</th>\n")
153 out.write("\n")
154 out.write("<tr>\n")
155 out.write("<td>vessel</td>\n")
156 out.write("<td>aisstr6</td>\n")
157 if 'vessel' in params:
158 out.write(" <td>"+str(params['vessel'])+"</td>\n")
159 out.write(" <td>"+str(params['vessel'])+"</td>\n")
160 out.write("</tr>\n")
161 out.write("\n")
162 out.write("<tr>\n")
163 out.write("<td>direction</td>\n")
164 out.write("<td>bool</td>\n")
165 if 'direction' in params:
166 out.write(" <td>"+str(params['direction'])+"</td>\n")
167 if str(params['direction']) in directionDecodeLut:
168 out.write("<td>"+directionDecodeLut[str(params['direction'])]+"</td>")
169 else:
170 out.write("<td><i>Missing LUT entry</i></td>")
171 out.write("</tr>\n")
172 out.write("\n")
173 out.write("<tr>\n")
174 out.write("<td>ETA_month</td>\n")
175 out.write("<td>uint</td>\n")
176 if 'ETA_month' in params:
177 out.write(" <td>"+str(params['ETA_month'])+"</td>\n")
178 out.write(" <td>"+str(params['ETA_month'])+"</td>\n")
179 out.write("</tr>\n")
180 out.write("\n")
181 out.write("<tr>\n")
182 out.write("<td>ETA_day</td>\n")
183 out.write("<td>uint</td>\n")
184 if 'ETA_day' in params:
185 out.write(" <td>"+str(params['ETA_day'])+"</td>\n")
186 out.write(" <td>"+str(params['ETA_day'])+"</td>\n")
187 out.write("</tr>\n")
188 out.write("\n")
189 out.write("<tr>\n")
190 out.write("<td>ETA_hour</td>\n")
191 out.write("<td>uint</td>\n")
192 if 'ETA_hour' in params:
193 out.write(" <td>"+str(params['ETA_hour'])+"</td>\n")
194 out.write(" <td>"+str(params['ETA_hour'])+"</td>\n")
195 out.write("</tr>\n")
196 out.write("\n")
197 out.write("<tr>\n")
198 out.write("<td>ETA_min</td>\n")
199 out.write("<td>uint</td>\n")
200 if 'ETA_min' in params:
201 out.write(" <td>"+str(params['ETA_min'])+"</td>\n")
202 out.write(" <td>"+str(params['ETA_min'])+"</td>\n")
203 out.write("</tr>\n")
204 out.write("\n")
205 out.write("<tr>\n")
206 out.write("<td>reserved</td>\n")
207 out.write("<td>uint</td>\n")
208 if 'reserved' in params:
209 out.write(" <td>"+str(params['reserved'])+"</td>\n")
210 out.write(" <td>"+str(params['reserved'])+"</td>\n")
211 out.write("</tr>\n")
212 out.write("</table>\n")
213
214 -def printFields(params, out=sys.stdout, format='std', fieldList=None):
215 '''Print a reserved message to stdout.
216
217 Fields in params:
218 - vessel(aisstr6): Vessel Name
219 - direction(bool): Up bound/Down bound
220 - ETA_month(uint): Estimated time of arrival month 1..12
221 - ETA_day(uint): Estimated time of arrival day of the month 1..31
222 - ETA_hour(uint): Estimated time of arrival UTC hours 0..23
223 - ETA_min(uint): Estimated time of arrival minutes
224 - reserved(uint): Reserved bits for future use (field automatically set to "0")
225 @param params: Dictionary of field names/values.
226 @param out: File like object to write to
227 @rtype: stdout
228 @return: text to out
229 '''
230
231 if 'std'==format:
232 out.write("reserved:\n")
233 if 'vessel' in params: out.write(" vessel: "+str(params['vessel'])+"\n")
234 if 'direction' in params: out.write(" direction: "+str(params['direction'])+"\n")
235 if 'ETA_month' in params: out.write(" ETA_month: "+str(params['ETA_month'])+"\n")
236 if 'ETA_day' in params: out.write(" ETA_day: "+str(params['ETA_day'])+"\n")
237 if 'ETA_hour' in params: out.write(" ETA_hour: "+str(params['ETA_hour'])+"\n")
238 if 'ETA_min' in params: out.write(" ETA_min: "+str(params['ETA_min'])+"\n")
239 if 'reserved' in params: out.write(" reserved: "+str(params['reserved'])+"\n")
240 elif 'csv'==format:
241 if None == options.fieldList:
242 options.fieldList = fieldList
243 needComma = False;
244 for field in fieldList:
245 if needComma: out.write(',')
246 needComma = True
247 if field in params:
248 out.write(str(params[field]))
249
250 out.write("\n")
251 elif 'html'==format:
252 printHtml(params,out)
253 else:
254 print "ERROR: unknown format:",format
255 assert False
256
257 return
258
259 directionEncodeLut = {
260 'Down bound':'0',
261 'Up bound':'1',
262 }
263
264 directionDecodeLut = {
265 '0':'Down bound',
266 '1':'Up bound',
267 }
268
269
270
271
272
273
274 import unittest
276 '''Return a params file base on the testvalue tags.
277 @rtype: dict
278 @return: params based on testvalue tags
279 '''
280 params = {}
281 params['vessel'] = 'ICEBERG@@@@@@@@'
282 params['direction'] = True
283 params['ETA_month'] = 2
284 params['ETA_day'] = 28
285 params['ETA_hour'] = 23
286 params['ETA_min'] = 45
287 params['reserved'] = 0
288
289 return params
290
292 '''Use testvalue tag text from each type to build test case the sls_lockorder message'''
294
295 params = testParams()
296 bits = encode(params)
297 r = decode(bits)
298
299
300 self.failUnlessEqual(r['vessel'],params['vessel'])
301 self.failUnlessEqual(r['direction'],params['direction'])
302 self.failUnlessEqual(r['ETA_month'],params['ETA_month'])
303 self.failUnlessEqual(r['ETA_day'],params['ETA_day'])
304 self.failUnlessEqual(r['ETA_hour'],params['ETA_hour'])
305 self.failUnlessEqual(r['ETA_min'],params['ETA_min'])
306 self.failUnlessEqual(r['reserved'],params['reserved'])
307
309 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true',
310 help='decode a "sls_lockorder" AIS message')
311 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true',
312 help='encode a "sls_lockorder" AIS message')
313 parser.add_option('--vessel-field', dest='vesselField',default='@@@@@@@@@@@@@@@',metavar='aisstr6',type='string'
314 ,help='Field parameter value [default: %default]')
315 parser.add_option('--direction-field', dest='directionField',metavar='bool',type='int'
316 ,help='Field parameter value [default: %default]')
317 parser.add_option('--ETA_month-field', dest='ETA_monthField',metavar='uint',type='int'
318 ,help='Field parameter value [default: %default]')
319 parser.add_option('--ETA_day-field', dest='ETA_dayField',metavar='uint',type='int'
320 ,help='Field parameter value [default: %default]')
321 parser.add_option('--ETA_hour-field', dest='ETA_hourField',metavar='uint',type='int'
322 ,help='Field parameter value [default: %default]')
323 parser.add_option('--ETA_min-field', dest='ETA_minField',metavar='uint',type='int'
324 ,help='Field parameter value [default: %default]')
325
326
327 if __name__=='__main__':
328
329 from optparse import OptionParser
330 parser = OptionParser(usage="%prog [options]",
331 version="%prog "+__version__)
332
333 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true',
334 help='run the documentation tests')
335 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true',
336 help='run the unit tests')
337 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true',
338 help='Make the test output verbose')
339
340
341
342 typeChoices = ('binary','nmeapayload','nmea')
343 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType'
344 ,default='nmeapayload'
345 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]')
346
347
348 outputChoices = ('std','html','csv' )
349 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType'
350 ,default='std'
351 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]')
352
353 parser.add_option('-o','--output',dest='outputFileName',default=None,
354 help='Name of the python file to write [default: stdout]')
355
356 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append',
357 choices=fieldList,
358 help='Which fields to include in the output. Currently only for csv output [default: all]')
359
360 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true',
361 help='Print the field name for csv')
362
363 addMsgOptions(parser)
364
365 (options,args) = parser.parse_args()
366 success=True
367
368 if options.doctest:
369 import os; print os.path.basename(sys.argv[0]), 'doctests ...',
370 sys.argv= [sys.argv[0]]
371 if options.verbose: sys.argv.append('-v')
372 import doctest
373 numfail,numtests=doctest.testmod()
374 if numfail==0: print 'ok'
375 else:
376 print 'FAILED'
377 success=False
378
379 if not success: sys.exit('Something Failed')
380 del success
381
382 if options.unittest:
383 sys.argv = [sys.argv[0]]
384 if options.verbose: sys.argv.append('-v')
385 unittest.main()
386
387 outfile = sys.stdout
388 if None!=options.outputFileName:
389 outfile = file(options.outputFileName,'w')
390
391
392 if options.doEncode:
393
394 if None==options.vesselField: parser.error("missing value for vesselField")
395 if None==options.directionField: parser.error("missing value for directionField")
396 if None==options.ETA_monthField: parser.error("missing value for ETA_monthField")
397 if None==options.ETA_dayField: parser.error("missing value for ETA_dayField")
398 if None==options.ETA_hourField: parser.error("missing value for ETA_hourField")
399 if None==options.ETA_minField: parser.error("missing value for ETA_minField")
400 msgDict={
401 'vessel': options.vesselField,
402 'direction': options.directionField,
403 'ETA_month': options.ETA_monthField,
404 'ETA_day': options.ETA_dayField,
405 'ETA_hour': options.ETA_hourField,
406 'ETA_min': options.ETA_minField,
407 'reserved': '0',
408 }
409
410 bits = encode(msgDict)
411 if 'binary'==options.ioType: print str(bits)
412 elif 'nmeapayload'==options.ioType:
413
414 print "bitLen",len(bits)
415 bitLen=len(bits)
416 if bitLen%6!=0:
417 bits = bits + BitVector(size=(6 - (bitLen%6)))
418 print "result:",binary.bitvectoais6(bits)[0]
419
420
421
422 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability")
423 else: sys.exit('ERROR: unknown ioType. Help!')
424
425 if options.printCsvfieldList:
426
427 if None == options.fieldList: options.fieldList = fieldList
428 import StringIO
429 buf = StringIO.StringIO()
430 for field in options.fieldList:
431 buf.write(field+',')
432 result = buf.getvalue()
433 if result[-1] == ',': print result[:-1]
434 else: print result
435
436 if options.doDecode:
437 for msg in args:
438 bv = None
439 if 'binary' == options.ioType: bv = BitVector(bitstring=msg)
440 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg)
441 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5])
442 else: sys.exit('ERROR: unknown ioType. Help!')
443
444 printFields(decode(bv),out=outfile,format=options.outputType,fieldList=options.fieldList)
445