Package ais :: Module ais_msg_6
[hide private]
[frames] | no frames]

Source Code for Module ais.ais_msg_6

  1  #!/usr/bin/env python 
  2   
  3  __version__ = '$Revision: 4791 $'.split()[1] 
  4  __date__ = '$Date: 2007-03-31 $'.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  @todo: FIX: put in a description of the message here with fields and types. 
 34  ''' 
 35   
 36  import sys 
 37  from decimal import Decimal 
 38  from BitVector import BitVector 
 39   
 40  import binary, aisstring 
 41   
 42  # FIX: check to see if these will be needed 
 43  TrueBV  = BitVector(bitstring="1") 
 44  "Why always rebuild the True bit?  This should speed things up a bunch" 
 45  FalseBV = BitVector(bitstring="0") 
 46  "Why always rebuild the False bit?  This should speed things up a bunch" 
 47   
 48   
 49  fieldList = ( 
 50          'MessageID', 
 51          'RepeatIndicator', 
 52          'UserID', 
 53          'SeqNum', 
 54          'DestinationID', 
 55          'RetransmitFlag', 
 56          'Spare', 
 57          'BinaryData', 
 58  ) 
 59   
 60  fieldListPostgres = ( 
 61          'MessageID', 
 62          'RepeatIndicator', 
 63          'UserID', 
 64          'SeqNum', 
 65          'DestinationID', 
 66          'RetransmitFlag', 
 67          'Spare', 
 68          'BinaryData', 
 69  ) 
 70   
 71  toPgFields = { 
 72  } 
 73  ''' 
 74  Go to the Postgis field names from the straight field name 
 75  ''' 
 76   
 77  fromPgFields = { 
 78  } 
 79  ''' 
 80  Go from the Postgis field names to the straight field name 
 81  ''' 
 82   
 83  pgTypes = { 
 84  } 
 85  ''' 
 86  Lookup table for each postgis field name to get its type. 
 87  ''' 
 88   
89 -def encode(params, validate=False):
90 '''Create a abm binary message payload to pack into an AIS Msg abm. 91 92 Fields in params: 93 - MessageID(uint): AIS message number. Must be 6 (field automatically set to "6") 94 - RepeatIndicator(uint): Indicated how many times a message has been repeated 95 - UserID(uint): Unique ship identification number (MMSI). Also known as the Source ID 96 - SeqNum(uint): Sequence number as described in 5.3.1. Assigned to each station 97 - DestinationID(uint): Unique ship identification number (MMSI). 98 - RetransmitFlag(bool): Should the message be restransmitted? 99 - Spare(uint): Must be 0 (field automatically set to "0") 100 - BinaryData(binary): Bits for a binary broadcast message 101 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing 102 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 103 @rtype: BitVector 104 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 105 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits. 106 ''' 107 108 bvList = [] 109 bvList.append(binary.setBitVectorSize(BitVector(intVal=6),6)) 110 if 'RepeatIndicator' in params: 111 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['RepeatIndicator']),2)) 112 else: 113 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 114 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['UserID']),30)) 115 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['SeqNum']),2)) 116 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['DestinationID']),30)) 117 if params["RetransmitFlag"]: bvList.append(TrueBV) 118 else: bvList.append(FalseBV) 119 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),1)) 120 bvList.append(params['BinaryData']) 121 122 return binary.joinBV(bvList)
123
124 -def decode(bv, validate=False):
125 '''Unpack a abm message 126 127 Fields in params: 128 - MessageID(uint): AIS message number. Must be 6 (field automatically set to "6") 129 - RepeatIndicator(uint): Indicated how many times a message has been repeated 130 - UserID(uint): Unique ship identification number (MMSI). Also known as the Source ID 131 - SeqNum(uint): Sequence number as described in 5.3.1. Assigned to each station 132 - DestinationID(uint): Unique ship identification number (MMSI). 133 - RetransmitFlag(bool): Should the message be restransmitted? 134 - Spare(uint): Must be 0 (field automatically set to "0") 135 - BinaryData(binary): Bits for a binary broadcast message 136 @type bv: BitVector 137 @param bv: Bits defining a message 138 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 139 @rtype: dict 140 @return: params 141 ''' 142 143 #Would be nice to check the bit count here.. 144 #if validate: 145 # assert (len(bv)==FIX: SOME NUMBER) 146 r = {} 147 r['MessageID']=6 148 r['RepeatIndicator']=int(bv[6:8]) 149 r['UserID']=int(bv[8:38]) 150 r['SeqNum']=int(bv[38:40]) 151 r['DestinationID']=int(bv[40:70]) 152 r['RetransmitFlag']=bool(int(bv[70:71])) 153 r['Spare']=0 154 r['BinaryData']=bv[72:] 155 return r
156
157 -def decodeMessageID(bv, validate=False):
158 return 6
159
160 -def decodeRepeatIndicator(bv, validate=False):
161 return int(bv[6:8])
162
163 -def decodeUserID(bv, validate=False):
164 return int(bv[8:38])
165
166 -def decodeSeqNum(bv, validate=False):
167 return int(bv[38:40])
168
169 -def decodeDestinationID(bv, validate=False):
170 return int(bv[40:70])
171
172 -def decodeRetransmitFlag(bv, validate=False):
173 return bool(int(bv[70:71]))
174
175 -def decodeSpare(bv, validate=False):
176 return 0
177
178 -def decodeBinaryData(bv, validate=False):
179 return bv[72:]
180 181
182 -def printHtml(params, out=sys.stdout):
183 out.write("<h3>abm<h3>\n") 184 out.write("<table border=\"1\">\n") 185 out.write("<tr bgcolor=\"orange\">\n") 186 out.write("<th align=\"left\">Field Name</th>\n") 187 out.write("<th align=\"left\">Type</th>\n") 188 out.write("<th align=\"left\">Value</th>\n") 189 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 190 out.write("<th align=\"left\">Units</th>\n") 191 out.write("\n") 192 out.write("<tr>\n") 193 out.write("<td>MessageID</td>\n") 194 out.write("<td>uint</td>\n") 195 if 'MessageID' in params: 196 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 197 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 198 out.write("</tr>\n") 199 out.write("\n") 200 out.write("<tr>\n") 201 out.write("<td>RepeatIndicator</td>\n") 202 out.write("<td>uint</td>\n") 203 if 'RepeatIndicator' in params: 204 out.write(" <td>"+str(params['RepeatIndicator'])+"</td>\n") 205 if str(params['RepeatIndicator']) in RepeatIndicatorDecodeLut: 206 out.write("<td>"+RepeatIndicatorDecodeLut[str(params['RepeatIndicator'])]+"</td>") 207 else: 208 out.write("<td><i>Missing LUT entry</i></td>") 209 out.write("</tr>\n") 210 out.write("\n") 211 out.write("<tr>\n") 212 out.write("<td>UserID</td>\n") 213 out.write("<td>uint</td>\n") 214 if 'UserID' in params: 215 out.write(" <td>"+str(params['UserID'])+"</td>\n") 216 out.write(" <td>"+str(params['UserID'])+"</td>\n") 217 out.write("</tr>\n") 218 out.write("\n") 219 out.write("<tr>\n") 220 out.write("<td>SeqNum</td>\n") 221 out.write("<td>uint</td>\n") 222 if 'SeqNum' in params: 223 out.write(" <td>"+str(params['SeqNum'])+"</td>\n") 224 out.write(" <td>"+str(params['SeqNum'])+"</td>\n") 225 out.write("</tr>\n") 226 out.write("\n") 227 out.write("<tr>\n") 228 out.write("<td>DestinationID</td>\n") 229 out.write("<td>uint</td>\n") 230 if 'DestinationID' in params: 231 out.write(" <td>"+str(params['DestinationID'])+"</td>\n") 232 out.write(" <td>"+str(params['DestinationID'])+"</td>\n") 233 out.write("</tr>\n") 234 out.write("\n") 235 out.write("<tr>\n") 236 out.write("<td>RetransmitFlag</td>\n") 237 out.write("<td>bool</td>\n") 238 if 'RetransmitFlag' in params: 239 out.write(" <td>"+str(params['RetransmitFlag'])+"</td>\n") 240 out.write(" <td>"+str(params['RetransmitFlag'])+"</td>\n") 241 out.write("</tr>\n") 242 out.write("\n") 243 out.write("<tr>\n") 244 out.write("<td>Spare</td>\n") 245 out.write("<td>uint</td>\n") 246 if 'Spare' in params: 247 out.write(" <td>"+str(params['Spare'])+"</td>\n") 248 out.write(" <td>"+str(params['Spare'])+"</td>\n") 249 out.write("</tr>\n") 250 out.write("\n") 251 out.write("<tr>\n") 252 out.write("<td>BinaryData</td>\n") 253 out.write("<td>binary</td>\n") 254 if 'BinaryData' in params: 255 out.write(" <td>"+str(params['BinaryData'])+"</td>\n") 256 out.write(" <td>"+str(params['BinaryData'])+"</td>\n") 257 out.write("</tr>\n") 258 out.write("</table>\n")
259
260 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'):
261 '''Print a abm message to stdout. 262 263 Fields in params: 264 - MessageID(uint): AIS message number. Must be 6 (field automatically set to "6") 265 - RepeatIndicator(uint): Indicated how many times a message has been repeated 266 - UserID(uint): Unique ship identification number (MMSI). Also known as the Source ID 267 - SeqNum(uint): Sequence number as described in 5.3.1. Assigned to each station 268 - DestinationID(uint): Unique ship identification number (MMSI). 269 - RetransmitFlag(bool): Should the message be restransmitted? 270 - Spare(uint): Must be 0 (field automatically set to "0") 271 - BinaryData(binary): Bits for a binary broadcast message 272 @param params: Dictionary of field names/values. 273 @param out: File like object to write to 274 @rtype: stdout 275 @return: text to out 276 ''' 277 278 if 'std'==format: 279 out.write("abm:\n") 280 if 'MessageID' in params: out.write(" MessageID: "+str(params['MessageID'])+"\n") 281 if 'RepeatIndicator' in params: out.write(" RepeatIndicator: "+str(params['RepeatIndicator'])+"\n") 282 if 'UserID' in params: out.write(" UserID: "+str(params['UserID'])+"\n") 283 if 'SeqNum' in params: out.write(" SeqNum: "+str(params['SeqNum'])+"\n") 284 if 'DestinationID' in params: out.write(" DestinationID: "+str(params['DestinationID'])+"\n") 285 if 'RetransmitFlag' in params: out.write(" RetransmitFlag: "+str(params['RetransmitFlag'])+"\n") 286 if 'Spare' in params: out.write(" Spare: "+str(params['Spare'])+"\n") 287 if 'BinaryData' in params: out.write(" BinaryData: "+str(params['BinaryData'])+"\n") 288 elif 'csv'==format: 289 if None == options.fieldList: 290 options.fieldList = fieldList 291 needComma = False; 292 for field in fieldList: 293 if needComma: out.write(',') 294 needComma = True 295 if field in params: 296 out.write(str(params[field])) 297 # else: leave it empty 298 out.write("\n") 299 elif 'html'==format: 300 printHtml(params,out) 301 elif 'sql'==format: 302 sqlInsertStr(params,out,dbType=dbType) 303 else: 304 print "ERROR: unknown format:",format 305 assert False 306 307 return # Nothing to return
308 309 RepeatIndicatorEncodeLut = { 310 'default':'0', 311 'do not repeat any more':'3', 312 } #RepeatIndicatorEncodeLut 313 314 RepeatIndicatorDecodeLut = { 315 '0':'default', 316 '3':'do not repeat any more', 317 } # RepeatIndicatorEncodeLut 318 319 ###################################################################### 320 # SQL SUPPORT 321 ###################################################################### 322
323 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 324 ,addCoastGuardFields=True 325 ,dbType='postgres' 326 ):
327 ''' 328 Return the SQL CREATE command for this message type 329 @param outfile: file like object to print to. 330 @param fields: which fields to put in the create. Defaults to all. 331 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 332 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 333 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 334 @type addCoastGuardFields: bool 335 @return: sql create string 336 @rtype: str 337 338 @see: sqlCreate 339 ''' 340 # FIX: should this sqlCreate be the same as in LaTeX (createFuncName) rather than hard coded? 341 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
342
343 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
344 ''' 345 Return the sqlhelp object to create the table. 346 347 @param fields: which fields to put in the create. Defaults to all. 348 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 349 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 350 @type addCoastGuardFields: bool 351 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 352 @return: An object that can be used to generate a return 353 @rtype: sqlhelp.create 354 ''' 355 if None == fields: fields = fieldList 356 import sqlhelp 357 c = sqlhelp.create('abm',dbType=dbType) 358 c.addPrimaryKey() 359 if 'MessageID' in fields: c.addInt ('MessageID') 360 if 'RepeatIndicator' in fields: c.addInt ('RepeatIndicator') 361 if 'UserID' in fields: c.addInt ('UserID') 362 if 'SeqNum' in fields: c.addInt ('SeqNum') 363 if 'DestinationID' in fields: c.addInt ('DestinationID') 364 if 'RetransmitFlag' in fields: c.addBool('RetransmitFlag') 365 if 'Spare' in fields: c.addInt ('Spare') 366 if 'BinaryData' in fields: c.addBitVarying('BinaryData',1024) 367 368 if addCoastGuardFields: 369 # c.addInt('cg_rssi') # Relative signal strength indicator 370 # c.addInt('cg_d') # dBm receive strength 371 # c.addInt('cg_T') # Receive timestamp from the AIS equipment 372 # c.addInt('cg_S') # Slot received in 373 # c.addVarChar('cg_x',10) # Idonno 374 c.addVarChar('cg_r',15) # Receiver station ID - should usually be an MMSI, but sometimes is a string 375 c.addInt('cg_sec') # UTC seconds since the epoch 376 377 c.addTimestamp('cg_timestamp') # UTC decoded cg_sec - not actually in the data stream 378 379 return c
380
381 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
382 ''' 383 Return the SQL INSERT command for this message type 384 @param params: dictionary of values keyed by field name 385 @param outfile: file like object to print to. 386 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 387 @return: sql create string 388 @rtype: str 389 390 @see: sqlCreate 391 ''' 392 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
393 394
395 -def sqlInsert(params,extraParams=None,dbType='postgres'):
396 ''' 397 Give the SQL INSERT statement 398 @param params: dict keyed by field name of values 399 @param extraParams: any extra fields that you have created beyond the normal ais message fields 400 @rtype: sqlhelp.insert 401 @return: insert class instance 402 @todo: allow optional type checking of params? 403 @warning: this will take invalid keys happily and do what??? 404 ''' 405 import sqlhelp 406 i = sqlhelp.insert('abm',dbType=dbType) 407 408 if dbType=='postgres': 409 finished = [] 410 for key in params: 411 if key in finished: 412 continue 413 414 if key not in toPgFields and key not in fromPgFields: 415 if type(params[key])==Decimal: i.add(key,float(params[key])) 416 else: i.add(key,params[key]) 417 else: 418 if key in fromPgFields: 419 val = params[key] 420 # Had better be a WKT type like POINT(-88.1 30.321) 421 i.addPostGIS(key,val) 422 finished.append(key) 423 else: 424 # Need to construct the type. 425 pgName = toPgFields[key] 426 #valStr='GeomFromText(\''+pgTypes[pgName]+'(' 427 valStr=pgTypes[pgName]+'(' 428 vals = [] 429 for nonPgKey in fromPgFields[pgName]: 430 vals.append(str(params[nonPgKey])) 431 finished.append(nonPgKey) 432 valStr+=' '.join(vals)+')' 433 i.addPostGIS(pgName,valStr) 434 else: 435 for key in params: 436 if type(params[key])==Decimal: i.add(key,float(params[key])) 437 else: i.add(key,params[key]) 438 439 if None != extraParams: 440 for key in extraParams: 441 i.add(key,extraParams[key]) 442 443 return i
444 445 ###################################################################### 446 # LATEX SUPPORT 447 ###################################################################### 448
449 -def latexDefinitionTable(outfile=sys.stdout 450 ):
451 ''' 452 Return the LaTeX definition table for this message type 453 @param outfile: file like object to print to. 454 @type outfile: file obj 455 @return: LaTeX table string via the outfile 456 @rtype: str 457 458 ''' 459 o = outfile 460 461 o.write(''' 462 \\begin{table}%[htb] 463 \\centering 464 \\begin{tabular}{|l|c|l|} 465 \\hline 466 Parameter & Number of bits & Description 467 \\\\ \\hline\\hline 468 MessageID & 6 & AIS message number. Must be 6 \\\\ \hline 469 RepeatIndicator & 2 & Indicated how many times a message has been repeated \\\\ \hline 470 UserID & 30 & Unique ship identification number (MMSI). Also known as the Source ID \\\\ \hline 471 SeqNum & 2 & Sequence number as described in 5.3.1. Assigned to each station \\\\ \hline 472 DestinationID & 30 & Unique ship identification number (MMSI). \\\\ \hline 473 RetransmitFlag & 1 & Should the message be restransmitted? \\\\ \hline 474 Spare & 1 & Must be 0 \\\\ \hline 475 BinaryData & -1 & Bits for a binary broadcast message\\\\ \\hline \\hline 476 Total bits & 71 & Appears to take 1 slot with 97 pad bits to fill the last slot \\\\ \\hline 477 \\end{tabular} 478 \\caption{AIS message number 8: Addressed Binary Message} 479 \\label{tab:abm} 480 \\end{table} 481 ''')
482 483 484 ###################################################################### 485 # UNIT TESTING 486 ###################################################################### 487 import unittest
488 -def testParams():
489 '''Return a params file base on the testvalue tags. 490 @rtype: dict 491 @return: params based on testvalue tags 492 ''' 493 params = {} 494 params['MessageID'] = 6 495 params['RepeatIndicator'] = 1 496 params['UserID'] = 1193046 497 params['SeqNum'] = 3 498 params['DestinationID'] = 1193047 499 params['RetransmitFlag'] = True 500 params['Spare'] = 0 501 params['BinaryData'] = BitVector(bitstring='110000101100000111100010010101001110111001101010011011111111100000110001011100001011111111101111111110011001000000010001110') 502 503 return params
504
505 -class Testabm(unittest.TestCase):
506 '''Use testvalue tag text from each type to build test case the abm message'''
507 - def testEncodeDecode(self):
508 509 params = testParams() 510 bits = encode(params) 511 r = decode(bits) 512 513 # Check that each parameter came through ok. 514 self.failUnlessEqual(r['MessageID'],params['MessageID']) 515 self.failUnlessEqual(r['RepeatIndicator'],params['RepeatIndicator']) 516 self.failUnlessEqual(r['UserID'],params['UserID']) 517 self.failUnlessEqual(r['SeqNum'],params['SeqNum']) 518 self.failUnlessEqual(r['DestinationID'],params['DestinationID']) 519 self.failUnlessEqual(r['RetransmitFlag'],params['RetransmitFlag']) 520 self.failUnlessEqual(r['Spare'],params['Spare']) 521 self.failUnlessEqual(r['BinaryData'],params['BinaryData'])
522
523 -def addMsgOptions(parser):
524 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 525 help='decode a "abm" AIS message') 526 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 527 help='encode a "abm" AIS message') 528 parser.add_option('--RepeatIndicator-field', dest='RepeatIndicatorField',default=0,metavar='uint',type='int' 529 ,help='Field parameter value [default: %default]') 530 parser.add_option('--UserID-field', dest='UserIDField',metavar='uint',type='int' 531 ,help='Field parameter value [default: %default]') 532 parser.add_option('--SeqNum-field', dest='SeqNumField',metavar='uint',type='int' 533 ,help='Field parameter value [default: %default]') 534 parser.add_option('--DestinationID-field', dest='DestinationIDField',metavar='uint',type='int' 535 ,help='Field parameter value [default: %default]') 536 parser.add_option('--RetransmitFlag-field', dest='RetransmitFlagField',metavar='bool',type='int' 537 ,help='Field parameter value [default: %default]') 538 parser.add_option('--BinaryData-field', dest='BinaryDataField',metavar='binary',type='string' 539 ,help='Field parameter value [default: %default]')
540 541 ############################################################ 542 if __name__=='__main__': 543 544 from optparse import OptionParser 545 parser = OptionParser(usage="%prog [options]", 546 version="%prog "+__version__) 547 548 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 549 help='run the documentation tests') 550 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 551 help='run the unit tests') 552 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 553 help='Make the test output verbose') 554 555 # FIX: remove nmea from binary messages. No way to build the whole packet? 556 # FIX: or build the surrounding msg 8 for a broadcast? 557 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 558 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 559 ,default='nmeapayload' 560 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 561 562 563 outputChoices = ('std','html','csv','sql' ) 564 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 565 ,default='std' 566 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 567 568 parser.add_option('-o','--output',dest='outputFileName',default=None, 569 help='Name of the python file to write [default: stdout]') 570 571 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 572 choices=fieldList, 573 help='Which fields to include in the output. Currently only for csv output [default: all]') 574 575 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 576 help='Print the field name for csv') 577 578 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 579 help='Print out an sql create command for the table.') 580 581 parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true', 582 help='Print a LaTeX table of the type') 583 584 dbChoices = ('sqlite','postgres') 585 parser.add_option('-D','--db-type',dest='dbType',default='postgres' 586 ,choices=dbChoices,type='choice' 587 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 588 589 addMsgOptions(parser) 590 591 (options,args) = parser.parse_args() 592 success=True 593 594 if options.doctest: 595 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 596 sys.argv= [sys.argv[0]] 597 if options.verbose: sys.argv.append('-v') 598 import doctest 599 numfail,numtests=doctest.testmod() 600 if numfail==0: print 'ok' 601 else: 602 print 'FAILED' 603 success=False 604 605 if not success: sys.exit('Something Failed') 606 del success # Hide success from epydoc 607 608 if options.unittest: 609 sys.argv = [sys.argv[0]] 610 if options.verbose: sys.argv.append('-v') 611 unittest.main() 612 613 outfile = sys.stdout 614 if None!=options.outputFileName: 615 outfile = file(options.outputFileName,'w') 616 617 618 if options.doEncode: 619 # First make sure all non required options are specified 620 if None==options.RepeatIndicatorField: parser.error("missing value for RepeatIndicatorField") 621 if None==options.UserIDField: parser.error("missing value for UserIDField") 622 if None==options.SeqNumField: parser.error("missing value for SeqNumField") 623 if None==options.DestinationIDField: parser.error("missing value for DestinationIDField") 624 if None==options.RetransmitFlagField: parser.error("missing value for RetransmitFlagField") 625 if None==options.BinaryDataField: parser.error("missing value for BinaryDataField") 626 msgDict={ 627 'MessageID': '6', 628 'RepeatIndicator': options.RepeatIndicatorField, 629 'UserID': options.UserIDField, 630 'SeqNum': options.SeqNumField, 631 'DestinationID': options.DestinationIDField, 632 'RetransmitFlag': options.RetransmitFlagField, 633 'Spare': '0', 634 'BinaryData': options.BinaryDataField, 635 } 636 637 bits = encode(msgDict) 638 if 'binary'==options.ioType: print str(bits) 639 elif 'nmeapayload'==options.ioType: 640 # FIX: figure out if this might be necessary at compile time 641 print "bitLen",len(bits) 642 bitLen=len(bits) 643 if bitLen%6!=0: 644 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 645 print "result:",binary.bitvectoais6(bits)[0] 646 647 648 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 649 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 650 else: sys.exit('ERROR: unknown ioType. Help!') 651 652 653 if options.sqlCreate: 654 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 655 656 if options.latexDefinitionTable: 657 latexDefinitionTable(outfile) 658 659 if options.printCsvfieldList: 660 # Make a csv separated list of fields that will be displayed for csv 661 if None == options.fieldList: options.fieldList = fieldList 662 import StringIO 663 buf = StringIO.StringIO() 664 for field in options.fieldList: 665 buf.write(field+',') 666 result = buf.getvalue() 667 if result[-1] == ',': print result[:-1] 668 else: print result 669 670 if options.doDecode: 671 for msg in args: 672 bv = None 673 674 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 675 # Found nmea 676 # FIX: do checksum 677 bv = binary.ais6tobitvec(msg.split(',')[5]) 678 else: # either binary or nmeapayload... expect mostly nmeapayloads 679 # assumes that an all 0 and 1 string can not be a nmeapayload 680 binaryMsg=True 681 for c in msg: 682 if c not in ('0','1'): 683 binaryMsg=False 684 break 685 if binaryMsg: 686 bv = BitVector(bitstring=msg) 687 else: # nmeapayload 688 bv = binary.ais6tobitvec(msg) 689 690 printFields(decode(bv) 691 ,out=outfile 692 ,format=options.outputType 693 ,fieldList=options.fieldList 694 ,dbType=options.dbType 695 ) 696