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-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  # 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  fieldList = [ 
 49          'dac', 
 50          'fid', 
 51          'efid', 
 52          'timetag_month', 
 53          'timetag_day', 
 54          'timetag_hour', 
 55          'timetag_min', 
 56          'timetag_sec', 
 57          'stationid', 
 58          'station_longitude', 
 59          'station_latitude', 
 60          'whale_longitude', 
 61          'whale_latitude', 
 62          'timetoexpire', 
 63          'radius', 
 64          'heading', 
 65          'numWhales', 
 66  ] 
 67   
68 -def encode(params, validate=False):
69 '''Create a whalenotice binary message payload to pack into an AIS Msg whalenotice. 70 71 Fields in params: 72 - dac(uint): Designated Area Code (field automatically set to "366") 73 - fid(uint): Functional Identifier (field automatically set to "1") 74 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2") 75 - timetag_month(uint): Time whale was last recorded month 1..12 76 - timetag_day(uint): Time whale was last recorded day of the month 1..31 77 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23 78 - timetag_min(uint): Time whale was last recorded minutes 79 - timetag_sec(uint): Time whale was last recorded seconds 80 - stationid(aisstr6): Character identifier of the station. Usually a number. 81 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 82 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 83 - whale_longitude(decimal): Where was the whale East West location 84 - whale_latitude(decimal): Where was the whale North South location 85 - timetoexpire(uint): Seconds until this notice expires 86 - radius(uint): Distance of the required exclusion/slow zone 87 - heading(uint): Direction the whale is traveling 88 - numWhales(uint): Number of whales detected 89 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing 90 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 91 @rtype: BitVector 92 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 93 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits. 94 ''' 95 96 bvList = [] 97 bvList.append(binary.setBitVectorSize(BitVector(intVal=366),16)) 98 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),4)) 99 bvList.append(binary.setBitVectorSize(BitVector(intVal=2),12)) 100 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_month']),4)) 101 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_day']),5)) 102 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_hour']),5)) 103 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_min']),6)) 104 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_sec']),6)) 105 if 'stationid' in params: 106 bvList.append(aisstring.encode(params['stationid'],42)) 107 else: 108 bvList.append(aisstring.encode('@@@@@@@',42)) 109 if 'station_longitude' in params: 110 bvList.append(binary.bvFromSignedInt(int(Decimal(params['station_longitude'])*Decimal('600000')),28)) 111 else: 112 bvList.append(binary.bvFromSignedInt(108600000,28)) 113 if 'station_latitude' in params: 114 bvList.append(binary.bvFromSignedInt(int(Decimal(params['station_latitude'])*Decimal('600000')),27)) 115 else: 116 bvList.append(binary.bvFromSignedInt(54600000,27)) 117 if 'whale_longitude' in params: 118 bvList.append(binary.bvFromSignedInt(int(Decimal(params['whale_longitude'])*Decimal('600000')),28)) 119 else: 120 bvList.append(binary.bvFromSignedInt(108600000,28)) 121 if 'whale_latitude' in params: 122 bvList.append(binary.bvFromSignedInt(int(Decimal(params['whale_latitude'])*Decimal('600000')),27)) 123 else: 124 bvList.append(binary.bvFromSignedInt(54600000,27)) 125 if 'timetoexpire' in params: 126 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetoexpire']),16)) 127 else: 128 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),16)) 129 if 'radius' in params: 130 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['radius']),16)) 131 else: 132 bvList.append(binary.setBitVectorSize(BitVector(intVal=65534),16)) 133 if 'heading' in params: 134 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['heading']),9)) 135 else: 136 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 137 if 'numWhales' in params: 138 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['numWhales']),8)) 139 else: 140 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),8)) 141 142 return binary.joinBV(bvList)
143
144 -def decode(bv, validate=False):
145 '''Unpack a whalenotice message 146 147 Fields in params: 148 - dac(uint): Designated Area Code (field automatically set to "366") 149 - fid(uint): Functional Identifier (field automatically set to "1") 150 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2") 151 - timetag_month(uint): Time whale was last recorded month 1..12 152 - timetag_day(uint): Time whale was last recorded day of the month 1..31 153 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23 154 - timetag_min(uint): Time whale was last recorded minutes 155 - timetag_sec(uint): Time whale was last recorded seconds 156 - stationid(aisstr6): Character identifier of the station. Usually a number. 157 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 158 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 159 - whale_longitude(decimal): Where was the whale East West location 160 - whale_latitude(decimal): Where was the whale North South location 161 - timetoexpire(uint): Seconds until this notice expires 162 - radius(uint): Distance of the required exclusion/slow zone 163 - heading(uint): Direction the whale is traveling 164 - numWhales(uint): Number of whales detected 165 @type bv: BitVector 166 @param bv: Bits defining a message 167 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 168 @rtype: dict 169 @return: params 170 ''' 171 172 #Would be nice to check the bit count here.. 173 #if validate: 174 # assert (len(bv)==FIX: SOME NUMBER) 175 r = {} 176 r['dac']=366 177 r['fid']=1 178 r['efid']=2 179 r['timetag_month']=int(bv[32:36]) 180 r['timetag_day']=int(bv[36:41]) 181 r['timetag_hour']=int(bv[41:46]) 182 r['timetag_min']=int(bv[46:52]) 183 r['timetag_sec']=int(bv[52:58]) 184 r['stationid']=aisstring.decode(bv[58:100]) 185 r['station_longitude']=Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000') 186 r['station_latitude']=Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000') 187 r['whale_longitude']=Decimal(binary.signedIntFromBV(bv[155:183]))/Decimal('600000') 188 r['whale_latitude']=Decimal(binary.signedIntFromBV(bv[183:210]))/Decimal('600000') 189 r['timetoexpire']=int(bv[210:226]) 190 r['radius']=int(bv[226:242]) 191 r['heading']=int(bv[242:251]) 192 r['numWhales']=int(bv[251:259]) 193 return r
194
195 -def decodedac(bv, validate=False):
196 return 366
197
198 -def decodefid(bv, validate=False):
199 return 1
200
201 -def decodeefid(bv, validate=False):
202 return 2
203
204 -def decodetimetag_month(bv, validate=False):
205 return int(bv[32:36])
206
207 -def decodetimetag_day(bv, validate=False):
208 return int(bv[36:41])
209
210 -def decodetimetag_hour(bv, validate=False):
211 return int(bv[41:46])
212
213 -def decodetimetag_min(bv, validate=False):
214 return int(bv[46:52])
215
216 -def decodetimetag_sec(bv, validate=False):
217 return int(bv[52:58])
218
219 -def decodestationid(bv, validate=False):
220 return aisstring.decode(bv[58:100])
221
222 -def decodestation_longitude(bv, validate=False):
223 return Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000')
224
225 -def decodestation_latitude(bv, validate=False):
226 return Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000')
227
228 -def decodewhale_longitude(bv, validate=False):
229 return Decimal(binary.signedIntFromBV(bv[155:183]))/Decimal('600000')
230
231 -def decodewhale_latitude(bv, validate=False):
232 return Decimal(binary.signedIntFromBV(bv[183:210]))/Decimal('600000')
233
234 -def decodetimetoexpire(bv, validate=False):
235 return int(bv[210:226])
236
237 -def decoderadius(bv, validate=False):
238 return int(bv[226:242])
239
240 -def decodeheading(bv, validate=False):
241 return int(bv[242:251])
242
243 -def decodenumWhales(bv, validate=False):
244 return int(bv[251:259])
245 246
247 -def printHtml(params, out=sys.stdout):
248 out.write("<h3>whalenotice<h3>\n") 249 out.write("<table border=\"1\">\n") 250 out.write("<tr bgcolor=\"orange\">\n") 251 out.write("<th align=\"left\">Field Name</th>\n") 252 out.write("<th align=\"left\">Type</th>\n") 253 out.write("<th align=\"left\">Value</th>\n") 254 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 255 out.write("<th align=\"left\">Units</th>\n") 256 out.write("\n") 257 out.write("<tr>\n") 258 out.write("<td>dac</td>\n") 259 out.write("<td>uint</td>\n") 260 if 'dac' in params: 261 out.write(" <td>"+str(params['dac'])+"</td>\n") 262 out.write(" <td>"+str(params['dac'])+"</td>\n") 263 out.write("</tr>\n") 264 out.write("\n") 265 out.write("<tr>\n") 266 out.write("<td>fid</td>\n") 267 out.write("<td>uint</td>\n") 268 if 'fid' in params: 269 out.write(" <td>"+str(params['fid'])+"</td>\n") 270 out.write(" <td>"+str(params['fid'])+"</td>\n") 271 out.write("</tr>\n") 272 out.write("\n") 273 out.write("<tr>\n") 274 out.write("<td>efid</td>\n") 275 out.write("<td>uint</td>\n") 276 if 'efid' in params: 277 out.write(" <td>"+str(params['efid'])+"</td>\n") 278 out.write(" <td>"+str(params['efid'])+"</td>\n") 279 out.write("</tr>\n") 280 out.write("\n") 281 out.write("<tr>\n") 282 out.write("<td>timetag_month</td>\n") 283 out.write("<td>uint</td>\n") 284 if 'timetag_month' in params: 285 out.write(" <td>"+str(params['timetag_month'])+"</td>\n") 286 out.write(" <td>"+str(params['timetag_month'])+"</td>\n") 287 out.write("</tr>\n") 288 out.write("\n") 289 out.write("<tr>\n") 290 out.write("<td>timetag_day</td>\n") 291 out.write("<td>uint</td>\n") 292 if 'timetag_day' in params: 293 out.write(" <td>"+str(params['timetag_day'])+"</td>\n") 294 out.write(" <td>"+str(params['timetag_day'])+"</td>\n") 295 out.write("</tr>\n") 296 out.write("\n") 297 out.write("<tr>\n") 298 out.write("<td>timetag_hour</td>\n") 299 out.write("<td>uint</td>\n") 300 if 'timetag_hour' in params: 301 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n") 302 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n") 303 out.write("</tr>\n") 304 out.write("\n") 305 out.write("<tr>\n") 306 out.write("<td>timetag_min</td>\n") 307 out.write("<td>uint</td>\n") 308 if 'timetag_min' in params: 309 out.write(" <td>"+str(params['timetag_min'])+"</td>\n") 310 out.write(" <td>"+str(params['timetag_min'])+"</td>\n") 311 out.write("</tr>\n") 312 out.write("\n") 313 out.write("<tr>\n") 314 out.write("<td>timetag_sec</td>\n") 315 out.write("<td>uint</td>\n") 316 if 'timetag_sec' in params: 317 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n") 318 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n") 319 out.write("</tr>\n") 320 out.write("\n") 321 out.write("<tr>\n") 322 out.write("<td>stationid</td>\n") 323 out.write("<td>aisstr6</td>\n") 324 if 'stationid' in params: 325 out.write(" <td>"+str(params['stationid'])+"</td>\n") 326 out.write(" <td>"+str(params['stationid'])+"</td>\n") 327 out.write("</tr>\n") 328 out.write("\n") 329 out.write("<tr>\n") 330 out.write("<td>station_longitude</td>\n") 331 out.write("<td>decimal</td>\n") 332 if 'station_longitude' in params: 333 out.write(" <td>"+str(params['station_longitude'])+"</td>\n") 334 out.write(" <td>"+str(params['station_longitude'])+"</td>\n") 335 out.write("<td>degrees</td>\n") 336 out.write("</tr>\n") 337 out.write("\n") 338 out.write("<tr>\n") 339 out.write("<td>station_latitude</td>\n") 340 out.write("<td>decimal</td>\n") 341 if 'station_latitude' in params: 342 out.write(" <td>"+str(params['station_latitude'])+"</td>\n") 343 out.write(" <td>"+str(params['station_latitude'])+"</td>\n") 344 out.write("<td>degrees</td>\n") 345 out.write("</tr>\n") 346 out.write("\n") 347 out.write("<tr>\n") 348 out.write("<td>whale_longitude</td>\n") 349 out.write("<td>decimal</td>\n") 350 if 'whale_longitude' in params: 351 out.write(" <td>"+str(params['whale_longitude'])+"</td>\n") 352 out.write(" <td>"+str(params['whale_longitude'])+"</td>\n") 353 out.write("<td>degrees</td>\n") 354 out.write("</tr>\n") 355 out.write("\n") 356 out.write("<tr>\n") 357 out.write("<td>whale_latitude</td>\n") 358 out.write("<td>decimal</td>\n") 359 if 'whale_latitude' in params: 360 out.write(" <td>"+str(params['whale_latitude'])+"</td>\n") 361 out.write(" <td>"+str(params['whale_latitude'])+"</td>\n") 362 out.write("<td>degrees</td>\n") 363 out.write("</tr>\n") 364 out.write("\n") 365 out.write("<tr>\n") 366 out.write("<td>timetoexpire</td>\n") 367 out.write("<td>uint</td>\n") 368 if 'timetoexpire' in params: 369 out.write(" <td>"+str(params['timetoexpire'])+"</td>\n") 370 out.write(" <td>"+str(params['timetoexpire'])+"</td>\n") 371 out.write("<td>seconds</td>\n") 372 out.write("</tr>\n") 373 out.write("\n") 374 out.write("<tr>\n") 375 out.write("<td>radius</td>\n") 376 out.write("<td>uint</td>\n") 377 if 'radius' in params: 378 out.write(" <td>"+str(params['radius'])+"</td>\n") 379 out.write(" <td>"+str(params['radius'])+"</td>\n") 380 out.write("<td>m</td>\n") 381 out.write("</tr>\n") 382 out.write("\n") 383 out.write("<tr>\n") 384 out.write("<td>heading</td>\n") 385 out.write("<td>uint</td>\n") 386 if 'heading' in params: 387 out.write(" <td>"+str(params['heading'])+"</td>\n") 388 out.write(" <td>"+str(params['heading'])+"</td>\n") 389 out.write("<td>degrees true north</td>\n") 390 out.write("</tr>\n") 391 out.write("\n") 392 out.write("<tr>\n") 393 out.write("<td>numWhales</td>\n") 394 out.write("<td>uint</td>\n") 395 if 'numWhales' in params: 396 out.write(" <td>"+str(params['numWhales'])+"</td>\n") 397 out.write(" <td>"+str(params['numWhales'])+"</td>\n") 398 out.write("</tr>\n") 399 out.write("</table>\n")
400 401
402 -def printKml(params, out=sys.stdout):
403 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer''' 404 out.write("\ <Placemark>\n") 405 out.write("\t <name>"+str(params['stationsid'])+"</name>\n") 406 out.write("\t\t<description>\n") 407 import StringIO 408 buf = StringIO.StringIO() 409 printHtml(params,buf) 410 import cgi 411 out.write(cgi.escape(buf.getvalue())) 412 out.write("\t\t</description>\n") 413 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n") 414 out.write("\t\t<Point>\n") 415 out.write("\t\t\t<coordinates>") 416 out.write(str(params['station_longitude'])) 417 out.write(',') 418 out.write(str(params['station_latitude'])) 419 out.write(",0</coordinates>\n") 420 out.write("\t\t</Point>\n") 421 out.write("\t</Placemark>\n")
422
423 -def printFields(params, out=sys.stdout, format='std', fieldList=None):
424 '''Print a numWhales message to stdout. 425 426 Fields in params: 427 - dac(uint): Designated Area Code (field automatically set to "366") 428 - fid(uint): Functional Identifier (field automatically set to "1") 429 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2") 430 - timetag_month(uint): Time whale was last recorded month 1..12 431 - timetag_day(uint): Time whale was last recorded day of the month 1..31 432 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23 433 - timetag_min(uint): Time whale was last recorded minutes 434 - timetag_sec(uint): Time whale was last recorded seconds 435 - stationid(aisstr6): Character identifier of the station. Usually a number. 436 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 437 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 438 - whale_longitude(decimal): Where was the whale East West location 439 - whale_latitude(decimal): Where was the whale North South location 440 - timetoexpire(uint): Seconds until this notice expires 441 - radius(uint): Distance of the required exclusion/slow zone 442 - heading(uint): Direction the whale is traveling 443 - numWhales(uint): Number of whales detected 444 @param params: Dictionary of field names/values. 445 @param out: File like object to write to 446 @rtype: stdout 447 @return: text to out 448 ''' 449 450 if 'std'==format: 451 out.write("numWhales:\n") 452 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n") 453 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n") 454 if 'efid' in params: out.write(" efid: "+str(params['efid'])+"\n") 455 if 'timetag_month' in params: out.write(" timetag_month: "+str(params['timetag_month'])+"\n") 456 if 'timetag_day' in params: out.write(" timetag_day: "+str(params['timetag_day'])+"\n") 457 if 'timetag_hour' in params: out.write(" timetag_hour: "+str(params['timetag_hour'])+"\n") 458 if 'timetag_min' in params: out.write(" timetag_min: "+str(params['timetag_min'])+"\n") 459 if 'timetag_sec' in params: out.write(" timetag_sec: "+str(params['timetag_sec'])+"\n") 460 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n") 461 if 'station_longitude' in params: out.write(" station_longitude: "+str(params['station_longitude'])+"\n") 462 if 'station_latitude' in params: out.write(" station_latitude: "+str(params['station_latitude'])+"\n") 463 if 'whale_longitude' in params: out.write(" whale_longitude: "+str(params['whale_longitude'])+"\n") 464 if 'whale_latitude' in params: out.write(" whale_latitude: "+str(params['whale_latitude'])+"\n") 465 if 'timetoexpire' in params: out.write(" timetoexpire: "+str(params['timetoexpire'])+"\n") 466 if 'radius' in params: out.write(" radius: "+str(params['radius'])+"\n") 467 if 'heading' in params: out.write(" heading: "+str(params['heading'])+"\n") 468 if 'numWhales' in params: out.write(" numWhales: "+str(params['numWhales'])+"\n") 469 elif 'csv'==format: 470 if None == options.fieldList: 471 options.fieldList = fieldList 472 needComma = False; 473 for field in fieldList: 474 if needComma: out.write(',') 475 needComma = True 476 if field in params: 477 out.write(str(params[field])) 478 # else: leave it empty 479 out.write("\n") 480 elif 'html'==format: 481 printHtml(params,out) 482 elif 'sql'==format: 483 sqlInsertStr(params,out) 484 elif 'kml'==format: 485 printKml(params,out) 486 elif 'kml-full'==format: 487 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 488 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n") 489 out.write("<Document>\n") 490 out.write(" <name>whalenotice</name>\n") 491 printKml(params,out) 492 out.write("</Document>\n") 493 out.write("</kml>\n") 494 else: 495 print "ERROR: unknown format:",format 496 assert False 497 498 return # Nothing to return
499 500 ###################################################################### 501 # SQL SUPPORT 502 ###################################################################### 503
504 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None):
505 ''' 506 Return the SQL CREATE command for this message type 507 @param outfile: file like object to print to. 508 @param fields: which fields to put in the create. Defaults to all. 509 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 510 @return: sql create string 511 @rtype: str 512 513 @see: sqlCreate 514 ''' 515 outfile.write(str(sqlCreate(fields,extraFields)))
516
517 -def sqlCreate(fields=None, extraFields=None):
518 ''' 519 Return the sqlhelp object to create the table. 520 521 @param fields: which fields to put in the create. Defaults to all. 522 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 523 @return: An object that can be used to generate a return 524 @rtype: sqlhelp.create 525 ''' 526 if None == fields: fields = fieldList 527 import sqlhelp 528 c = sqlhelp.create('whalenotice') 529 if 'dac' in fields: c.addInt ('dac') 530 if 'fid' in fields: c.addInt ('fid') 531 if 'efid' in fields: c.addInt ('efid') 532 if 'timetag_month' in fields: c.addInt ('timetag_month') 533 if 'timetag_day' in fields: c.addInt ('timetag_day') 534 if 'timetag_hour' in fields: c.addInt ('timetag_hour') 535 if 'timetag_min' in fields: c.addInt ('timetag_min') 536 if 'timetag_sec' in fields: c.addInt ('timetag_sec') 537 if 'stationid' in fields: c.addVarChar(stationid,7) 538 if 'station_longitude' in fields: c.addDecimal('station_longitude',8,5) 539 if 'station_latitude' in fields: c.addDecimal('station_latitude',8,5) 540 if 'whale_longitude' in fields: c.addDecimal('whale_longitude',8,5) 541 if 'whale_latitude' in fields: c.addDecimal('whale_latitude',8,5) 542 if 'timetoexpire' in fields: c.addInt ('timetoexpire') 543 if 'radius' in fields: c.addInt ('radius') 544 if 'heading' in fields: c.addInt ('heading') 545 if 'numWhales' in fields: c.addInt ('numWhales') 546 547 return c
548
549 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None):
550 ''' 551 Return the SQL CREATE command for this message type 552 @param params: dictionary of values keyed by field name 553 @param outfile: file like object to print to. 554 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 555 @return: sql create string 556 @rtype: str 557 558 @see: sqlCreate 559 ''' 560 outfile.write(str(sqlInsert(params,extraParams)))
561 562
563 -def sqlInsert(params,extraParams=None):
564 ''' 565 Give the SQL insert statement 566 @param params: dict keyed by field name of values 567 @param extraParams: any extra fields that you have created beyond the normal ais message fields 568 @rtype: sqlhelp.insert 569 @return: insert class instance 570 @todo: allow optional type checking of params? 571 @warning: this will take invalid keys happily and do what??? 572 ''' 573 import sqlhelp 574 i = sqlhelp.insert('whalenotice') 575 for key in params: i.add(key,params[key]) 576 if None != extraParams: 577 for key in extraParams: 578 i.add(key,extraParams[key]) 579 580 return i
581 582 583 ###################################################################### 584 # UNIT TESTING 585 ###################################################################### 586 import unittest
587 -def testParams():
588 '''Return a params file base on the testvalue tags. 589 @rtype: dict 590 @return: params based on testvalue tags 591 ''' 592 params = {} 593 params['dac'] = 366 594 params['fid'] = 1 595 params['efid'] = 2 596 params['timetag_month'] = 2 597 params['timetag_day'] = 28 598 params['timetag_hour'] = 23 599 params['timetag_min'] = 45 600 params['timetag_sec'] = 58 601 params['stationid'] = 'A234567' 602 params['station_longitude'] = Decimal('-122.16328055555556') 603 params['station_latitude'] = Decimal('37.424458333333334') 604 params['whale_longitude'] = Decimal('-122.16328055555556') 605 params['whale_latitude'] = Decimal('37.424458333333334') 606 params['timetoexpire'] = 1 607 params['radius'] = 5000 608 params['heading'] = 35 609 params['numWhales'] = 2 610 611 return params
612
613 -class Testwhalenotice(unittest.TestCase):
614 '''Use testvalue tag text from each type to build test case the whalenotice message'''
615 - def testEncodeDecode(self):
616 617 params = testParams() 618 bits = encode(params) 619 r = decode(bits) 620 621 # Check that each parameter came through ok. 622 self.failUnlessEqual(r['dac'],params['dac']) 623 self.failUnlessEqual(r['fid'],params['fid']) 624 self.failUnlessEqual(r['efid'],params['efid']) 625 self.failUnlessEqual(r['timetag_month'],params['timetag_month']) 626 self.failUnlessEqual(r['timetag_day'],params['timetag_day']) 627 self.failUnlessEqual(r['timetag_hour'],params['timetag_hour']) 628 self.failUnlessEqual(r['timetag_min'],params['timetag_min']) 629 self.failUnlessEqual(r['timetag_sec'],params['timetag_sec']) 630 self.failUnlessEqual(r['stationid'],params['stationid']) 631 self.failUnlessAlmostEqual(r['station_longitude'],params['station_longitude'],5) 632 self.failUnlessAlmostEqual(r['station_latitude'],params['station_latitude'],5) 633 self.failUnlessAlmostEqual(r['whale_longitude'],params['whale_longitude'],5) 634 self.failUnlessAlmostEqual(r['whale_latitude'],params['whale_latitude'],5) 635 self.failUnlessEqual(r['timetoexpire'],params['timetoexpire']) 636 self.failUnlessEqual(r['radius'],params['radius']) 637 self.failUnlessEqual(r['heading'],params['heading']) 638 self.failUnlessEqual(r['numWhales'],params['numWhales'])
639
640 -def addMsgOptions(parser):
641 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 642 help='decode a "whalenotice" AIS message') 643 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 644 help='encode a "whalenotice" AIS message') 645 parser.add_option('--timetag_month-field', dest='timetag_monthField',metavar='uint',type='int' 646 ,help='Field parameter value [default: %default]') 647 parser.add_option('--timetag_day-field', dest='timetag_dayField',metavar='uint',type='int' 648 ,help='Field parameter value [default: %default]') 649 parser.add_option('--timetag_hour-field', dest='timetag_hourField',metavar='uint',type='int' 650 ,help='Field parameter value [default: %default]') 651 parser.add_option('--timetag_min-field', dest='timetag_minField',metavar='uint',type='int' 652 ,help='Field parameter value [default: %default]') 653 parser.add_option('--timetag_sec-field', dest='timetag_secField',metavar='uint',type='int' 654 ,help='Field parameter value [default: %default]') 655 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string' 656 ,help='Field parameter value [default: %default]') 657 parser.add_option('--station_longitude-field', dest='station_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 658 ,help='Field parameter value [default: %default]') 659 parser.add_option('--station_latitude-field', dest='station_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 660 ,help='Field parameter value [default: %default]') 661 parser.add_option('--whale_longitude-field', dest='whale_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 662 ,help='Field parameter value [default: %default]') 663 parser.add_option('--whale_latitude-field', dest='whale_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 664 ,help='Field parameter value [default: %default]') 665 parser.add_option('--timetoexpire-field', dest='timetoexpireField',default=0,metavar='uint',type='int' 666 ,help='Field parameter value [default: %default]') 667 parser.add_option('--radius-field', dest='radiusField',default=65534,metavar='uint',type='int' 668 ,help='Field parameter value [default: %default]') 669 parser.add_option('--heading-field', dest='headingField',default=511,metavar='uint',type='int' 670 ,help='Field parameter value [default: %default]') 671 parser.add_option('--numWhales-field', dest='numWhalesField',default=0,metavar='uint',type='int' 672 ,help='Field parameter value [default: %default]')
673 674 ############################################################ 675 if __name__=='__main__': 676 677 from optparse import OptionParser 678 parser = OptionParser(usage="%prog [options]", 679 version="%prog "+__version__) 680 681 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 682 help='run the documentation tests') 683 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 684 help='run the unit tests') 685 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 686 help='Make the test output verbose') 687 688 # FIX: remove nmea from binary messages. No way to build the whole packet? 689 # FIX: or build the surrounding msg 8 for a broadcast? 690 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 691 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 692 ,default='nmeapayload' 693 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]') 694 695 696 outputChoices = ('std','html','csv','sql' , 'kml','kml-full') 697 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 698 ,default='std' 699 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 700 701 parser.add_option('-o','--output',dest='outputFileName',default=None, 702 help='Name of the python file to write [default: stdout]') 703 704 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 705 choices=fieldList, 706 help='Which fields to include in the output. Currently only for csv output [default: all]') 707 708 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 709 help='Print the field name for csv') 710 711 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 712 help='Print out an sql create command for the table.') 713 714 addMsgOptions(parser) 715 716 (options,args) = parser.parse_args() 717 success=True 718 719 if options.doctest: 720 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 721 sys.argv= [sys.argv[0]] 722 if options.verbose: sys.argv.append('-v') 723 import doctest 724 numfail,numtests=doctest.testmod() 725 if numfail==0: print 'ok' 726 else: 727 print 'FAILED' 728 success=False 729 730 if not success: sys.exit('Something Failed') 731 del success # Hide success from epydoc 732 733 if options.unittest: 734 sys.argv = [sys.argv[0]] 735 if options.verbose: sys.argv.append('-v') 736 unittest.main() 737 738 outfile = sys.stdout 739 if None!=options.outputFileName: 740 outfile = file(options.outputFileName,'w') 741 742 743 if options.doEncode: 744 # First make sure all non required options are specified 745 if None==options.timetag_monthField: parser.error("missing value for timetag_monthField") 746 if None==options.timetag_dayField: parser.error("missing value for timetag_dayField") 747 if None==options.timetag_hourField: parser.error("missing value for timetag_hourField") 748 if None==options.timetag_minField: parser.error("missing value for timetag_minField") 749 if None==options.timetag_secField: parser.error("missing value for timetag_secField") 750 if None==options.stationidField: parser.error("missing value for stationidField") 751 if None==options.station_longitudeField: parser.error("missing value for station_longitudeField") 752 if None==options.station_latitudeField: parser.error("missing value for station_latitudeField") 753 if None==options.whale_longitudeField: parser.error("missing value for whale_longitudeField") 754 if None==options.whale_latitudeField: parser.error("missing value for whale_latitudeField") 755 if None==options.timetoexpireField: parser.error("missing value for timetoexpireField") 756 if None==options.radiusField: parser.error("missing value for radiusField") 757 if None==options.headingField: parser.error("missing value for headingField") 758 if None==options.numWhalesField: parser.error("missing value for numWhalesField") 759 msgDict={ 760 'dac': '366', 761 'fid': '1', 762 'efid': '2', 763 'timetag_month': options.timetag_monthField, 764 'timetag_day': options.timetag_dayField, 765 'timetag_hour': options.timetag_hourField, 766 'timetag_min': options.timetag_minField, 767 'timetag_sec': options.timetag_secField, 768 'stationid': options.stationidField, 769 'station_longitude': options.station_longitudeField, 770 'station_latitude': options.station_latitudeField, 771 'whale_longitude': options.whale_longitudeField, 772 'whale_latitude': options.whale_latitudeField, 773 'timetoexpire': options.timetoexpireField, 774 'radius': options.radiusField, 775 'heading': options.headingField, 776 'numWhales': options.numWhalesField, 777 } 778 779 bits = encode(msgDict) 780 if 'binary'==options.ioType: print str(bits) 781 elif 'nmeapayload'==options.ioType: 782 # FIX: figure out if this might be necessary at compile time 783 print "bitLen",len(bits) 784 bitLen=len(bits) 785 if bitLen%6!=0: 786 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 787 print "result:",binary.bitvectoais6(bits)[0] 788 789 790 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 791 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 792 else: sys.exit('ERROR: unknown ioType. Help!') 793 794 795 if options.sqlCreate: 796 sqlCreateStr(outfile,options.fieldList) 797 798 if options.printCsvfieldList: 799 # Make a csv separated list of fields that will be displayed for csv 800 if None == options.fieldList: options.fieldList = fieldList 801 import StringIO 802 buf = StringIO.StringIO() 803 for field in options.fieldList: 804 buf.write(field+',') 805 result = buf.getvalue() 806 if result[-1] == ',': print result[:-1] 807 else: print result 808 809 if options.doDecode: 810 for msg in args: 811 bv = None 812 if 'binary' == options.ioType: bv = BitVector(bitstring=msg) 813 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg) 814 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5]) 815 else: sys.exit('ERROR: unknown ioType. Help!') 816 817 printFields(decode(bv),out=outfile,format=options.outputType,fieldList=options.fieldList) 818