1
2
3 __version__ = '$Revision: 4791 $'.split()[1]
4 __date__ = '$Date: 2007-01-23 $'.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 elif 'sql'==format:
254 sqlInsertStr(params,out)
255 else:
256 print "ERROR: unknown format:",format
257 assert False
258
259 return
260
261 directionEncodeLut = {
262 'Down bound':'0',
263 'Up bound':'1',
264 }
265
266 directionDecodeLut = {
267 '0':'Down bound',
268 '1':'Up bound',
269 }
270
271
272
273
274
275 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None):
276 '''
277 Return the SQL CREATE command for this message type
278 @param outfile: file like object to print to.
279 @param fields: which fields to put in the create. Defaults to all.
280 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields
281 @return: sql create string
282 @rtype: str
283
284 @see: sqlCreate
285 '''
286 outfile.write(str(sqlCreate(fields,extraFields)))
287
288 -def sqlCreate(fields=None, extraFields=None):
289 '''
290 Return the sqlhelp object to create the table.
291
292 @param fields: which fields to put in the create. Defaults to all.
293 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields
294 @return: An object that can be used to generate a return
295 @rtype: sqlhelp.create
296 '''
297 if None == fields: fields = fieldList
298 import sqlhelp
299 c = sqlhelp.create('sls_lockorder')
300 if 'vessel' in fields: c.addVarChar(vessel,15)
301 if 'direction' in fields: c.addBool('direction')
302 if 'ETA_month' in fields: c.addInt ('ETA_month')
303 if 'ETA_day' in fields: c.addInt ('ETA_day')
304 if 'ETA_hour' in fields: c.addInt ('ETA_hour')
305 if 'ETA_min' in fields: c.addInt ('ETA_min')
306 if 'reserved' in fields: c.addInt ('reserved')
307
308 return c
309
310 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None):
311 '''
312 Return the SQL CREATE command for this message type
313 @param params: dictionary of values keyed by field name
314 @param outfile: file like object to print to.
315 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields
316 @return: sql create string
317 @rtype: str
318
319 @see: sqlCreate
320 '''
321 outfile.write(str(sqlInsert(params,extraParams)))
322
323
325 '''
326 Give the SQL insert statement
327 @param params: dict keyed by field name of values
328 @param extraParams: any extra fields that you have created beyond the normal ais message fields
329 @rtype: sqlhelp.insert
330 @return: insert class instance
331 @todo: allow optional type checking of params?
332 @warning: this will take invalid keys happily and do what???
333 '''
334 import sqlhelp
335 i = sqlhelp.insert('sls_lockorder')
336 for key in params: i.add(key,params[key])
337 if None != extraParams:
338 for key in extraParams:
339 i.add(key,extraParams[key])
340
341 return i
342
343
344
345
346
347 import unittest
349 '''Return a params file base on the testvalue tags.
350 @rtype: dict
351 @return: params based on testvalue tags
352 '''
353 params = {}
354 params['vessel'] = 'ICEBERG@@@@@@@@'
355 params['direction'] = True
356 params['ETA_month'] = 2
357 params['ETA_day'] = 28
358 params['ETA_hour'] = 23
359 params['ETA_min'] = 45
360 params['reserved'] = 0
361
362 return params
363
365 '''Use testvalue tag text from each type to build test case the sls_lockorder message'''
367
368 params = testParams()
369 bits = encode(params)
370 r = decode(bits)
371
372
373 self.failUnlessEqual(r['vessel'],params['vessel'])
374 self.failUnlessEqual(r['direction'],params['direction'])
375 self.failUnlessEqual(r['ETA_month'],params['ETA_month'])
376 self.failUnlessEqual(r['ETA_day'],params['ETA_day'])
377 self.failUnlessEqual(r['ETA_hour'],params['ETA_hour'])
378 self.failUnlessEqual(r['ETA_min'],params['ETA_min'])
379 self.failUnlessEqual(r['reserved'],params['reserved'])
380
382 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true',
383 help='decode a "sls_lockorder" AIS message')
384 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true',
385 help='encode a "sls_lockorder" AIS message')
386 parser.add_option('--vessel-field', dest='vesselField',default='@@@@@@@@@@@@@@@',metavar='aisstr6',type='string'
387 ,help='Field parameter value [default: %default]')
388 parser.add_option('--direction-field', dest='directionField',metavar='bool',type='int'
389 ,help='Field parameter value [default: %default]')
390 parser.add_option('--ETA_month-field', dest='ETA_monthField',metavar='uint',type='int'
391 ,help='Field parameter value [default: %default]')
392 parser.add_option('--ETA_day-field', dest='ETA_dayField',metavar='uint',type='int'
393 ,help='Field parameter value [default: %default]')
394 parser.add_option('--ETA_hour-field', dest='ETA_hourField',metavar='uint',type='int'
395 ,help='Field parameter value [default: %default]')
396 parser.add_option('--ETA_min-field', dest='ETA_minField',metavar='uint',type='int'
397 ,help='Field parameter value [default: %default]')
398
399
400 if __name__=='__main__':
401
402 from optparse import OptionParser
403 parser = OptionParser(usage="%prog [options]",
404 version="%prog "+__version__)
405
406 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true',
407 help='run the documentation tests')
408 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true',
409 help='run the unit tests')
410 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true',
411 help='Make the test output verbose')
412
413
414
415 typeChoices = ('binary','nmeapayload','nmea')
416 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType'
417 ,default='nmeapayload'
418 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]')
419
420
421 outputChoices = ('std','html','csv','sql' )
422 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType'
423 ,default='std'
424 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]')
425
426 parser.add_option('-o','--output',dest='outputFileName',default=None,
427 help='Name of the python file to write [default: stdout]')
428
429 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append',
430 choices=fieldList,
431 help='Which fields to include in the output. Currently only for csv output [default: all]')
432
433 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true',
434 help='Print the field name for csv')
435
436 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true',
437 help='Print out an sql create command for the table.')
438
439 addMsgOptions(parser)
440
441 (options,args) = parser.parse_args()
442 success=True
443
444 if options.doctest:
445 import os; print os.path.basename(sys.argv[0]), 'doctests ...',
446 sys.argv= [sys.argv[0]]
447 if options.verbose: sys.argv.append('-v')
448 import doctest
449 numfail,numtests=doctest.testmod()
450 if numfail==0: print 'ok'
451 else:
452 print 'FAILED'
453 success=False
454
455 if not success: sys.exit('Something Failed')
456 del success
457
458 if options.unittest:
459 sys.argv = [sys.argv[0]]
460 if options.verbose: sys.argv.append('-v')
461 unittest.main()
462
463 outfile = sys.stdout
464 if None!=options.outputFileName:
465 outfile = file(options.outputFileName,'w')
466
467
468 if options.doEncode:
469
470 if None==options.vesselField: parser.error("missing value for vesselField")
471 if None==options.directionField: parser.error("missing value for directionField")
472 if None==options.ETA_monthField: parser.error("missing value for ETA_monthField")
473 if None==options.ETA_dayField: parser.error("missing value for ETA_dayField")
474 if None==options.ETA_hourField: parser.error("missing value for ETA_hourField")
475 if None==options.ETA_minField: parser.error("missing value for ETA_minField")
476 msgDict={
477 'vessel': options.vesselField,
478 'direction': options.directionField,
479 'ETA_month': options.ETA_monthField,
480 'ETA_day': options.ETA_dayField,
481 'ETA_hour': options.ETA_hourField,
482 'ETA_min': options.ETA_minField,
483 'reserved': '0',
484 }
485
486 bits = encode(msgDict)
487 if 'binary'==options.ioType: print str(bits)
488 elif 'nmeapayload'==options.ioType:
489
490 print "bitLen",len(bits)
491 bitLen=len(bits)
492 if bitLen%6!=0:
493 bits = bits + BitVector(size=(6 - (bitLen%6)))
494 print "result:",binary.bitvectoais6(bits)[0]
495
496
497
498 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability")
499 else: sys.exit('ERROR: unknown ioType. Help!')
500
501
502 if options.sqlCreate:
503 sqlCreateStr(outfile,options.fieldList)
504
505 if options.printCsvfieldList:
506
507 if None == options.fieldList: options.fieldList = fieldList
508 import StringIO
509 buf = StringIO.StringIO()
510 for field in options.fieldList:
511 buf.write(field+',')
512 result = buf.getvalue()
513 if result[-1] == ',': print result[:-1]
514 else: print result
515
516 if options.doDecode:
517 for msg in args:
518 bv = None
519 if 'binary' == options.ioType: bv = BitVector(bitstring=msg)
520 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg)
521 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5])
522 else: sys.exit('ERROR: unknown ioType. Help!')
523
524 printFields(decode(bv),out=outfile,format=options.outputType,fieldList=options.fieldList)
525