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

Source Code for Module ais.whalenotice

  1  #!/usr/bin/env python 
  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  # FIX: check to see if these will be needed 
 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 -def encode(params, validate=False):
49 '''Create a whalenotice binary message payload to pack into an AIS Msg whalenotice. 50 51 Fields in params: 52 - dac(uint): Designated Area Code (field automatically set to "366") 53 - fid(uint): Functional Identifier (field automatically set to "1") 54 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2") 55 - timetag_month(uint): Time whale was last recorded month 1..12 56 - timetag_day(uint): Time whale was last recorded day of the month 1..31 57 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23 58 - timetag_min(uint): Time whale was last recorded minutes 59 - timetag_sec(uint): Time whale was last recorded seconds 60 - stationid(aisstr6): Character identifier of the station. Usually a number. 61 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 62 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 63 - whale_longitude(decimal): Where was the whale East West location 64 - whale_latitude(decimal): Where was the whale North South location 65 - timetoexpire(uint): Seconds until this notice expires 66 - radius(uint): Distance of the required exclusion/slow zone 67 - heading(uint): Direction the whale is traveling 68 - numWhales(uint): Number of whales detected 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 bvList.append(binary.setBitVectorSize(BitVector(intVal=366),16)) 78 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),4)) 79 bvList.append(binary.setBitVectorSize(BitVector(intVal=2),12)) 80 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_month']),4)) 81 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_day']),5)) 82 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_hour']),5)) 83 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_min']),6)) 84 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_sec']),6)) 85 if 'stationid' in params: 86 bvList.append(aisstring.encode(params['stationid'],42)) 87 else: 88 bvList.append(aisstring.encode('@@@@@@@',42)) 89 if 'station_longitude' in params: 90 bvList.append(binary.bvFromSignedInt(int(Decimal(params['station_longitude'])*Decimal('600000')),28)) 91 else: 92 bvList.append(binary.bvFromSignedInt(108600000,28)) 93 if 'station_latitude' in params: 94 bvList.append(binary.bvFromSignedInt(int(Decimal(params['station_latitude'])*Decimal('600000')),27)) 95 else: 96 bvList.append(binary.bvFromSignedInt(54600000,27)) 97 if 'whale_longitude' in params: 98 bvList.append(binary.bvFromSignedInt(int(Decimal(params['whale_longitude'])*Decimal('600000')),28)) 99 else: 100 bvList.append(binary.bvFromSignedInt(108600000,28)) 101 if 'whale_latitude' in params: 102 bvList.append(binary.bvFromSignedInt(int(Decimal(params['whale_latitude'])*Decimal('600000')),27)) 103 else: 104 bvList.append(binary.bvFromSignedInt(54600000,27)) 105 if 'timetoexpire' in params: 106 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetoexpire']),16)) 107 else: 108 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),16)) 109 if 'radius' in params: 110 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['radius']),16)) 111 else: 112 bvList.append(binary.setBitVectorSize(BitVector(intVal=65534),16)) 113 if 'heading' in params: 114 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['heading']),9)) 115 else: 116 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 117 if 'numWhales' in params: 118 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['numWhales']),8)) 119 else: 120 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),8)) 121 122 return binary.joinBV(bvList)
123
124 -def decode(bv, validate=False):
125 '''Unpack a whalenotice message 126 127 Fields in params: 128 - dac(uint): Designated Area Code (field automatically set to "366") 129 - fid(uint): Functional Identifier (field automatically set to "1") 130 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2") 131 - timetag_month(uint): Time whale was last recorded month 1..12 132 - timetag_day(uint): Time whale was last recorded day of the month 1..31 133 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23 134 - timetag_min(uint): Time whale was last recorded minutes 135 - timetag_sec(uint): Time whale was last recorded seconds 136 - stationid(aisstr6): Character identifier of the station. Usually a number. 137 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 138 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 139 - whale_longitude(decimal): Where was the whale East West location 140 - whale_latitude(decimal): Where was the whale North South location 141 - timetoexpire(uint): Seconds until this notice expires 142 - radius(uint): Distance of the required exclusion/slow zone 143 - heading(uint): Direction the whale is traveling 144 - numWhales(uint): Number of whales detected 145 @type bv: BitVector 146 @param bv: Bits defining a message 147 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 148 @rtype: dict 149 @return: params 150 ''' 151 152 #Would be nice to check the bit count here.. 153 #if validate: 154 # assert (len(bv)==FIX: SOME NUMBER) 155 r = {} 156 r['dac']=366 157 r['fid']=1 158 r['efid']=2 159 r['timetag_month']=int(bv[32:36]) 160 r['timetag_day']=int(bv[36:41]) 161 r['timetag_hour']=int(bv[41:46]) 162 r['timetag_min']=int(bv[46:52]) 163 r['timetag_sec']=int(bv[52:58]) 164 r['stationid']=aisstring.decode(bv[58:100]) 165 r['station_longitude']=Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000') 166 r['station_latitude']=Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000') 167 r['whale_longitude']=Decimal(binary.signedIntFromBV(bv[155:183]))/Decimal('600000') 168 r['whale_latitude']=Decimal(binary.signedIntFromBV(bv[183:210]))/Decimal('600000') 169 r['timetoexpire']=int(bv[210:226]) 170 r['radius']=int(bv[226:242]) 171 r['heading']=int(bv[242:251]) 172 r['numWhales']=int(bv[251:259]) 173 return r
174
175 -def decodedac(bv, validate=False):
176 return 366
177
178 -def decodefid(bv, validate=False):
179 return 1
180
181 -def decodeefid(bv, validate=False):
182 return 2
183
184 -def decodetimetag_month(bv, validate=False):
185 return int(bv[32:36])
186
187 -def decodetimetag_day(bv, validate=False):
188 return int(bv[36:41])
189
190 -def decodetimetag_hour(bv, validate=False):
191 return int(bv[41:46])
192
193 -def decodetimetag_min(bv, validate=False):
194 return int(bv[46:52])
195
196 -def decodetimetag_sec(bv, validate=False):
197 return int(bv[52:58])
198
199 -def decodestationid(bv, validate=False):
200 return aisstring.decode(bv[58:100])
201
202 -def decodestation_longitude(bv, validate=False):
203 return Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000')
204
205 -def decodestation_latitude(bv, validate=False):
206 return Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000')
207
208 -def decodewhale_longitude(bv, validate=False):
209 return Decimal(binary.signedIntFromBV(bv[155:183]))/Decimal('600000')
210
211 -def decodewhale_latitude(bv, validate=False):
212 return Decimal(binary.signedIntFromBV(bv[183:210]))/Decimal('600000')
213
214 -def decodetimetoexpire(bv, validate=False):
215 return int(bv[210:226])
216
217 -def decoderadius(bv, validate=False):
218 return int(bv[226:242])
219
220 -def decodeheading(bv, validate=False):
221 return int(bv[242:251])
222
223 -def decodenumWhales(bv, validate=False):
224 return int(bv[251:259])
225 226
227 -def printHtml(params, out=sys.stdout):
228 out.write("<h3>whalenotice<h3>\n") 229 out.write("<table border=\"1\">\n") 230 out.write("<tr bgcolor=\"orange\">\n") 231 out.write("<th align=\"left\">Field Name</th>\n") 232 out.write("<th align=\"left\">Type</th>\n") 233 out.write("<th align=\"left\">Value</th>\n") 234 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 235 out.write("<th align=\"left\">Units</th>\n") 236 out.write("\n") 237 out.write("<tr>\n") 238 out.write("<td>dac</td>\n") 239 out.write("<td>uint</td>\n") 240 if 'dac' in params: 241 out.write(" <td>"+str(params['dac'])+"</td>\n") 242 out.write(" <td>"+str(params['dac'])+"</td>\n") 243 out.write("</tr>\n") 244 out.write("\n") 245 out.write("<tr>\n") 246 out.write("<td>fid</td>\n") 247 out.write("<td>uint</td>\n") 248 if 'fid' in params: 249 out.write(" <td>"+str(params['fid'])+"</td>\n") 250 out.write(" <td>"+str(params['fid'])+"</td>\n") 251 out.write("</tr>\n") 252 out.write("\n") 253 out.write("<tr>\n") 254 out.write("<td>efid</td>\n") 255 out.write("<td>uint</td>\n") 256 if 'efid' in params: 257 out.write(" <td>"+str(params['efid'])+"</td>\n") 258 out.write(" <td>"+str(params['efid'])+"</td>\n") 259 out.write("</tr>\n") 260 out.write("\n") 261 out.write("<tr>\n") 262 out.write("<td>timetag_month</td>\n") 263 out.write("<td>uint</td>\n") 264 if 'timetag_month' in params: 265 out.write(" <td>"+str(params['timetag_month'])+"</td>\n") 266 out.write(" <td>"+str(params['timetag_month'])+"</td>\n") 267 out.write("</tr>\n") 268 out.write("\n") 269 out.write("<tr>\n") 270 out.write("<td>timetag_day</td>\n") 271 out.write("<td>uint</td>\n") 272 if 'timetag_day' in params: 273 out.write(" <td>"+str(params['timetag_day'])+"</td>\n") 274 out.write(" <td>"+str(params['timetag_day'])+"</td>\n") 275 out.write("</tr>\n") 276 out.write("\n") 277 out.write("<tr>\n") 278 out.write("<td>timetag_hour</td>\n") 279 out.write("<td>uint</td>\n") 280 if 'timetag_hour' in params: 281 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n") 282 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n") 283 out.write("</tr>\n") 284 out.write("\n") 285 out.write("<tr>\n") 286 out.write("<td>timetag_min</td>\n") 287 out.write("<td>uint</td>\n") 288 if 'timetag_min' in params: 289 out.write(" <td>"+str(params['timetag_min'])+"</td>\n") 290 out.write(" <td>"+str(params['timetag_min'])+"</td>\n") 291 out.write("</tr>\n") 292 out.write("\n") 293 out.write("<tr>\n") 294 out.write("<td>timetag_sec</td>\n") 295 out.write("<td>uint</td>\n") 296 if 'timetag_sec' in params: 297 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n") 298 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n") 299 out.write("</tr>\n") 300 out.write("\n") 301 out.write("<tr>\n") 302 out.write("<td>stationid</td>\n") 303 out.write("<td>aisstr6</td>\n") 304 if 'stationid' in params: 305 out.write(" <td>"+str(params['stationid'])+"</td>\n") 306 out.write(" <td>"+str(params['stationid'])+"</td>\n") 307 out.write("</tr>\n") 308 out.write("\n") 309 out.write("<tr>\n") 310 out.write("<td>station_longitude</td>\n") 311 out.write("<td>decimal</td>\n") 312 if 'station_longitude' in params: 313 out.write(" <td>"+str(params['station_longitude'])+"</td>\n") 314 out.write(" <td>"+str(params['station_longitude'])+"</td>\n") 315 out.write("<td>degrees</td>\n") 316 out.write("</tr>\n") 317 out.write("\n") 318 out.write("<tr>\n") 319 out.write("<td>station_latitude</td>\n") 320 out.write("<td>decimal</td>\n") 321 if 'station_latitude' in params: 322 out.write(" <td>"+str(params['station_latitude'])+"</td>\n") 323 out.write(" <td>"+str(params['station_latitude'])+"</td>\n") 324 out.write("<td>degrees</td>\n") 325 out.write("</tr>\n") 326 out.write("\n") 327 out.write("<tr>\n") 328 out.write("<td>whale_longitude</td>\n") 329 out.write("<td>decimal</td>\n") 330 if 'whale_longitude' in params: 331 out.write(" <td>"+str(params['whale_longitude'])+"</td>\n") 332 out.write(" <td>"+str(params['whale_longitude'])+"</td>\n") 333 out.write("<td>degrees</td>\n") 334 out.write("</tr>\n") 335 out.write("\n") 336 out.write("<tr>\n") 337 out.write("<td>whale_latitude</td>\n") 338 out.write("<td>decimal</td>\n") 339 if 'whale_latitude' in params: 340 out.write(" <td>"+str(params['whale_latitude'])+"</td>\n") 341 out.write(" <td>"+str(params['whale_latitude'])+"</td>\n") 342 out.write("<td>degrees</td>\n") 343 out.write("</tr>\n") 344 out.write("\n") 345 out.write("<tr>\n") 346 out.write("<td>timetoexpire</td>\n") 347 out.write("<td>uint</td>\n") 348 if 'timetoexpire' in params: 349 out.write(" <td>"+str(params['timetoexpire'])+"</td>\n") 350 out.write(" <td>"+str(params['timetoexpire'])+"</td>\n") 351 out.write("<td>seconds</td>\n") 352 out.write("</tr>\n") 353 out.write("\n") 354 out.write("<tr>\n") 355 out.write("<td>radius</td>\n") 356 out.write("<td>uint</td>\n") 357 if 'radius' in params: 358 out.write(" <td>"+str(params['radius'])+"</td>\n") 359 out.write(" <td>"+str(params['radius'])+"</td>\n") 360 out.write("<td>m</td>\n") 361 out.write("</tr>\n") 362 out.write("\n") 363 out.write("<tr>\n") 364 out.write("<td>heading</td>\n") 365 out.write("<td>uint</td>\n") 366 if 'heading' in params: 367 out.write(" <td>"+str(params['heading'])+"</td>\n") 368 out.write(" <td>"+str(params['heading'])+"</td>\n") 369 out.write("<td>degrees true north</td>\n") 370 out.write("</tr>\n") 371 out.write("\n") 372 out.write("<tr>\n") 373 out.write("<td>numWhales</td>\n") 374 out.write("<td>uint</td>\n") 375 if 'numWhales' in params: 376 out.write(" <td>"+str(params['numWhales'])+"</td>\n") 377 out.write(" <td>"+str(params['numWhales'])+"</td>\n") 378 out.write("</tr>\n") 379 out.write("</table>\n")
380
381 -def printKml(params, out=sys.stdout):
382 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer''' 383 out.write("\ <Placemark>\n") 384 out.write("\t <name>"+str(params['stationsid'])+"</name>\n") 385 out.write("\t\t<description>\n") 386 import StringIO 387 buf = StringIO.StringIO() 388 printHtml(params,buf) 389 import cgi 390 out.write(cgi.escape(buf.getvalue())) 391 out.write("\t\t</description>\n") 392 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n") 393 out.write("\t\t<Point>\n") 394 out.write("\t\t\t<coordinates>") 395 out.write(str(params['station_longitude'])) 396 out.write(',') 397 out.write(str(params['station_latitude'])) 398 out.write(",0</coordinates>\n") 399 out.write("\t\t</Point>\n") 400 out.write("\t</Placemark>\n")
401
402 -def printFields(params, out=sys.stdout, format='std'):
403 '''Print a numWhales message to stdout. 404 405 Fields in params: 406 - dac(uint): Designated Area Code (field automatically set to "366") 407 - fid(uint): Functional Identifier (field automatically set to "1") 408 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2") 409 - timetag_month(uint): Time whale was last recorded month 1..12 410 - timetag_day(uint): Time whale was last recorded day of the month 1..31 411 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23 412 - timetag_min(uint): Time whale was last recorded minutes 413 - timetag_sec(uint): Time whale was last recorded seconds 414 - stationid(aisstr6): Character identifier of the station. Usually a number. 415 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 416 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 417 - whale_longitude(decimal): Where was the whale East West location 418 - whale_latitude(decimal): Where was the whale North South location 419 - timetoexpire(uint): Seconds until this notice expires 420 - radius(uint): Distance of the required exclusion/slow zone 421 - heading(uint): Direction the whale is traveling 422 - numWhales(uint): Number of whales detected 423 @param params: Dictionary of field names/values. 424 @param out: File like object to write to 425 @rtype: stdout 426 @return: text to out 427 ''' 428 429 if 'std'==format: 430 out.write("numWhales:\n") 431 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n") 432 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n") 433 if 'efid' in params: out.write(" efid: "+str(params['efid'])+"\n") 434 if 'timetag_month' in params: out.write(" timetag_month: "+str(params['timetag_month'])+"\n") 435 if 'timetag_day' in params: out.write(" timetag_day: "+str(params['timetag_day'])+"\n") 436 if 'timetag_hour' in params: out.write(" timetag_hour: "+str(params['timetag_hour'])+"\n") 437 if 'timetag_min' in params: out.write(" timetag_min: "+str(params['timetag_min'])+"\n") 438 if 'timetag_sec' in params: out.write(" timetag_sec: "+str(params['timetag_sec'])+"\n") 439 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n") 440 if 'station_longitude' in params: out.write(" station_longitude: "+str(params['station_longitude'])+"\n") 441 if 'station_latitude' in params: out.write(" station_latitude: "+str(params['station_latitude'])+"\n") 442 if 'whale_longitude' in params: out.write(" whale_longitude: "+str(params['whale_longitude'])+"\n") 443 if 'whale_latitude' in params: out.write(" whale_latitude: "+str(params['whale_latitude'])+"\n") 444 if 'timetoexpire' in params: out.write(" timetoexpire: "+str(params['timetoexpire'])+"\n") 445 if 'radius' in params: out.write(" radius: "+str(params['radius'])+"\n") 446 if 'heading' in params: out.write(" heading: "+str(params['heading'])+"\n") 447 if 'numWhales' in params: out.write(" numWhales: "+str(params['numWhales'])+"\n") 448 elif 'html'==format: 449 printHtml(params,out) 450 elif 'kml'==format: 451 printKml(params,out) 452 elif 'kml-full'==format: 453 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 454 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n") 455 out.write("<Document>\n") 456 out.write(" <name>Position</name>\n") 457 printKml(params,out) 458 out.write("</Document>\n") 459 out.write("</kml>\n") 460 else: 461 print "ERROR: unknown format:",format 462 assert False 463 464 return # Nothing to return
465 466 467 468 ###################################################################### 469 # UNIT TESTING 470 ###################################################################### 471 import unittest
472 -def testParams():
473 '''Return a params file base on the testvalue tags. 474 @rtype: dict 475 @return: params based on testvalue tags 476 ''' 477 params = {} 478 params['dac'] = 366 479 params['fid'] = 1 480 params['efid'] = 2 481 params['timetag_month'] = 2 482 params['timetag_day'] = 28 483 params['timetag_hour'] = 23 484 params['timetag_min'] = 45 485 params['timetag_sec'] = 58 486 params['stationid'] = 'A234567' 487 params['station_longitude'] = Decimal('-122.16328055555556') 488 params['station_latitude'] = Decimal('37.424458333333334') 489 params['whale_longitude'] = Decimal('-122.16328055555556') 490 params['whale_latitude'] = Decimal('37.424458333333334') 491 params['timetoexpire'] = 1 492 params['radius'] = 5000 493 params['heading'] = 35 494 params['numWhales'] = 2 495 496 return params
497
498 -class Testwhalenotice(unittest.TestCase):
499 '''Use testvalue tag text from each type to build test case the whalenotice message'''
500 - def testEncodeDecode(self):
501 502 params = testParams() 503 bits = encode(params) 504 r = decode(bits) 505 506 # Check that each parameter came through ok. 507 self.failUnlessEqual(r['dac'],params['dac']) 508 self.failUnlessEqual(r['fid'],params['fid']) 509 self.failUnlessEqual(r['efid'],params['efid']) 510 self.failUnlessEqual(r['timetag_month'],params['timetag_month']) 511 self.failUnlessEqual(r['timetag_day'],params['timetag_day']) 512 self.failUnlessEqual(r['timetag_hour'],params['timetag_hour']) 513 self.failUnlessEqual(r['timetag_min'],params['timetag_min']) 514 self.failUnlessEqual(r['timetag_sec'],params['timetag_sec']) 515 self.failUnlessEqual(r['stationid'],params['stationid']) 516 self.failUnlessAlmostEqual(r['station_longitude'],params['station_longitude'],5) 517 self.failUnlessAlmostEqual(r['station_latitude'],params['station_latitude'],5) 518 self.failUnlessAlmostEqual(r['whale_longitude'],params['whale_longitude'],5) 519 self.failUnlessAlmostEqual(r['whale_latitude'],params['whale_latitude'],5) 520 self.failUnlessEqual(r['timetoexpire'],params['timetoexpire']) 521 self.failUnlessEqual(r['radius'],params['radius']) 522 self.failUnlessEqual(r['heading'],params['heading']) 523 self.failUnlessEqual(r['numWhales'],params['numWhales'])
524
525 -def addMsgOptions(parser):
526 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 527 help='decode a "whalenotice" AIS message') 528 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 529 help='encode a "whalenotice" AIS message') 530 parser.add_option('--timetag_month-field', dest='timetag_monthField',metavar='uint',type='int' 531 ,help='Field parameter value [default: %default]') 532 parser.add_option('--timetag_day-field', dest='timetag_dayField',metavar='uint',type='int' 533 ,help='Field parameter value [default: %default]') 534 parser.add_option('--timetag_hour-field', dest='timetag_hourField',metavar='uint',type='int' 535 ,help='Field parameter value [default: %default]') 536 parser.add_option('--timetag_min-field', dest='timetag_minField',metavar='uint',type='int' 537 ,help='Field parameter value [default: %default]') 538 parser.add_option('--timetag_sec-field', dest='timetag_secField',metavar='uint',type='int' 539 ,help='Field parameter value [default: %default]') 540 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string' 541 ,help='Field parameter value [default: %default]') 542 parser.add_option('--station_longitude-field', dest='station_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 543 ,help='Field parameter value [default: %default]') 544 parser.add_option('--station_latitude-field', dest='station_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 545 ,help='Field parameter value [default: %default]') 546 parser.add_option('--whale_longitude-field', dest='whale_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 547 ,help='Field parameter value [default: %default]') 548 parser.add_option('--whale_latitude-field', dest='whale_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 549 ,help='Field parameter value [default: %default]') 550 parser.add_option('--timetoexpire-field', dest='timetoexpireField',default=0,metavar='uint',type='int' 551 ,help='Field parameter value [default: %default]') 552 parser.add_option('--radius-field', dest='radiusField',default=65534,metavar='uint',type='int' 553 ,help='Field parameter value [default: %default]') 554 parser.add_option('--heading-field', dest='headingField',default=511,metavar='uint',type='int' 555 ,help='Field parameter value [default: %default]') 556 parser.add_option('--numWhales-field', dest='numWhalesField',default=0,metavar='uint',type='int' 557 ,help='Field parameter value [default: %default]')
558 559 ############################################################ 560 if __name__=='__main__': 561 562 from optparse import OptionParser 563 parser = OptionParser(usage="%prog [options]", 564 version="%prog "+__version__) 565 566 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 567 help='run the documentation tests') 568 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 569 help='run the unit tests') 570 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 571 help='Make the test output verbose') 572 573 # FIX: remove nmea from binary messages. No way to build the whole packet? 574 # FIX: or build the surrounding msg 8 for a broadcast? 575 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 576 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 577 ,default='nmeapayload' 578 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]') 579 580 581 outputChoices = ('std','html','xml' , 'kml','kml-full') 582 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 583 ,default='std' 584 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 585 586 parser.add_option('-o','--output',dest='outputFileName',default=None, 587 help='Name of the python file to write [default: stdout]') 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.timetag_monthField: parser.error("missing value for timetag_monthField") 621 if None==options.timetag_dayField: parser.error("missing value for timetag_dayField") 622 if None==options.timetag_hourField: parser.error("missing value for timetag_hourField") 623 if None==options.timetag_minField: parser.error("missing value for timetag_minField") 624 if None==options.timetag_secField: parser.error("missing value for timetag_secField") 625 if None==options.stationidField: parser.error("missing value for stationidField") 626 if None==options.station_longitudeField: parser.error("missing value for station_longitudeField") 627 if None==options.station_latitudeField: parser.error("missing value for station_latitudeField") 628 if None==options.whale_longitudeField: parser.error("missing value for whale_longitudeField") 629 if None==options.whale_latitudeField: parser.error("missing value for whale_latitudeField") 630 if None==options.timetoexpireField: parser.error("missing value for timetoexpireField") 631 if None==options.radiusField: parser.error("missing value for radiusField") 632 if None==options.headingField: parser.error("missing value for headingField") 633 if None==options.numWhalesField: parser.error("missing value for numWhalesField") 634 msgDict={ 635 'dac': '366', 636 'fid': '1', 637 'efid': '2', 638 'timetag_month': options.timetag_monthField, 639 'timetag_day': options.timetag_dayField, 640 'timetag_hour': options.timetag_hourField, 641 'timetag_min': options.timetag_minField, 642 'timetag_sec': options.timetag_secField, 643 'stationid': options.stationidField, 644 'station_longitude': options.station_longitudeField, 645 'station_latitude': options.station_latitudeField, 646 'whale_longitude': options.whale_longitudeField, 647 'whale_latitude': options.whale_latitudeField, 648 'timetoexpire': options.timetoexpireField, 649 'radius': options.radiusField, 650 'heading': options.headingField, 651 'numWhales': options.numWhalesField, 652 } 653 654 bits = encode(msgDict) 655 if 'binary'==options.ioType: print str(bits) 656 elif 'nmeapayload'==options.ioType: 657 # FIX: figure out if this might be necessary at compile time 658 print "bitLen",len(bits) 659 bitLen=len(bits) 660 if bitLen%6!=0: 661 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 662 print "result:",binary.bitvectoais6(bits)[0] 663 664 665 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 666 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 667 else: sys.exit('ERROR: unknown ioType. Help!') 668 669 if options.doDecode: 670 for msg in args: 671 bv = None 672 if 'binary' == options.ioType: bv = BitVector(bitstring=msg) 673 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg) 674 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5]) 675 else: sys.exit('ERROR: unknown ioType. Help!') 676 677 printFields(decode(bv),out=outfile,format=options.outputType) 678