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

Source Code for Module ais.imo_001_11

   1  #!/usr/bin/env python 
   2   
   3  __version__ = '$Revision: 4791 $'.split()[1] 
   4  __date__ = '$Date: 2008-01-09 $'.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          'Spare', 
  54          'dac', 
  55          'fid', 
  56          'latitude', 
  57          'longitude', 
  58          'day', 
  59          'hour', 
  60          'min', 
  61          'avewind', 
  62          'windgust', 
  63          'winddir', 
  64          'windgustdir', 
  65          'airtemp', 
  66          'relhumid', 
  67          'dewpoint', 
  68          'airpressure', 
  69          'airpressuretrend', 
  70          'horizvis', 
  71          'waterlevel', 
  72          'waterleveltrend', 
  73          'surfcurspeed', 
  74          'surfcurdir', 
  75          'curspeed2', 
  76          'curdir2', 
  77          'curlevel2', 
  78          'curspeed3', 
  79          'curdir3', 
  80          'curlevel3', 
  81          'sigwaveheight', 
  82          'waveperiod', 
  83          'wavedir', 
  84          'swellheight', 
  85          'swellperiod', 
  86          'swelldir', 
  87          'seastate', 
  88          'watertemp', 
  89          'preciptype', 
  90          'salinity', 
  91          'ice', 
  92          'Spare', 
  93  ) 
  94   
  95  fieldListPostgres = ( 
  96          'MessageID', 
  97          'RepeatIndicator', 
  98          'UserID', 
  99          'Spare', 
 100          'dac', 
 101          'fid', 
 102          'Position',     # PostGIS data type 
 103          'day', 
 104          'hour', 
 105          'min', 
 106          'avewind', 
 107          'windgust', 
 108          'winddir', 
 109          'windgustdir', 
 110          'airtemp', 
 111          'relhumid', 
 112          'dewpoint', 
 113          'airpressure', 
 114          'airpressuretrend', 
 115          'horizvis', 
 116          'waterlevel', 
 117          'waterleveltrend', 
 118          'surfcurspeed', 
 119          'surfcurdir', 
 120          'curspeed2', 
 121          'curdir2', 
 122          'curlevel2', 
 123          'curspeed3', 
 124          'curdir3', 
 125          'curlevel3', 
 126          'sigwaveheight', 
 127          'waveperiod', 
 128          'wavedir', 
 129          'swellheight', 
 130          'swellperiod', 
 131          'swelldir', 
 132          'seastate', 
 133          'watertemp', 
 134          'preciptype', 
 135          'salinity', 
 136          'ice', 
 137          'Spare', 
 138  ) 
 139   
 140  toPgFields = { 
 141          'latitude':'Position', 
 142          'longitude':'Position', 
 143  } 
 144  ''' 
 145  Go to the Postgis field names from the straight field name 
 146  ''' 
 147   
 148  fromPgFields = { 
 149          'Position':('latitude','longitude',), 
 150  } 
 151  ''' 
 152  Go from the Postgis field names to the straight field name 
 153  ''' 
 154   
 155  pgTypes = { 
 156          'Position':'POINT', 
 157  } 
 158  ''' 
 159  Lookup table for each postgis field name to get its type. 
 160  ''' 
 161   
162 -def encode(params, validate=False):
163 '''Create a imo_met_hydro binary message payload to pack into an AIS Msg imo_met_hydro. 164 165 Fields in params: 166 - MessageID(uint): AIS message number. Must be 8 (field automatically set to "8") 167 - RepeatIndicator(uint): Indicated how many times a message has been repeated 168 - UserID(uint): MMSI number of transmitter broadcasting the message 169 - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0") 170 - dac(uint): Designated Area Code - part 1 of the IAI (field automatically set to "1") 171 - fid(uint): Functional Identifier - part 2 of the IAI (field automatically set to "11") 172 - latitude(decimal): Location of the vessel. North South location 173 - longitude(decimal): Location of the vessel. East West location 174 - day(uint): Day 0..31 175 - hour(uint): Hour 0..23 176 - min(uint): Min 177 - avewind(uint): Average wind speed values for the last 10 minutes. 178 - windgust(uint): Wind gust is the max wind speed value reading during the last 10 minutes. 179 - winddir(uint): Wind direction 180 - windgustdir(uint): Wind direction for the gust. 181 - airtemp(decimal): Dry bulb temperature 182 - relhumid(uint): Relative humidity 183 - dewpoint(decimal): Dew Point 184 - airpressure(udecimal): Air pressure 185 - airpressuretrend(uint): Air pressure trend 186 - horizvis(udecimal): Horizontal visibility 187 - waterlevel(decimal): Water level (incl. tide) 188 - waterleveltrend(uint): Water level trend 189 - surfcurspeed(udecimal): Surface current speed 190 - surfcurdir(uint): Surface current direction 191 - curspeed2(udecimal): Level 2 current speed 192 - curdir2(uint): Level 2 current direction 193 - curlevel2(uint): Measuring level below sea surface for level 2 194 - curspeed3(udecimal): Level 3 current speed 195 - curdir3(uint): Level 3 current direction 196 - curlevel3(uint): Measuring level below sea surface for level 3 197 - sigwaveheight(udecimal): Significant wave height 198 - waveperiod(uint): Wave period 199 - wavedir(uint): Wave direction 200 - swellheight(udecimal): Swell height 201 - swellperiod(uint): Swell period 202 - swelldir(uint): Swell direction 203 - seastate(uint): Sea state according to the Beaufort scale 204 - watertemp(udecimal): Water temperature 205 - preciptype(uint): According to WMO 206 - salinity(decimal): Salinity 207 - ice(uint): Yes or no for the presence of ice 208 - Spare(uint): Must be zero (field automatically set to "0") 209 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing 210 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 211 @rtype: BitVector 212 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 213 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits. 214 ''' 215 216 bvList = [] 217 bvList.append(binary.setBitVectorSize(BitVector(intVal=8),6)) 218 if 'RepeatIndicator' in params: 219 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['RepeatIndicator']),2)) 220 else: 221 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 222 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['UserID']),30)) 223 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 224 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),10)) 225 bvList.append(binary.setBitVectorSize(BitVector(intVal=11),6)) 226 if 'latitude' in params: 227 bvList.append(binary.bvFromSignedInt(int(Decimal(params['latitude'])*Decimal('60000')),24)) 228 else: 229 bvList.append(binary.bvFromSignedInt(5460000,24)) 230 if 'longitude' in params: 231 bvList.append(binary.bvFromSignedInt(int(Decimal(params['longitude'])*Decimal('60000')),25)) 232 else: 233 bvList.append(binary.bvFromSignedInt(10860000,25)) 234 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['day']),5)) 235 if 'hour' in params: 236 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['hour']),5)) 237 else: 238 bvList.append(binary.setBitVectorSize(BitVector(intVal=31),5)) 239 if 'min' in params: 240 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['min']),6)) 241 else: 242 bvList.append(binary.setBitVectorSize(BitVector(intVal=63),6)) 243 if 'avewind' in params: 244 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['avewind']),7)) 245 else: 246 bvList.append(binary.setBitVectorSize(BitVector(intVal=127),7)) 247 if 'windgust' in params: 248 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['windgust']),7)) 249 else: 250 bvList.append(binary.setBitVectorSize(BitVector(intVal=127),7)) 251 if 'winddir' in params: 252 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['winddir']),9)) 253 else: 254 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 255 if 'windgustdir' in params: 256 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['windgustdir']),9)) 257 else: 258 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 259 if 'airtemp' in params: 260 bvList.append(binary.bvFromSignedInt(int(Decimal(params['airtemp'])*Decimal('10')),11)) 261 else: 262 bvList.append(binary.bvFromSignedInt(1023,11)) 263 if 'relhumid' in params: 264 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['relhumid']),7)) 265 else: 266 bvList.append(binary.setBitVectorSize(BitVector(intVal=127),7)) 267 if 'dewpoint' in params: 268 bvList.append(binary.bvFromSignedInt(int(Decimal(params['dewpoint'])*Decimal('10')),10)) 269 else: 270 bvList.append(binary.bvFromSignedInt(511,10)) 271 if 'airpressure' in params: 272 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['airpressure']-(800))*Decimal('1')))),9)) 273 else: 274 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(1311)),9)) 275 if 'airpressuretrend' in params: 276 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['airpressuretrend']),2)) 277 else: 278 bvList.append(binary.setBitVectorSize(BitVector(intVal=3),2)) 279 if 'horizvis' in params: 280 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['horizvis'])*Decimal('10')))),8)) 281 else: 282 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8)) 283 bvList.append(binary.bvFromSignedInt(int(Decimal(params['waterlevel'])*Decimal('10')),9)) 284 if 'waterleveltrend' in params: 285 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['waterleveltrend']),2)) 286 else: 287 bvList.append(binary.setBitVectorSize(BitVector(intVal=3),2)) 288 if 'surfcurspeed' in params: 289 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['surfcurspeed'])*Decimal('10')))),8)) 290 else: 291 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8)) 292 if 'surfcurdir' in params: 293 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['surfcurdir']),9)) 294 else: 295 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 296 if 'curspeed2' in params: 297 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['curspeed2'])*Decimal('10')))),8)) 298 else: 299 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8)) 300 if 'curdir2' in params: 301 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curdir2']),9)) 302 else: 303 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 304 if 'curlevel2' in params: 305 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curlevel2']),5)) 306 else: 307 bvList.append(binary.setBitVectorSize(BitVector(intVal=31),5)) 308 if 'curspeed3' in params: 309 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['curspeed3'])*Decimal('10')))),8)) 310 else: 311 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8)) 312 if 'curdir3' in params: 313 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curdir3']),9)) 314 else: 315 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 316 if 'curlevel3' in params: 317 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['curlevel3']),5)) 318 else: 319 bvList.append(binary.setBitVectorSize(BitVector(intVal=31),5)) 320 if 'sigwaveheight' in params: 321 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['sigwaveheight'])*Decimal('10')))),8)) 322 else: 323 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8)) 324 if 'waveperiod' in params: 325 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['waveperiod']),6)) 326 else: 327 bvList.append(binary.setBitVectorSize(BitVector(intVal=63),6)) 328 if 'wavedir' in params: 329 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['wavedir']),9)) 330 else: 331 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 332 if 'swellheight' in params: 333 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['swellheight'])*Decimal('10')))),8)) 334 else: 335 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8)) 336 if 'swellperiod' in params: 337 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['swellperiod']),6)) 338 else: 339 bvList.append(binary.setBitVectorSize(BitVector(intVal=63),6)) 340 if 'swelldir' in params: 341 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['swelldir']),9)) 342 else: 343 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9)) 344 if 'seastate' in params: 345 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['seastate']),4)) 346 else: 347 bvList.append(binary.setBitVectorSize(BitVector(intVal=15),4)) 348 if 'watertemp' in params: 349 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['watertemp']-(-10))*Decimal('10')))),10)) 350 else: 351 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(923)),10)) 352 if 'preciptype' in params: 353 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['preciptype']),3)) 354 else: 355 bvList.append(binary.setBitVectorSize(BitVector(intVal=7),3)) 356 if 'salinity' in params: 357 bvList.append(binary.bvFromSignedInt(int(Decimal(params['salinity'])*Decimal('10')),9)) 358 else: 359 bvList.append(binary.bvFromSignedInt(923,9)) 360 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['ice']),2)) 361 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),6)) 362 363 return binary.joinBV(bvList)
364
365 -def decode(bv, validate=False):
366 '''Unpack a imo_met_hydro message 367 368 Fields in params: 369 - MessageID(uint): AIS message number. Must be 8 (field automatically set to "8") 370 - RepeatIndicator(uint): Indicated how many times a message has been repeated 371 - UserID(uint): MMSI number of transmitter broadcasting the message 372 - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0") 373 - dac(uint): Designated Area Code - part 1 of the IAI (field automatically set to "1") 374 - fid(uint): Functional Identifier - part 2 of the IAI (field automatically set to "11") 375 - latitude(decimal): Location of the vessel. North South location 376 - longitude(decimal): Location of the vessel. East West location 377 - day(uint): Day 0..31 378 - hour(uint): Hour 0..23 379 - min(uint): Min 380 - avewind(uint): Average wind speed values for the last 10 minutes. 381 - windgust(uint): Wind gust is the max wind speed value reading during the last 10 minutes. 382 - winddir(uint): Wind direction 383 - windgustdir(uint): Wind direction for the gust. 384 - airtemp(decimal): Dry bulb temperature 385 - relhumid(uint): Relative humidity 386 - dewpoint(decimal): Dew Point 387 - airpressure(udecimal): Air pressure 388 - airpressuretrend(uint): Air pressure trend 389 - horizvis(udecimal): Horizontal visibility 390 - waterlevel(decimal): Water level (incl. tide) 391 - waterleveltrend(uint): Water level trend 392 - surfcurspeed(udecimal): Surface current speed 393 - surfcurdir(uint): Surface current direction 394 - curspeed2(udecimal): Level 2 current speed 395 - curdir2(uint): Level 2 current direction 396 - curlevel2(uint): Measuring level below sea surface for level 2 397 - curspeed3(udecimal): Level 3 current speed 398 - curdir3(uint): Level 3 current direction 399 - curlevel3(uint): Measuring level below sea surface for level 3 400 - sigwaveheight(udecimal): Significant wave height 401 - waveperiod(uint): Wave period 402 - wavedir(uint): Wave direction 403 - swellheight(udecimal): Swell height 404 - swellperiod(uint): Swell period 405 - swelldir(uint): Swell direction 406 - seastate(uint): Sea state according to the Beaufort scale 407 - watertemp(udecimal): Water temperature 408 - preciptype(uint): According to WMO 409 - salinity(decimal): Salinity 410 - ice(uint): Yes or no for the presence of ice 411 - Spare(uint): Must be zero (field automatically set to "0") 412 @type bv: BitVector 413 @param bv: Bits defining a message 414 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 415 @rtype: dict 416 @return: params 417 ''' 418 419 #Would be nice to check the bit count here.. 420 #if validate: 421 # assert (len(bv)==FIX: SOME NUMBER) 422 r = {} 423 r['MessageID']=8 424 r['RepeatIndicator']=int(bv[6:8]) 425 r['UserID']=int(bv[8:38]) 426 r['Spare']=0 427 r['dac']=1 428 r['fid']=11 429 r['latitude']=Decimal(binary.signedIntFromBV(bv[56:80]))/Decimal('60000') 430 r['longitude']=Decimal(binary.signedIntFromBV(bv[80:105]))/Decimal('60000') 431 r['day']=int(bv[105:110]) 432 r['hour']=int(bv[110:115]) 433 r['min']=int(bv[115:121]) 434 r['avewind']=int(bv[121:128]) 435 r['windgust']=int(bv[128:135]) 436 r['winddir']=int(bv[135:144]) 437 r['windgustdir']=int(bv[144:153]) 438 r['airtemp']=Decimal(binary.signedIntFromBV(bv[153:164]))/Decimal('10') 439 r['relhumid']=int(bv[164:171]) 440 r['dewpoint']=Decimal(binary.signedIntFromBV(bv[171:181]))/Decimal('10') 441 r['airpressure']=Decimal(int(bv[181:190]))/Decimal('1')+Decimal('800') 442 r['airpressuretrend']=int(bv[190:192]) 443 r['horizvis']=Decimal(int(bv[192:200]))/Decimal('10') 444 r['waterlevel']=Decimal(binary.signedIntFromBV(bv[200:209]))/Decimal('10') 445 r['waterleveltrend']=int(bv[209:211]) 446 r['surfcurspeed']=Decimal(int(bv[211:219]))/Decimal('10') 447 r['surfcurdir']=int(bv[219:228]) 448 r['curspeed2']=Decimal(int(bv[228:236]))/Decimal('10') 449 r['curdir2']=int(bv[236:245]) 450 r['curlevel2']=int(bv[245:250]) 451 r['curspeed3']=Decimal(int(bv[250:258]))/Decimal('10') 452 r['curdir3']=int(bv[258:267]) 453 r['curlevel3']=int(bv[267:272]) 454 r['sigwaveheight']=Decimal(int(bv[272:280]))/Decimal('10') 455 r['waveperiod']=int(bv[280:286]) 456 r['wavedir']=int(bv[286:295]) 457 r['swellheight']=Decimal(int(bv[295:303]))/Decimal('10') 458 r['swellperiod']=int(bv[303:309]) 459 r['swelldir']=int(bv[309:318]) 460 r['seastate']=int(bv[318:322]) 461 r['watertemp']=Decimal(int(bv[322:332]))/Decimal('10')+Decimal('-10') 462 r['preciptype']=int(bv[332:335]) 463 r['salinity']=Decimal(binary.signedIntFromBV(bv[335:344]))/Decimal('10') 464 r['ice']=int(bv[344:346]) 465 r['Spare']=0 466 return r
467
468 -def decodeMessageID(bv, validate=False):
469 return 8
470
471 -def decodeRepeatIndicator(bv, validate=False):
472 return int(bv[6:8])
473
474 -def decodeUserID(bv, validate=False):
475 return int(bv[8:38])
476
477 -def decodeSpare(bv, validate=False):
478 return 0
479
480 -def decodedac(bv, validate=False):
481 return 1
482
483 -def decodefid(bv, validate=False):
484 return 11
485
486 -def decodelatitude(bv, validate=False):
487 return Decimal(binary.signedIntFromBV(bv[56:80]))/Decimal('60000')
488
489 -def decodelongitude(bv, validate=False):
490 return Decimal(binary.signedIntFromBV(bv[80:105]))/Decimal('60000')
491
492 -def decodeday(bv, validate=False):
493 return int(bv[105:110])
494
495 -def decodehour(bv, validate=False):
496 return int(bv[110:115])
497
498 -def decodemin(bv, validate=False):
499 return int(bv[115:121])
500
501 -def decodeavewind(bv, validate=False):
502 return int(bv[121:128])
503
504 -def decodewindgust(bv, validate=False):
505 return int(bv[128:135])
506
507 -def decodewinddir(bv, validate=False):
508 return int(bv[135:144])
509
510 -def decodewindgustdir(bv, validate=False):
511 return int(bv[144:153])
512
513 -def decodeairtemp(bv, validate=False):
514 return Decimal(binary.signedIntFromBV(bv[153:164]))/Decimal('10')
515
516 -def decoderelhumid(bv, validate=False):
517 return int(bv[164:171])
518
519 -def decodedewpoint(bv, validate=False):
520 return Decimal(binary.signedIntFromBV(bv[171:181]))/Decimal('10')
521
522 -def decodeairpressure(bv, validate=False):
523 return Decimal(int(bv[181:190]))/Decimal('1')+Decimal('800')
524
525 -def decodeairpressuretrend(bv, validate=False):
526 return int(bv[190:192])
527
528 -def decodehorizvis(bv, validate=False):
529 return Decimal(int(bv[192:200]))/Decimal('10')
530
531 -def decodewaterlevel(bv, validate=False):
532 return Decimal(binary.signedIntFromBV(bv[200:209]))/Decimal('10')
533
534 -def decodewaterleveltrend(bv, validate=False):
535 return int(bv[209:211])
536
537 -def decodesurfcurspeed(bv, validate=False):
538 return Decimal(int(bv[211:219]))/Decimal('10')
539
540 -def decodesurfcurdir(bv, validate=False):
541 return int(bv[219:228])
542
543 -def decodecurspeed2(bv, validate=False):
544 return Decimal(int(bv[228:236]))/Decimal('10')
545
546 -def decodecurdir2(bv, validate=False):
547 return int(bv[236:245])
548
549 -def decodecurlevel2(bv, validate=False):
550 return int(bv[245:250])
551
552 -def decodecurspeed3(bv, validate=False):
553 return Decimal(int(bv[250:258]))/Decimal('10')
554
555 -def decodecurdir3(bv, validate=False):
556 return int(bv[258:267])
557
558 -def decodecurlevel3(bv, validate=False):
559 return int(bv[267:272])
560
561 -def decodesigwaveheight(bv, validate=False):
562 return Decimal(int(bv[272:280]))/Decimal('10')
563
564 -def decodewaveperiod(bv, validate=False):
565 return int(bv[280:286])
566
567 -def decodewavedir(bv, validate=False):
568 return int(bv[286:295])
569
570 -def decodeswellheight(bv, validate=False):
571 return Decimal(int(bv[295:303]))/Decimal('10')
572
573 -def decodeswellperiod(bv, validate=False):
574 return int(bv[303:309])
575
576 -def decodeswelldir(bv, validate=False):
577 return int(bv[309:318])
578
579 -def decodeseastate(bv, validate=False):
580 return int(bv[318:322])
581
582 -def decodewatertemp(bv, validate=False):
583 return Decimal(int(bv[322:332]))/Decimal('10')+Decimal('-10')
584
585 -def decodepreciptype(bv, validate=False):
586 return int(bv[332:335])
587
588 -def decodesalinity(bv, validate=False):
589 return Decimal(binary.signedIntFromBV(bv[335:344]))/Decimal('10')
590
591 -def decodeice(bv, validate=False):
592 return int(bv[344:346])
593
594 -def decodeSpare(bv, validate=False):
595 return 0
596 597
598 -def printHtml(params, out=sys.stdout):
599 out.write("<h3>imo_met_hydro</h3>\n") 600 out.write("<table border=\"1\">\n") 601 out.write("<tr bgcolor=\"orange\">\n") 602 out.write("<th align=\"left\">Field Name</th>\n") 603 out.write("<th align=\"left\">Type</th>\n") 604 out.write("<th align=\"left\">Value</th>\n") 605 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 606 out.write("<th align=\"left\">Units</th>\n") 607 out.write("\n") 608 out.write("<tr>\n") 609 out.write("<td>MessageID</td>\n") 610 out.write("<td>uint</td>\n") 611 if 'MessageID' in params: 612 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 613 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 614 out.write("</tr>\n") 615 out.write("\n") 616 out.write("<tr>\n") 617 out.write("<td>RepeatIndicator</td>\n") 618 out.write("<td>uint</td>\n") 619 if 'RepeatIndicator' in params: 620 out.write(" <td>"+str(params['RepeatIndicator'])+"</td>\n") 621 if str(params['RepeatIndicator']) in RepeatIndicatorDecodeLut: 622 out.write("<td>"+RepeatIndicatorDecodeLut[str(params['RepeatIndicator'])]+"</td>") 623 else: 624 out.write("<td><i>Missing LUT entry</i></td>") 625 out.write("</tr>\n") 626 out.write("\n") 627 out.write("<tr>\n") 628 out.write("<td>UserID</td>\n") 629 out.write("<td>uint</td>\n") 630 if 'UserID' in params: 631 out.write(" <td>"+str(params['UserID'])+"</td>\n") 632 out.write(" <td>"+str(params['UserID'])+"</td>\n") 633 out.write("</tr>\n") 634 out.write("\n") 635 out.write("<tr>\n") 636 out.write("<td>Spare</td>\n") 637 out.write("<td>uint</td>\n") 638 if 'Spare' in params: 639 out.write(" <td>"+str(params['Spare'])+"</td>\n") 640 out.write(" <td>"+str(params['Spare'])+"</td>\n") 641 out.write("</tr>\n") 642 out.write("\n") 643 out.write("<tr>\n") 644 out.write("<td>dac</td>\n") 645 out.write("<td>uint</td>\n") 646 if 'dac' in params: 647 out.write(" <td>"+str(params['dac'])+"</td>\n") 648 out.write(" <td>"+str(params['dac'])+"</td>\n") 649 out.write("</tr>\n") 650 out.write("\n") 651 out.write("<tr>\n") 652 out.write("<td>fid</td>\n") 653 out.write("<td>uint</td>\n") 654 if 'fid' in params: 655 out.write(" <td>"+str(params['fid'])+"</td>\n") 656 out.write(" <td>"+str(params['fid'])+"</td>\n") 657 out.write("</tr>\n") 658 out.write("\n") 659 out.write("<tr>\n") 660 out.write("<td>latitude</td>\n") 661 out.write("<td>decimal</td>\n") 662 if 'latitude' in params: 663 out.write(" <td>"+str(params['latitude'])+"</td>\n") 664 out.write(" <td>"+str(params['latitude'])+"</td>\n") 665 out.write("<td>degrees</td>\n") 666 out.write("</tr>\n") 667 out.write("\n") 668 out.write("<tr>\n") 669 out.write("<td>longitude</td>\n") 670 out.write("<td>decimal</td>\n") 671 if 'longitude' in params: 672 out.write(" <td>"+str(params['longitude'])+"</td>\n") 673 out.write(" <td>"+str(params['longitude'])+"</td>\n") 674 out.write("<td>degrees</td>\n") 675 out.write("</tr>\n") 676 out.write("\n") 677 out.write("<tr>\n") 678 out.write("<td>day</td>\n") 679 out.write("<td>uint</td>\n") 680 if 'day' in params: 681 out.write(" <td>"+str(params['day'])+"</td>\n") 682 out.write(" <td>"+str(params['day'])+"</td>\n") 683 out.write("<td>days</td>\n") 684 out.write("</tr>\n") 685 out.write("\n") 686 out.write("<tr>\n") 687 out.write("<td>hour</td>\n") 688 out.write("<td>uint</td>\n") 689 if 'hour' in params: 690 out.write(" <td>"+str(params['hour'])+"</td>\n") 691 out.write(" <td>"+str(params['hour'])+"</td>\n") 692 out.write("<td>hours</td>\n") 693 out.write("</tr>\n") 694 out.write("\n") 695 out.write("<tr>\n") 696 out.write("<td>min</td>\n") 697 out.write("<td>uint</td>\n") 698 if 'min' in params: 699 out.write(" <td>"+str(params['min'])+"</td>\n") 700 out.write(" <td>"+str(params['min'])+"</td>\n") 701 out.write("<td>minutes</td>\n") 702 out.write("</tr>\n") 703 out.write("\n") 704 out.write("<tr>\n") 705 out.write("<td>avewind</td>\n") 706 out.write("<td>uint</td>\n") 707 if 'avewind' in params: 708 out.write(" <td>"+str(params['avewind'])+"</td>\n") 709 out.write(" <td>"+str(params['avewind'])+"</td>\n") 710 out.write("<td>knots</td>\n") 711 out.write("</tr>\n") 712 out.write("\n") 713 out.write("<tr>\n") 714 out.write("<td>windgust</td>\n") 715 out.write("<td>uint</td>\n") 716 if 'windgust' in params: 717 out.write(" <td>"+str(params['windgust'])+"</td>\n") 718 out.write(" <td>"+str(params['windgust'])+"</td>\n") 719 out.write("<td>knots</td>\n") 720 out.write("</tr>\n") 721 out.write("\n") 722 out.write("<tr>\n") 723 out.write("<td>winddir</td>\n") 724 out.write("<td>uint</td>\n") 725 if 'winddir' in params: 726 out.write(" <td>"+str(params['winddir'])+"</td>\n") 727 out.write(" <td>"+str(params['winddir'])+"</td>\n") 728 out.write("<td>degrees</td>\n") 729 out.write("</tr>\n") 730 out.write("\n") 731 out.write("<tr>\n") 732 out.write("<td>windgustdir</td>\n") 733 out.write("<td>uint</td>\n") 734 if 'windgustdir' in params: 735 out.write(" <td>"+str(params['windgustdir'])+"</td>\n") 736 out.write(" <td>"+str(params['windgustdir'])+"</td>\n") 737 out.write("<td>degrees</td>\n") 738 out.write("</tr>\n") 739 out.write("\n") 740 out.write("<tr>\n") 741 out.write("<td>airtemp</td>\n") 742 out.write("<td>decimal</td>\n") 743 if 'airtemp' in params: 744 out.write(" <td>"+str(params['airtemp'])+"</td>\n") 745 out.write(" <td>"+str(params['airtemp'])+"</td>\n") 746 out.write("<td>degrees Celsius</td>\n") 747 out.write("</tr>\n") 748 out.write("\n") 749 out.write("<tr>\n") 750 out.write("<td>relhumid</td>\n") 751 out.write("<td>uint</td>\n") 752 if 'relhumid' in params: 753 out.write(" <td>"+str(params['relhumid'])+"</td>\n") 754 out.write(" <td>"+str(params['relhumid'])+"</td>\n") 755 out.write("<td>percent</td>\n") 756 out.write("</tr>\n") 757 out.write("\n") 758 out.write("<tr>\n") 759 out.write("<td>dewpoint</td>\n") 760 out.write("<td>decimal</td>\n") 761 if 'dewpoint' in params: 762 out.write(" <td>"+str(params['dewpoint'])+"</td>\n") 763 out.write(" <td>"+str(params['dewpoint'])+"</td>\n") 764 out.write("<td>degrees Celsius</td>\n") 765 out.write("</tr>\n") 766 out.write("\n") 767 out.write("<tr>\n") 768 out.write("<td>airpressure</td>\n") 769 out.write("<td>udecimal</td>\n") 770 if 'airpressure' in params: 771 out.write(" <td>"+str(params['airpressure'])+"</td>\n") 772 out.write(" <td>"+str(params['airpressure'])+"</td>\n") 773 out.write("<td>hPa</td>\n") 774 out.write("</tr>\n") 775 out.write("\n") 776 out.write("<tr>\n") 777 out.write("<td>airpressuretrend</td>\n") 778 out.write("<td>uint</td>\n") 779 if 'airpressuretrend' in params: 780 out.write(" <td>"+str(params['airpressuretrend'])+"</td>\n") 781 if str(params['airpressuretrend']) in airpressuretrendDecodeLut: 782 out.write("<td>"+airpressuretrendDecodeLut[str(params['airpressuretrend'])]+"</td>") 783 else: 784 out.write("<td><i>Missing LUT entry</i></td>") 785 out.write("</tr>\n") 786 out.write("\n") 787 out.write("<tr>\n") 788 out.write("<td>horizvis</td>\n") 789 out.write("<td>udecimal</td>\n") 790 if 'horizvis' in params: 791 out.write(" <td>"+str(params['horizvis'])+"</td>\n") 792 out.write(" <td>"+str(params['horizvis'])+"</td>\n") 793 out.write("<td>nm</td>\n") 794 out.write("</tr>\n") 795 out.write("\n") 796 out.write("<tr>\n") 797 out.write("<td>waterlevel</td>\n") 798 out.write("<td>decimal</td>\n") 799 if 'waterlevel' in params: 800 out.write(" <td>"+str(params['waterlevel'])+"</td>\n") 801 out.write(" <td>"+str(params['waterlevel'])+"</td>\n") 802 out.write("<td>m</td>\n") 803 out.write("</tr>\n") 804 out.write("\n") 805 out.write("<tr>\n") 806 out.write("<td>waterleveltrend</td>\n") 807 out.write("<td>uint</td>\n") 808 if 'waterleveltrend' in params: 809 out.write(" <td>"+str(params['waterleveltrend'])+"</td>\n") 810 if str(params['waterleveltrend']) in waterleveltrendDecodeLut: 811 out.write("<td>"+waterleveltrendDecodeLut[str(params['waterleveltrend'])]+"</td>") 812 else: 813 out.write("<td><i>Missing LUT entry</i></td>") 814 out.write("</tr>\n") 815 out.write("\n") 816 out.write("<tr>\n") 817 out.write("<td>surfcurspeed</td>\n") 818 out.write("<td>udecimal</td>\n") 819 if 'surfcurspeed' in params: 820 out.write(" <td>"+str(params['surfcurspeed'])+"</td>\n") 821 out.write(" <td>"+str(params['surfcurspeed'])+"</td>\n") 822 out.write("<td>knots</td>\n") 823 out.write("</tr>\n") 824 out.write("\n") 825 out.write("<tr>\n") 826 out.write("<td>surfcurdir</td>\n") 827 out.write("<td>uint</td>\n") 828 if 'surfcurdir' in params: 829 out.write(" <td>"+str(params['surfcurdir'])+"</td>\n") 830 out.write(" <td>"+str(params['surfcurdir'])+"</td>\n") 831 out.write("<td>degrees</td>\n") 832 out.write("</tr>\n") 833 out.write("\n") 834 out.write("<tr>\n") 835 out.write("<td>curspeed2</td>\n") 836 out.write("<td>udecimal</td>\n") 837 if 'curspeed2' in params: 838 out.write(" <td>"+str(params['curspeed2'])+"</td>\n") 839 out.write(" <td>"+str(params['curspeed2'])+"</td>\n") 840 out.write("<td>knots</td>\n") 841 out.write("</tr>\n") 842 out.write("\n") 843 out.write("<tr>\n") 844 out.write("<td>curdir2</td>\n") 845 out.write("<td>uint</td>\n") 846 if 'curdir2' in params: 847 out.write(" <td>"+str(params['curdir2'])+"</td>\n") 848 out.write(" <td>"+str(params['curdir2'])+"</td>\n") 849 out.write("<td>degrees</td>\n") 850 out.write("</tr>\n") 851 out.write("\n") 852 out.write("<tr>\n") 853 out.write("<td>curlevel2</td>\n") 854 out.write("<td>uint</td>\n") 855 if 'curlevel2' in params: 856 out.write(" <td>"+str(params['curlevel2'])+"</td>\n") 857 out.write(" <td>"+str(params['curlevel2'])+"</td>\n") 858 out.write("<td>m</td>\n") 859 out.write("</tr>\n") 860 out.write("\n") 861 out.write("<tr>\n") 862 out.write("<td>curspeed3</td>\n") 863 out.write("<td>udecimal</td>\n") 864 if 'curspeed3' in params: 865 out.write(" <td>"+str(params['curspeed3'])+"</td>\n") 866 out.write(" <td>"+str(params['curspeed3'])+"</td>\n") 867 out.write("<td>knots</td>\n") 868 out.write("</tr>\n") 869 out.write("\n") 870 out.write("<tr>\n") 871 out.write("<td>curdir3</td>\n") 872 out.write("<td>uint</td>\n") 873 if 'curdir3' in params: 874 out.write(" <td>"+str(params['curdir3'])+"</td>\n") 875 out.write(" <td>"+str(params['curdir3'])+"</td>\n") 876 out.write("<td>degrees</td>\n") 877 out.write("</tr>\n") 878 out.write("\n") 879 out.write("<tr>\n") 880 out.write("<td>curlevel3</td>\n") 881 out.write("<td>uint</td>\n") 882 if 'curlevel3' in params: 883 out.write(" <td>"+str(params['curlevel3'])+"</td>\n") 884 out.write(" <td>"+str(params['curlevel3'])+"</td>\n") 885 out.write("<td>m</td>\n") 886 out.write("</tr>\n") 887 out.write("\n") 888 out.write("<tr>\n") 889 out.write("<td>sigwaveheight</td>\n") 890 out.write("<td>udecimal</td>\n") 891 if 'sigwaveheight' in params: 892 out.write(" <td>"+str(params['sigwaveheight'])+"</td>\n") 893 out.write(" <td>"+str(params['sigwaveheight'])+"</td>\n") 894 out.write("<td>m</td>\n") 895 out.write("</tr>\n") 896 out.write("\n") 897 out.write("<tr>\n") 898 out.write("<td>waveperiod</td>\n") 899 out.write("<td>uint</td>\n") 900 if 'waveperiod' in params: 901 out.write(" <td>"+str(params['waveperiod'])+"</td>\n") 902 out.write(" <td>"+str(params['waveperiod'])+"</td>\n") 903 out.write("<td>sec</td>\n") 904 out.write("</tr>\n") 905 out.write("\n") 906 out.write("<tr>\n") 907 out.write("<td>wavedir</td>\n") 908 out.write("<td>uint</td>\n") 909 if 'wavedir' in params: 910 out.write(" <td>"+str(params['wavedir'])+"</td>\n") 911 out.write(" <td>"+str(params['wavedir'])+"</td>\n") 912 out.write("<td>degrees</td>\n") 913 out.write("</tr>\n") 914 out.write("\n") 915 out.write("<tr>\n") 916 out.write("<td>swellheight</td>\n") 917 out.write("<td>udecimal</td>\n") 918 if 'swellheight' in params: 919 out.write(" <td>"+str(params['swellheight'])+"</td>\n") 920 out.write(" <td>"+str(params['swellheight'])+"</td>\n") 921 out.write("<td>m</td>\n") 922 out.write("</tr>\n") 923 out.write("\n") 924 out.write("<tr>\n") 925 out.write("<td>swellperiod</td>\n") 926 out.write("<td>uint</td>\n") 927 if 'swellperiod' in params: 928 out.write(" <td>"+str(params['swellperiod'])+"</td>\n") 929 out.write(" <td>"+str(params['swellperiod'])+"</td>\n") 930 out.write("<td>sec</td>\n") 931 out.write("</tr>\n") 932 out.write("\n") 933 out.write("<tr>\n") 934 out.write("<td>swelldir</td>\n") 935 out.write("<td>uint</td>\n") 936 if 'swelldir' in params: 937 out.write(" <td>"+str(params['swelldir'])+"</td>\n") 938 out.write(" <td>"+str(params['swelldir'])+"</td>\n") 939 out.write("<td>degrees</td>\n") 940 out.write("</tr>\n") 941 out.write("\n") 942 out.write("<tr>\n") 943 out.write("<td>seastate</td>\n") 944 out.write("<td>uint</td>\n") 945 if 'seastate' in params: 946 out.write(" <td>"+str(params['seastate'])+"</td>\n") 947 if str(params['seastate']) in seastateDecodeLut: 948 out.write("<td>"+seastateDecodeLut[str(params['seastate'])]+"</td>") 949 else: 950 out.write("<td><i>Missing LUT entry</i></td>") 951 out.write("<td>Beaufort scale</td>\n") 952 out.write("</tr>\n") 953 out.write("\n") 954 out.write("<tr>\n") 955 out.write("<td>watertemp</td>\n") 956 out.write("<td>udecimal</td>\n") 957 if 'watertemp' in params: 958 out.write(" <td>"+str(params['watertemp'])+"</td>\n") 959 out.write(" <td>"+str(params['watertemp'])+"</td>\n") 960 out.write("<td>degrees Celsius</td>\n") 961 out.write("</tr>\n") 962 out.write("\n") 963 out.write("<tr>\n") 964 out.write("<td>preciptype</td>\n") 965 out.write("<td>uint</td>\n") 966 if 'preciptype' in params: 967 out.write(" <td>"+str(params['preciptype'])+"</td>\n") 968 if str(params['preciptype']) in preciptypeDecodeLut: 969 out.write("<td>"+preciptypeDecodeLut[str(params['preciptype'])]+"</td>") 970 else: 971 out.write("<td><i>Missing LUT entry</i></td>") 972 out.write("<td>WMO scale index</td>\n") 973 out.write("</tr>\n") 974 out.write("\n") 975 out.write("<tr>\n") 976 out.write("<td>salinity</td>\n") 977 out.write("<td>decimal</td>\n") 978 if 'salinity' in params: 979 out.write(" <td>"+str(params['salinity'])+"</td>\n") 980 out.write(" <td>"+str(params['salinity'])+"</td>\n") 981 out.write("<td>0/00</td>\n") 982 out.write("</tr>\n") 983 out.write("\n") 984 out.write("<tr>\n") 985 out.write("<td>ice</td>\n") 986 out.write("<td>uint</td>\n") 987 if 'ice' in params: 988 out.write(" <td>"+str(params['ice'])+"</td>\n") 989 if str(params['ice']) in iceDecodeLut: 990 out.write("<td>"+iceDecodeLut[str(params['ice'])]+"</td>") 991 else: 992 out.write("<td><i>Missing LUT entry</i></td>") 993 out.write("</tr>\n") 994 out.write("\n") 995 out.write("<tr>\n") 996 out.write("<td>Spare</td>\n") 997 out.write("<td>uint</td>\n") 998 if 'Spare' in params: 999 out.write(" <td>"+str(params['Spare'])+"</td>\n") 1000 out.write(" <td>"+str(params['Spare'])+"</td>\n") 1001 out.write("</tr>\n") 1002 out.write("</table>\n")
1003 1004
1005 -def printKml(params, out=sys.stdout):
1006 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer''' 1007 out.write("\ <Placemark>\n") 1008 out.write("\t <name>"+str(params['UserID'])+"</name>\n") 1009 out.write("\t\t<description>\n") 1010 import StringIO 1011 buf = StringIO.StringIO() 1012 printHtml(params,buf) 1013 import cgi 1014 out.write(cgi.escape(buf.getvalue())) 1015 out.write("\t\t</description>\n") 1016 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n") 1017 out.write("\t\t<Point>\n") 1018 out.write("\t\t\t<coordinates>") 1019 out.write(str(params['longitude'])) 1020 out.write(',') 1021 out.write(str(params['latitude'])) 1022 out.write(",0</coordinates>\n") 1023 out.write("\t\t</Point>\n") 1024 out.write("\t</Placemark>\n")
1025
1026 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'):
1027 '''Print a imo_met_hydro message to stdout. 1028 1029 Fields in params: 1030 - MessageID(uint): AIS message number. Must be 8 (field automatically set to "8") 1031 - RepeatIndicator(uint): Indicated how many times a message has been repeated 1032 - UserID(uint): MMSI number of transmitter broadcasting the message 1033 - Spare(uint): Reserved for definition by a regional authority. (field automatically set to "0") 1034 - dac(uint): Designated Area Code - part 1 of the IAI (field automatically set to "1") 1035 - fid(uint): Functional Identifier - part 2 of the IAI (field automatically set to "11") 1036 - latitude(decimal): Location of the vessel. North South location 1037 - longitude(decimal): Location of the vessel. East West location 1038 - day(uint): Day 0..31 1039 - hour(uint): Hour 0..23 1040 - min(uint): Min 1041 - avewind(uint): Average wind speed values for the last 10 minutes. 1042 - windgust(uint): Wind gust is the max wind speed value reading during the last 10 minutes. 1043 - winddir(uint): Wind direction 1044 - windgustdir(uint): Wind direction for the gust. 1045 - airtemp(decimal): Dry bulb temperature 1046 - relhumid(uint): Relative humidity 1047 - dewpoint(decimal): Dew Point 1048 - airpressure(udecimal): Air pressure 1049 - airpressuretrend(uint): Air pressure trend 1050 - horizvis(udecimal): Horizontal visibility 1051 - waterlevel(decimal): Water level (incl. tide) 1052 - waterleveltrend(uint): Water level trend 1053 - surfcurspeed(udecimal): Surface current speed 1054 - surfcurdir(uint): Surface current direction 1055 - curspeed2(udecimal): Level 2 current speed 1056 - curdir2(uint): Level 2 current direction 1057 - curlevel2(uint): Measuring level below sea surface for level 2 1058 - curspeed3(udecimal): Level 3 current speed 1059 - curdir3(uint): Level 3 current direction 1060 - curlevel3(uint): Measuring level below sea surface for level 3 1061 - sigwaveheight(udecimal): Significant wave height 1062 - waveperiod(uint): Wave period 1063 - wavedir(uint): Wave direction 1064 - swellheight(udecimal): Swell height 1065 - swellperiod(uint): Swell period 1066 - swelldir(uint): Swell direction 1067 - seastate(uint): Sea state according to the Beaufort scale 1068 - watertemp(udecimal): Water temperature 1069 - preciptype(uint): According to WMO 1070 - salinity(decimal): Salinity 1071 - ice(uint): Yes or no for the presence of ice 1072 - Spare(uint): Must be zero (field automatically set to "0") 1073 @param params: Dictionary of field names/values. 1074 @param out: File like object to write to 1075 @rtype: stdout 1076 @return: text to out 1077 ''' 1078 1079 if 'std'==format: 1080 out.write("imo_met_hydro:\n") 1081 if 'MessageID' in params: out.write(" MessageID: "+str(params['MessageID'])+"\n") 1082 if 'RepeatIndicator' in params: out.write(" RepeatIndicator: "+str(params['RepeatIndicator'])+"\n") 1083 if 'UserID' in params: out.write(" UserID: "+str(params['UserID'])+"\n") 1084 if 'Spare' in params: out.write(" Spare: "+str(params['Spare'])+"\n") 1085 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n") 1086 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n") 1087 if 'latitude' in params: out.write(" latitude: "+str(params['latitude'])+"\n") 1088 if 'longitude' in params: out.write(" longitude: "+str(params['longitude'])+"\n") 1089 if 'day' in params: out.write(" day: "+str(params['day'])+"\n") 1090 if 'hour' in params: out.write(" hour: "+str(params['hour'])+"\n") 1091 if 'min' in params: out.write(" min: "+str(params['min'])+"\n") 1092 if 'avewind' in params: out.write(" avewind: "+str(params['avewind'])+"\n") 1093 if 'windgust' in params: out.write(" windgust: "+str(params['windgust'])+"\n") 1094 if 'winddir' in params: out.write(" winddir: "+str(params['winddir'])+"\n") 1095 if 'windgustdir' in params: out.write(" windgustdir: "+str(params['windgustdir'])+"\n") 1096 if 'airtemp' in params: out.write(" airtemp: "+str(params['airtemp'])+"\n") 1097 if 'relhumid' in params: out.write(" relhumid: "+str(params['relhumid'])+"\n") 1098 if 'dewpoint' in params: out.write(" dewpoint: "+str(params['dewpoint'])+"\n") 1099 if 'airpressure' in params: out.write(" airpressure: "+str(params['airpressure'])+"\n") 1100 if 'airpressuretrend' in params: out.write(" airpressuretrend: "+str(params['airpressuretrend'])+"\n") 1101 if 'horizvis' in params: out.write(" horizvis: "+str(params['horizvis'])+"\n") 1102 if 'waterlevel' in params: out.write(" waterlevel: "+str(params['waterlevel'])+"\n") 1103 if 'waterleveltrend' in params: out.write(" waterleveltrend: "+str(params['waterleveltrend'])+"\n") 1104 if 'surfcurspeed' in params: out.write(" surfcurspeed: "+str(params['surfcurspeed'])+"\n") 1105 if 'surfcurdir' in params: out.write(" surfcurdir: "+str(params['surfcurdir'])+"\n") 1106 if 'curspeed2' in params: out.write(" curspeed2: "+str(params['curspeed2'])+"\n") 1107 if 'curdir2' in params: out.write(" curdir2: "+str(params['curdir2'])+"\n") 1108 if 'curlevel2' in params: out.write(" curlevel2: "+str(params['curlevel2'])+"\n") 1109 if 'curspeed3' in params: out.write(" curspeed3: "+str(params['curspeed3'])+"\n") 1110 if 'curdir3' in params: out.write(" curdir3: "+str(params['curdir3'])+"\n") 1111 if 'curlevel3' in params: out.write(" curlevel3: "+str(params['curlevel3'])+"\n") 1112 if 'sigwaveheight' in params: out.write(" sigwaveheight: "+str(params['sigwaveheight'])+"\n") 1113 if 'waveperiod' in params: out.write(" waveperiod: "+str(params['waveperiod'])+"\n") 1114 if 'wavedir' in params: out.write(" wavedir: "+str(params['wavedir'])+"\n") 1115 if 'swellheight' in params: out.write(" swellheight: "+str(params['swellheight'])+"\n") 1116 if 'swellperiod' in params: out.write(" swellperiod: "+str(params['swellperiod'])+"\n") 1117 if 'swelldir' in params: out.write(" swelldir: "+str(params['swelldir'])+"\n") 1118 if 'seastate' in params: out.write(" seastate: "+str(params['seastate'])+"\n") 1119 if 'watertemp' in params: out.write(" watertemp: "+str(params['watertemp'])+"\n") 1120 if 'preciptype' in params: out.write(" preciptype: "+str(params['preciptype'])+"\n") 1121 if 'salinity' in params: out.write(" salinity: "+str(params['salinity'])+"\n") 1122 if 'ice' in params: out.write(" ice: "+str(params['ice'])+"\n") 1123 if 'Spare' in params: out.write(" Spare: "+str(params['Spare'])+"\n") 1124 elif 'csv'==format: 1125 if None == options.fieldList: 1126 options.fieldList = fieldList 1127 needComma = False; 1128 for field in fieldList: 1129 if needComma: out.write(',') 1130 needComma = True 1131 if field in params: 1132 out.write(str(params[field])) 1133 # else: leave it empty 1134 out.write("\n") 1135 elif 'html'==format: 1136 printHtml(params,out) 1137 elif 'sql'==format: 1138 sqlInsertStr(params,out,dbType=dbType) 1139 elif 'kml'==format: 1140 printKml(params,out) 1141 elif 'kml-full'==format: 1142 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 1143 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n") 1144 out.write("<Document>\n") 1145 out.write(" <name>imo_met_hydro</name>\n") 1146 printKml(params,out) 1147 out.write("</Document>\n") 1148 out.write("</kml>\n") 1149 else: 1150 print "ERROR: unknown format:",format 1151 assert False 1152 1153 return # Nothing to return
1154 1155 RepeatIndicatorEncodeLut = { 1156 'default':'0', 1157 'do not repeat any more':'3', 1158 } #RepeatIndicatorEncodeLut 1159 1160 RepeatIndicatorDecodeLut = { 1161 '0':'default', 1162 '3':'do not repeat any more', 1163 } # RepeatIndicatorEncodeLut 1164 1165 airpressuretrendEncodeLut = { 1166 'steady':'0', 1167 'decreasing':'1', 1168 'increasing':'2', 1169 'unavailable':'3', 1170 } #airpressuretrendEncodeLut 1171 1172 airpressuretrendDecodeLut = { 1173 '0':'steady', 1174 '1':'decreasing', 1175 '2':'increasing', 1176 '3':'unavailable', 1177 } # airpressuretrendEncodeLut 1178 1179 waterleveltrendEncodeLut = { 1180 'steady':'0', 1181 'decreasing':'1', 1182 'increasing':'2', 1183 'unavailable':'3', 1184 } #waterleveltrendEncodeLut 1185 1186 waterleveltrendDecodeLut = { 1187 '0':'steady', 1188 '1':'decreasing', 1189 '2':'increasing', 1190 '3':'unavailable', 1191 } # waterleveltrendEncodeLut 1192 1193 seastateEncodeLut = { 1194 'Calm':'0', 1195 'Light air':'1', 1196 'Light breeze':'2', 1197 'Gentle breeze':'3', 1198 'Moderate breeze':'4', 1199 'Fresh breeze':'5', 1200 'Strong breeze':'6', 1201 'Near gale':'7', 1202 'Gale':'8', 1203 'Strong gale':'9', 1204 'Storm':'10', 1205 'Violent storm':'11', 1206 'Hurricane':'12', 1207 'unavailable':'15', 1208 } #seastateEncodeLut 1209 1210 seastateDecodeLut = { 1211 '0':'Calm', 1212 '1':'Light air', 1213 '2':'Light breeze', 1214 '3':'Gentle breeze', 1215 '4':'Moderate breeze', 1216 '5':'Fresh breeze', 1217 '6':'Strong breeze', 1218 '7':'Near gale', 1219 '8':'Gale', 1220 '9':'Strong gale', 1221 '10':'Storm', 1222 '11':'Violent storm', 1223 '12':'Hurricane', 1224 '15':'unavailable', 1225 } # seastateEncodeLut 1226 1227 preciptypeEncodeLut = { 1228 'FIX: find the WMO list of types':'0', 1229 'unavailable':'7', 1230 } #preciptypeEncodeLut 1231 1232 preciptypeDecodeLut = { 1233 '0':'FIX: find the WMO list of types', 1234 '7':'unavailable', 1235 } # preciptypeEncodeLut 1236 1237 iceEncodeLut = { 1238 'Not sure. Maybe no ice?':'0', 1239 'Not sure. Maybe yes ice?':'1', 1240 'Not sure. Maybe not allowed?':'2', 1241 'Unknown?':'3', 1242 } #iceEncodeLut 1243 1244 iceDecodeLut = { 1245 '0':'Not sure. Maybe no ice?', 1246 '1':'Not sure. Maybe yes ice?', 1247 '2':'Not sure. Maybe not allowed?', 1248 '3':'Unknown?', 1249 } # iceEncodeLut 1250 1251 ###################################################################### 1252 # SQL SUPPORT 1253 ###################################################################### 1254 1255 dbTableName='imo_met_hydro' 1256 'Database table name' 1257
1258 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 1259 ,addCoastGuardFields=True 1260 ,dbType='postgres' 1261 ):
1262 ''' 1263 Return the SQL CREATE command for this message type 1264 @param outfile: file like object to print to. 1265 @param fields: which fields to put in the create. Defaults to all. 1266 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 1267 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 1268 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 1269 @type addCoastGuardFields: bool 1270 @return: sql create string 1271 @rtype: str 1272 1273 @see: sqlCreate 1274 ''' 1275 # FIX: should this sqlCreate be the same as in LaTeX (createFuncName) rather than hard coded? 1276 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
1277
1278 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
1279 ''' 1280 Return the sqlhelp object to create the table. 1281 1282 @param fields: which fields to put in the create. Defaults to all. 1283 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 1284 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 1285 @type addCoastGuardFields: bool 1286 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 1287 @return: An object that can be used to generate a return 1288 @rtype: sqlhelp.create 1289 ''' 1290 if None == fields: fields = fieldList 1291 import sqlhelp 1292 c = sqlhelp.create('imo_met_hydro',dbType=dbType) 1293 c.addPrimaryKey() 1294 if 'MessageID' in fields: c.addInt ('MessageID') 1295 if 'RepeatIndicator' in fields: c.addInt ('RepeatIndicator') 1296 if 'UserID' in fields: c.addInt ('UserID') 1297 if 'Spare' in fields: c.addInt ('Spare') 1298 if 'dac' in fields: c.addInt ('dac') 1299 if 'fid' in fields: c.addInt ('fid') 1300 if dbType != 'postgres': 1301 if 'latitude' in fields: c.addDecimal('latitude',7,4) 1302 if dbType != 'postgres': 1303 if 'longitude' in fields: c.addDecimal('longitude',7,4) 1304 if 'day' in fields: c.addInt ('day') 1305 if 'hour' in fields: c.addInt ('hour') 1306 if 'min' in fields: c.addInt ('min') 1307 if 'avewind' in fields: c.addInt ('avewind') 1308 if 'windgust' in fields: c.addInt ('windgust') 1309 if 'winddir' in fields: c.addInt ('winddir') 1310 if 'windgustdir' in fields: c.addInt ('windgustdir') 1311 if 'airtemp' in fields: c.addDecimal('airtemp',4,1) 1312 if 'relhumid' in fields: c.addInt ('relhumid') 1313 if 'dewpoint' in fields: c.addDecimal('dewpoint',4,1) 1314 if 'airpressure' in fields: c.addDecimal('airpressure',3,0) 1315 if 'airpressuretrend' in fields: c.addInt ('airpressuretrend') 1316 if 'horizvis' in fields: c.addDecimal('horizvis',3,1) 1317 if 'waterlevel' in fields: c.addDecimal('waterlevel',3,1) 1318 if 'waterleveltrend' in fields: c.addInt ('waterleveltrend') 1319 if 'surfcurspeed' in fields: c.addDecimal('surfcurspeed',3,1) 1320 if 'surfcurdir' in fields: c.addInt ('surfcurdir') 1321 if 'curspeed2' in fields: c.addDecimal('curspeed2',3,1) 1322 if 'curdir2' in fields: c.addInt ('curdir2') 1323 if 'curlevel2' in fields: c.addInt ('curlevel2') 1324 if 'curspeed3' in fields: c.addDecimal('curspeed3',3,1) 1325 if 'curdir3' in fields: c.addInt ('curdir3') 1326 if 'curlevel3' in fields: c.addInt ('curlevel3') 1327 if 'sigwaveheight' in fields: c.addDecimal('sigwaveheight',3,1) 1328 if 'waveperiod' in fields: c.addInt ('waveperiod') 1329 if 'wavedir' in fields: c.addInt ('wavedir') 1330 if 'swellheight' in fields: c.addDecimal('swellheight',3,1) 1331 if 'swellperiod' in fields: c.addInt ('swellperiod') 1332 if 'swelldir' in fields: c.addInt ('swelldir') 1333 if 'seastate' in fields: c.addInt ('seastate') 1334 if 'watertemp' in fields: c.addDecimal('watertemp',4,1) 1335 if 'preciptype' in fields: c.addInt ('preciptype') 1336 if 'salinity' in fields: c.addDecimal('salinity',3,1) 1337 if 'ice' in fields: c.addInt ('ice') 1338 if 'Spare' in fields: c.addInt ('Spare') 1339 1340 if addCoastGuardFields: 1341 # c.addInt('cg_rssi') # Relative signal strength indicator 1342 # c.addInt('cg_d') # dBm receive strength 1343 # c.addInt('cg_T') # Receive timestamp from the AIS equipment 1344 # c.addInt('cg_S') # Slot received in 1345 # c.addVarChar('cg_x',10) # Idonno 1346 c.addVarChar('cg_r',15) # Receiver station ID - should usually be an MMSI, but sometimes is a string 1347 c.addInt('cg_sec') # UTC seconds since the epoch 1348 1349 c.addTimestamp('cg_timestamp') # UTC decoded cg_sec - not actually in the data stream 1350 1351 if dbType == 'postgres': 1352 #--- EPSG 4326 : WGS 84 1353 #INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs '); 1354 c.addPostGIS('Position','POINT',2,SRID=4326); 1355 1356 return c
1357
1358 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
1359 ''' 1360 Return the SQL INSERT command for this message type 1361 @param params: dictionary of values keyed by field name 1362 @param outfile: file like object to print to. 1363 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 1364 @return: sql create string 1365 @rtype: str 1366 1367 @see: sqlCreate 1368 ''' 1369 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
1370 1371
1372 -def sqlInsert(params,extraParams=None,dbType='postgres'):
1373 ''' 1374 Give the SQL INSERT statement 1375 @param params: dict keyed by field name of values 1376 @param extraParams: any extra fields that you have created beyond the normal ais message fields 1377 @rtype: sqlhelp.insert 1378 @return: insert class instance 1379 @todo: allow optional type checking of params? 1380 @warning: this will take invalid keys happily and do what??? 1381 ''' 1382 import sqlhelp 1383 i = sqlhelp.insert('imo_met_hydro',dbType=dbType) 1384 1385 if dbType=='postgres': 1386 finished = [] 1387 for key in params: 1388 if key in finished: 1389 continue 1390 1391 if key not in toPgFields and key not in fromPgFields: 1392 if type(params[key])==Decimal: i.add(key,float(params[key])) 1393 else: i.add(key,params[key]) 1394 else: 1395 if key in fromPgFields: 1396 val = params[key] 1397 # Had better be a WKT type like POINT(-88.1 30.321) 1398 i.addPostGIS(key,val) 1399 finished.append(key) 1400 else: 1401 # Need to construct the type. 1402 pgName = toPgFields[key] 1403 #valStr='GeomFromText(\''+pgTypes[pgName]+'(' 1404 valStr=pgTypes[pgName]+'(' 1405 vals = [] 1406 for nonPgKey in fromPgFields[pgName]: 1407 vals.append(str(params[nonPgKey])) 1408 finished.append(nonPgKey) 1409 valStr+=' '.join(vals)+')' 1410 i.addPostGIS(pgName,valStr) 1411 else: 1412 for key in params: 1413 if type(params[key])==Decimal: i.add(key,float(params[key])) 1414 else: i.add(key,params[key]) 1415 1416 if None != extraParams: 1417 for key in extraParams: 1418 i.add(key,extraParams[key]) 1419 1420 return i
1421 1422 ###################################################################### 1423 # LATEX SUPPORT 1424 ###################################################################### 1425
1426 -def latexDefinitionTable(outfile=sys.stdout 1427 ):
1428 ''' 1429 Return the LaTeX definition table for this message type 1430 @param outfile: file like object to print to. 1431 @type outfile: file obj 1432 @return: LaTeX table string via the outfile 1433 @rtype: str 1434 1435 ''' 1436 o = outfile 1437 1438 o.write(''' 1439 \\begin{table}%[htb] 1440 \\centering 1441 \\begin{tabular}{|l|c|l|} 1442 \\hline 1443 Parameter & Number of bits & Description 1444 \\\\ \\hline\\hline 1445 MessageID & 6 & AIS message number. Must be 8 \\\\ \hline 1446 RepeatIndicator & 2 & Indicated how many times a message has been repeated \\\\ \hline 1447 UserID & 30 & MMSI number of transmitter broadcasting the message \\\\ \hline 1448 Spare & 2 & Reserved for definition by a regional authority. \\\\ \hline 1449 dac & 10 & Designated Area Code - part 1 of the IAI \\\\ \hline 1450 fid & 6 & Functional Identifier - part 2 of the IAI \\\\ \hline 1451 latitude & 24 & Location of the vessel. North South location \\\\ \hline 1452 longitude & 25 & Location of the vessel. East West location \\\\ \hline 1453 day & 5 & Day 0..31 \\\\ \hline 1454 hour & 5 & Hour 0..23 \\\\ \hline 1455 min & 6 & Min \\\\ \hline 1456 avewind & 7 & Average wind speed values for the last 10 minutes. \\\\ \hline 1457 windgust & 7 & Wind gust is the max wind speed value reading during the last 10 minutes. \\\\ \hline 1458 winddir & 9 & Wind direction \\\\ \hline 1459 windgustdir & 9 & Wind direction for the gust. \\\\ \hline 1460 airtemp & 11 & Dry bulb temperature \\\\ \hline 1461 relhumid & 7 & Relative humidity \\\\ \hline 1462 dewpoint & 10 & Dew Point \\\\ \hline 1463 airpressure & 9 & Air pressure \\\\ \hline 1464 airpressuretrend & 2 & Air pressure trend \\\\ \hline 1465 horizvis & 8 & Horizontal visibility \\\\ \hline 1466 waterlevel & 9 & Water level (incl. tide) \\\\ \hline 1467 waterleveltrend & 2 & Water level trend \\\\ \hline 1468 surfcurspeed & 8 & Surface current speed \\\\ \hline 1469 surfcurdir & 9 & Surface current direction \\\\ \hline 1470 curspeed2 & 8 & Level 2 current speed \\\\ \hline 1471 curdir2 & 9 & Level 2 current direction \\\\ \hline 1472 curlevel2 & 5 & Measuring level below sea surface for level 2 \\\\ \hline 1473 curspeed3 & 8 & Level 3 current speed \\\\ \hline 1474 curdir3 & 9 & Level 3 current direction \\\\ \hline 1475 curlevel3 & 5 & Measuring level below sea surface for level 3 \\\\ \hline 1476 sigwaveheight & 8 & Significant wave height \\\\ \hline 1477 waveperiod & 6 & Wave period \\\\ \hline 1478 wavedir & 9 & Wave direction \\\\ \hline 1479 swellheight & 8 & Swell height \\\\ \hline 1480 swellperiod & 6 & Swell period \\\\ \hline 1481 swelldir & 9 & Swell direction \\\\ \hline 1482 seastate & 4 & Sea state according to the Beaufort scale \\\\ \hline 1483 watertemp & 10 & Water temperature \\\\ \hline 1484 preciptype & 3 & According to WMO \\\\ \hline 1485 salinity & 9 & Salinity \\\\ \hline 1486 ice & 2 & Yes or no for the presence of ice \\\\ \hline 1487 Spare & 6 & Must be zero\\\\ \\hline \\hline 1488 Total bits & 352 & Appears to take 2 slots with 72 pad bits to fill the last slot \\\\ \\hline 1489 \\end{tabular} 1490 \\caption{AIS message number 8: IMO meteorological and hydroglogical data. Specified in SN\\Circ.236 Annex 2. Also defined in IALA Guidelines on AIS, Vol 1, Part 1, Ed. 1.3. Guildeline No 1028. } 1491 \\label{tab:imo_met_hydro} 1492 \\end{table} 1493 ''')
1494 1495 ###################################################################### 1496 # Text Definition 1497 ###################################################################### 1498
1499 -def textDefinitionTable(outfile=sys.stdout 1500 ,delim='\t' 1501 ):
1502 ''' 1503 Return the text definition table for this message type 1504 @param outfile: file like object to print to. 1505 @type outfile: file obj 1506 @return: text table string via the outfile 1507 @rtype: str 1508 1509 ''' 1510 o = outfile 1511 o.write('''Parameter'''+delim+'Number of bits'''+delim+'''Description 1512 MessageID'''+delim+'''6'''+delim+'''AIS message number. Must be 8 1513 RepeatIndicator'''+delim+'''2'''+delim+'''Indicated how many times a message has been repeated 1514 UserID'''+delim+'''30'''+delim+'''MMSI number of transmitter broadcasting the message 1515 Spare'''+delim+'''2'''+delim+'''Reserved for definition by a regional authority. 1516 dac'''+delim+'''10'''+delim+'''Designated Area Code - part 1 of the IAI 1517 fid'''+delim+'''6'''+delim+'''Functional Identifier - part 2 of the IAI 1518 latitude'''+delim+'''24'''+delim+'''Location of the vessel. North South location 1519 longitude'''+delim+'''25'''+delim+'''Location of the vessel. East West location 1520 day'''+delim+'''5'''+delim+'''Day 0..31 1521 hour'''+delim+'''5'''+delim+'''Hour 0..23 1522 min'''+delim+'''6'''+delim+'''Min 1523 avewind'''+delim+'''7'''+delim+'''Average wind speed values for the last 10 minutes. 1524 windgust'''+delim+'''7'''+delim+'''Wind gust is the max wind speed value reading during the last 10 minutes. 1525 winddir'''+delim+'''9'''+delim+'''Wind direction 1526 windgustdir'''+delim+'''9'''+delim+'''Wind direction for the gust. 1527 airtemp'''+delim+'''11'''+delim+'''Dry bulb temperature 1528 relhumid'''+delim+'''7'''+delim+'''Relative humidity 1529 dewpoint'''+delim+'''10'''+delim+'''Dew Point 1530 airpressure'''+delim+'''9'''+delim+'''Air pressure 1531 airpressuretrend'''+delim+'''2'''+delim+'''Air pressure trend 1532 horizvis'''+delim+'''8'''+delim+'''Horizontal visibility 1533 waterlevel'''+delim+'''9'''+delim+'''Water level (incl. tide) 1534 waterleveltrend'''+delim+'''2'''+delim+'''Water level trend 1535 surfcurspeed'''+delim+'''8'''+delim+'''Surface current speed 1536 surfcurdir'''+delim+'''9'''+delim+'''Surface current direction 1537 curspeed2'''+delim+'''8'''+delim+'''Level 2 current speed 1538 curdir2'''+delim+'''9'''+delim+'''Level 2 current direction 1539 curlevel2'''+delim+'''5'''+delim+'''Measuring level below sea surface for level 2 1540 curspeed3'''+delim+'''8'''+delim+'''Level 3 current speed 1541 curdir3'''+delim+'''9'''+delim+'''Level 3 current direction 1542 curlevel3'''+delim+'''5'''+delim+'''Measuring level below sea surface for level 3 1543 sigwaveheight'''+delim+'''8'''+delim+'''Significant wave height 1544 waveperiod'''+delim+'''6'''+delim+'''Wave period 1545 wavedir'''+delim+'''9'''+delim+'''Wave direction 1546 swellheight'''+delim+'''8'''+delim+'''Swell height 1547 swellperiod'''+delim+'''6'''+delim+'''Swell period 1548 swelldir'''+delim+'''9'''+delim+'''Swell direction 1549 seastate'''+delim+'''4'''+delim+'''Sea state according to the Beaufort scale 1550 watertemp'''+delim+'''10'''+delim+'''Water temperature 1551 preciptype'''+delim+'''3'''+delim+'''According to WMO 1552 salinity'''+delim+'''9'''+delim+'''Salinity 1553 ice'''+delim+'''2'''+delim+'''Yes or no for the presence of ice 1554 Spare'''+delim+'''6'''+delim+'''Must be zero 1555 Total bits'''+delim+'''352'''+delim+'''Appears to take 2 slots with 72 pad bits to fill the last slot''')
1556 1557 1558 ###################################################################### 1559 # UNIT TESTING 1560 ###################################################################### 1561 import unittest
1562 -def testParams():
1563 '''Return a params file base on the testvalue tags. 1564 @rtype: dict 1565 @return: params based on testvalue tags 1566 ''' 1567 params = {} 1568 params['MessageID'] = 8 1569 params['RepeatIndicator'] = 1 1570 params['UserID'] = 1193046 1571 params['Spare'] = 0 1572 params['dac'] = 1 1573 params['fid'] = 11 1574 params['latitude'] = Decimal('37.42446') 1575 params['longitude'] = Decimal('-122.16328') 1576 params['day'] = 3 1577 params['hour'] = 21 1578 params['min'] = 58 1579 params['avewind'] = 23 1580 params['windgust'] = 35 1581 params['winddir'] = 329 1582 params['windgustdir'] = 293 1583 params['airtemp'] = Decimal('-40.1') 1584 params['relhumid'] = 99 1585 params['dewpoint'] = Decimal('-19.2') 1586 params['airpressure'] = Decimal('1150') 1587 params['airpressuretrend'] = 2 1588 params['horizvis'] = Decimal('11.9') 1589 params['waterlevel'] = Decimal('-8.9') 1590 params['waterleveltrend'] = 0 1591 params['surfcurspeed'] = Decimal('22.3') 1592 params['surfcurdir'] = 321 1593 params['curspeed2'] = Decimal('12.7') 1594 params['curdir2'] = 122 1595 params['curlevel2'] = 29 1596 params['curspeed3'] = Decimal('19.2') 1597 params['curdir3'] = 93 1598 params['curlevel3'] = 28 1599 params['sigwaveheight'] = Decimal('22.8') 1600 params['waveperiod'] = 2 1601 params['wavedir'] = 187 1602 params['swellheight'] = Decimal('0.2') 1603 params['swellperiod'] = 59 1604 params['swelldir'] = 1 1605 params['seastate'] = 12 1606 params['watertemp'] = Decimal('48.8') 1607 params['preciptype'] = 2 1608 params['salinity'] = Decimal('0.9') 1609 params['ice'] = 1 1610 params['Spare'] = 0 1611 1612 return params
1613
1614 -class Testimo_met_hydro(unittest.TestCase):
1615 '''Use testvalue tag text from each type to build test case the imo_met_hydro message'''
1616 - def testEncodeDecode(self):
1617 1618 params = testParams() 1619 bits = encode(params) 1620 r = decode(bits) 1621 1622 # Check that each parameter came through ok. 1623 self.failUnlessEqual(r['MessageID'],params['MessageID']) 1624 self.failUnlessEqual(r['RepeatIndicator'],params['RepeatIndicator']) 1625 self.failUnlessEqual(r['UserID'],params['UserID']) 1626 self.failUnlessEqual(r['Spare'],params['Spare']) 1627 self.failUnlessEqual(r['dac'],params['dac']) 1628 self.failUnlessEqual(r['fid'],params['fid']) 1629 self.failUnlessAlmostEqual(r['latitude'],params['latitude'],4) 1630 self.failUnlessAlmostEqual(r['longitude'],params['longitude'],4) 1631 self.failUnlessEqual(r['day'],params['day']) 1632 self.failUnlessEqual(r['hour'],params['hour']) 1633 self.failUnlessEqual(r['min'],params['min']) 1634 self.failUnlessEqual(r['avewind'],params['avewind']) 1635 self.failUnlessEqual(r['windgust'],params['windgust']) 1636 self.failUnlessEqual(r['winddir'],params['winddir']) 1637 self.failUnlessEqual(r['windgustdir'],params['windgustdir']) 1638 self.failUnlessAlmostEqual(r['airtemp'],params['airtemp'],1) 1639 self.failUnlessEqual(r['relhumid'],params['relhumid']) 1640 self.failUnlessAlmostEqual(r['dewpoint'],params['dewpoint'],1) 1641 self.failUnlessAlmostEqual(r['airpressure'],params['airpressure'],0) 1642 self.failUnlessEqual(r['airpressuretrend'],params['airpressuretrend']) 1643 self.failUnlessAlmostEqual(r['horizvis'],params['horizvis'],1) 1644 self.failUnlessAlmostEqual(r['waterlevel'],params['waterlevel'],1) 1645 self.failUnlessEqual(r['waterleveltrend'],params['waterleveltrend']) 1646 self.failUnlessAlmostEqual(r['surfcurspeed'],params['surfcurspeed'],1) 1647 self.failUnlessEqual(r['surfcurdir'],params['surfcurdir']) 1648 self.failUnlessAlmostEqual(r['curspeed2'],params['curspeed2'],1) 1649 self.failUnlessEqual(r['curdir2'],params['curdir2']) 1650 self.failUnlessEqual(r['curlevel2'],params['curlevel2']) 1651 self.failUnlessAlmostEqual(r['curspeed3'],params['curspeed3'],1) 1652 self.failUnlessEqual(r['curdir3'],params['curdir3']) 1653 self.failUnlessEqual(r['curlevel3'],params['curlevel3']) 1654 self.failUnlessAlmostEqual(r['sigwaveheight'],params['sigwaveheight'],1) 1655 self.failUnlessEqual(r['waveperiod'],params['waveperiod']) 1656 self.failUnlessEqual(r['wavedir'],params['wavedir']) 1657 self.failUnlessAlmostEqual(r['swellheight'],params['swellheight'],1) 1658 self.failUnlessEqual(r['swellperiod'],params['swellperiod']) 1659 self.failUnlessEqual(r['swelldir'],params['swelldir']) 1660 self.failUnlessEqual(r['seastate'],params['seastate']) 1661 self.failUnlessAlmostEqual(r['watertemp'],params['watertemp'],1) 1662 self.failUnlessEqual(r['preciptype'],params['preciptype']) 1663 self.failUnlessAlmostEqual(r['salinity'],params['salinity'],1) 1664 self.failUnlessEqual(r['ice'],params['ice']) 1665 self.failUnlessEqual(r['Spare'],params['Spare'])
1666
1667 -def addMsgOptions(parser):
1668 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 1669 help='decode a "imo_met_hydro" AIS message') 1670 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 1671 help='encode a "imo_met_hydro" AIS message') 1672 parser.add_option('--RepeatIndicator-field', dest='RepeatIndicatorField',default=0,metavar='uint',type='int' 1673 ,help='Field parameter value [default: %default]') 1674 parser.add_option('--UserID-field', dest='UserIDField',metavar='uint',type='int' 1675 ,help='Field parameter value [default: %default]') 1676 parser.add_option('--latitude-field', dest='latitudeField',default=Decimal('91'),metavar='decimal',type='string' 1677 ,help='Field parameter value [default: %default]') 1678 parser.add_option('--longitude-field', dest='longitudeField',default=Decimal('181'),metavar='decimal',type='string' 1679 ,help='Field parameter value [default: %default]') 1680 parser.add_option('--day-field', dest='dayField',metavar='uint',type='int' 1681 ,help='Field parameter value [default: %default]') 1682 parser.add_option('--hour-field', dest='hourField',default=31,metavar='uint',type='int' 1683 ,help='Field parameter value [default: %default]') 1684 parser.add_option('--min-field', dest='minField',default=63,metavar='uint',type='int' 1685 ,help='Field parameter value [default: %default]') 1686 parser.add_option('--avewind-field', dest='avewindField',default=127,metavar='uint',type='int' 1687 ,help='Field parameter value [default: %default]') 1688 parser.add_option('--windgust-field', dest='windgustField',default=127,metavar='uint',type='int' 1689 ,help='Field parameter value [default: %default]') 1690 parser.add_option('--winddir-field', dest='winddirField',default=511,metavar='uint',type='int' 1691 ,help='Field parameter value [default: %default]') 1692 parser.add_option('--windgustdir-field', dest='windgustdirField',default=511,metavar='uint',type='int' 1693 ,help='Field parameter value [default: %default]') 1694 parser.add_option('--airtemp-field', dest='airtempField',default=Decimal('102.3'),metavar='decimal',type='string' 1695 ,help='Field parameter value [default: %default]') 1696 parser.add_option('--relhumid-field', dest='relhumidField',default=127,metavar='uint',type='int' 1697 ,help='Field parameter value [default: %default]') 1698 parser.add_option('--dewpoint-field', dest='dewpointField',default=Decimal('51.1'),metavar='decimal',type='string' 1699 ,help='Field parameter value [default: %default]') 1700 parser.add_option('--airpressure-field', dest='airpressureField',default=Decimal('1311'),metavar='udecimal',type='string' 1701 ,help='Field parameter value [default: %default]') 1702 parser.add_option('--airpressuretrend-field', dest='airpressuretrendField',default=3,metavar='uint',type='int' 1703 ,help='Field parameter value [default: %default]') 1704 parser.add_option('--horizvis-field', dest='horizvisField',default=Decimal('25.5'),metavar='udecimal',type='string' 1705 ,help='Field parameter value [default: %default]') 1706 parser.add_option('--waterlevel-field', dest='waterlevelField',metavar='decimal',type='string' 1707 ,help='Field parameter value [default: %default]') 1708 parser.add_option('--waterleveltrend-field', dest='waterleveltrendField',default=3,metavar='uint',type='int' 1709 ,help='Field parameter value [default: %default]') 1710 parser.add_option('--surfcurspeed-field', dest='surfcurspeedField',default=Decimal('25.5'),metavar='udecimal',type='string' 1711 ,help='Field parameter value [default: %default]') 1712 parser.add_option('--surfcurdir-field', dest='surfcurdirField',default=511,metavar='uint',type='int' 1713 ,help='Field parameter value [default: %default]') 1714 parser.add_option('--curspeed2-field', dest='curspeed2Field',default=Decimal('25.5'),metavar='udecimal',type='string' 1715 ,help='Field parameter value [default: %default]') 1716 parser.add_option('--curdir2-field', dest='curdir2Field',default=511,metavar='uint',type='int' 1717 ,help='Field parameter value [default: %default]') 1718 parser.add_option('--curlevel2-field', dest='curlevel2Field',default=31,metavar='uint',type='int' 1719 ,help='Field parameter value [default: %default]') 1720 parser.add_option('--curspeed3-field', dest='curspeed3Field',default=Decimal('25.5'),metavar='udecimal',type='string' 1721 ,help='Field parameter value [default: %default]') 1722 parser.add_option('--curdir3-field', dest='curdir3Field',default=511,metavar='uint',type='int' 1723 ,help='Field parameter value [default: %default]') 1724 parser.add_option('--curlevel3-field', dest='curlevel3Field',default=31,metavar='uint',type='int' 1725 ,help='Field parameter value [default: %default]') 1726 parser.add_option('--sigwaveheight-field', dest='sigwaveheightField',default=Decimal('25.5'),metavar='udecimal',type='string' 1727 ,help='Field parameter value [default: %default]') 1728 parser.add_option('--waveperiod-field', dest='waveperiodField',default=63,metavar='uint',type='int' 1729 ,help='Field parameter value [default: %default]') 1730 parser.add_option('--wavedir-field', dest='wavedirField',default=511,metavar='uint',type='int' 1731 ,help='Field parameter value [default: %default]') 1732 parser.add_option('--swellheight-field', dest='swellheightField',default=Decimal('25.5'),metavar='udecimal',type='string' 1733 ,help='Field parameter value [default: %default]') 1734 parser.add_option('--swellperiod-field', dest='swellperiodField',default=63,metavar='uint',type='int' 1735 ,help='Field parameter value [default: %default]') 1736 parser.add_option('--swelldir-field', dest='swelldirField',default=511,metavar='uint',type='int' 1737 ,help='Field parameter value [default: %default]') 1738 parser.add_option('--seastate-field', dest='seastateField',default=15,metavar='uint',type='int' 1739 ,help='Field parameter value [default: %default]') 1740 parser.add_option('--watertemp-field', dest='watertempField',default=Decimal('92.3'),metavar='udecimal',type='string' 1741 ,help='Field parameter value [default: %default]') 1742 parser.add_option('--preciptype-field', dest='preciptypeField',default=7,metavar='uint',type='int' 1743 ,help='Field parameter value [default: %default]') 1744 parser.add_option('--salinity-field', dest='salinityField',default=Decimal('92.3'),metavar='decimal',type='string' 1745 ,help='Field parameter value [default: %default]') 1746 parser.add_option('--ice-field', dest='iceField',metavar='uint',type='int' 1747 ,help='Field parameter value [default: %default]')
1748 1749 ############################################################ 1750 if __name__=='__main__': 1751 1752 from optparse import OptionParser 1753 parser = OptionParser(usage="%prog [options]", 1754 version="%prog "+__version__) 1755 1756 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 1757 help='run the documentation tests') 1758 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 1759 help='run the unit tests') 1760 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 1761 help='Make the test output verbose') 1762 1763 # FIX: remove nmea from binary messages. No way to build the whole packet? 1764 # FIX: or build the surrounding msg 8 for a broadcast? 1765 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 1766 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 1767 ,default='nmeapayload' 1768 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 1769 1770 1771 outputChoices = ('std','html','csv','sql' , 'kml','kml-full') 1772 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 1773 ,default='std' 1774 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 1775 1776 parser.add_option('-o','--output',dest='outputFileName',default=None, 1777 help='Name of the python file to write [default: stdout]') 1778 1779 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 1780 choices=fieldList, 1781 help='Which fields to include in the output. Currently only for csv output [default: all]') 1782 1783 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 1784 help='Print the field name for csv') 1785 1786 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 1787 help='Print out an sql create command for the table.') 1788 1789 parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true', 1790 help='Print a LaTeX table of the type') 1791 1792 parser.add_option('--text-table',dest='textDefinitionTable',default=False,action='store_true', 1793 help='Print delimited table of the type (for Word table importing)') 1794 parser.add_option('--delimt-text-table',dest='delimTextDefinitionTable',default='\t' 1795 ,help='Delimiter for text table [default: \'%default\'](for Word table importing)') 1796 1797 1798 dbChoices = ('sqlite','postgres') 1799 parser.add_option('-D','--db-type',dest='dbType',default='postgres' 1800 ,choices=dbChoices,type='choice' 1801 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 1802 1803 addMsgOptions(parser) 1804 1805 (options,args) = parser.parse_args() 1806 success=True 1807 1808 if options.doctest: 1809 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 1810 sys.argv= [sys.argv[0]] 1811 if options.verbose: sys.argv.append('-v') 1812 import doctest 1813 numfail,numtests=doctest.testmod() 1814 if numfail==0: print 'ok' 1815 else: 1816 print 'FAILED' 1817 success=False 1818 1819 if not success: sys.exit('Something Failed') 1820 del success # Hide success from epydoc 1821 1822 if options.unittest: 1823 sys.argv = [sys.argv[0]] 1824 if options.verbose: sys.argv.append('-v') 1825 unittest.main() 1826 1827 outfile = sys.stdout 1828 if None!=options.outputFileName: 1829 outfile = file(options.outputFileName,'w') 1830 1831 1832 if options.doEncode: 1833 # First make sure all non required options are specified 1834 if None==options.RepeatIndicatorField: parser.error("missing value for RepeatIndicatorField") 1835 if None==options.UserIDField: parser.error("missing value for UserIDField") 1836 if None==options.latitudeField: parser.error("missing value for latitudeField") 1837 if None==options.longitudeField: parser.error("missing value for longitudeField") 1838 if None==options.dayField: parser.error("missing value for dayField") 1839 if None==options.hourField: parser.error("missing value for hourField") 1840 if None==options.minField: parser.error("missing value for minField") 1841 if None==options.avewindField: parser.error("missing value for avewindField") 1842 if None==options.windgustField: parser.error("missing value for windgustField") 1843 if None==options.winddirField: parser.error("missing value for winddirField") 1844 if None==options.windgustdirField: parser.error("missing value for windgustdirField") 1845 if None==options.airtempField: parser.error("missing value for airtempField") 1846 if None==options.relhumidField: parser.error("missing value for relhumidField") 1847 if None==options.dewpointField: parser.error("missing value for dewpointField") 1848 if None==options.airpressureField: parser.error("missing value for airpressureField") 1849 if None==options.airpressuretrendField: parser.error("missing value for airpressuretrendField") 1850 if None==options.horizvisField: parser.error("missing value for horizvisField") 1851 if None==options.waterlevelField: parser.error("missing value for waterlevelField") 1852 if None==options.waterleveltrendField: parser.error("missing value for waterleveltrendField") 1853 if None==options.surfcurspeedField: parser.error("missing value for surfcurspeedField") 1854 if None==options.surfcurdirField: parser.error("missing value for surfcurdirField") 1855 if None==options.curspeed2Field: parser.error("missing value for curspeed2Field") 1856 if None==options.curdir2Field: parser.error("missing value for curdir2Field") 1857 if None==options.curlevel2Field: parser.error("missing value for curlevel2Field") 1858 if None==options.curspeed3Field: parser.error("missing value for curspeed3Field") 1859 if None==options.curdir3Field: parser.error("missing value for curdir3Field") 1860 if None==options.curlevel3Field: parser.error("missing value for curlevel3Field") 1861 if None==options.sigwaveheightField: parser.error("missing value for sigwaveheightField") 1862 if None==options.waveperiodField: parser.error("missing value for waveperiodField") 1863 if None==options.wavedirField: parser.error("missing value for wavedirField") 1864 if None==options.swellheightField: parser.error("missing value for swellheightField") 1865 if None==options.swellperiodField: parser.error("missing value for swellperiodField") 1866 if None==options.swelldirField: parser.error("missing value for swelldirField") 1867 if None==options.seastateField: parser.error("missing value for seastateField") 1868 if None==options.watertempField: parser.error("missing value for watertempField") 1869 if None==options.preciptypeField: parser.error("missing value for preciptypeField") 1870 if None==options.salinityField: parser.error("missing value for salinityField") 1871 if None==options.iceField: parser.error("missing value for iceField") 1872 msgDict={ 1873 'MessageID': '8', 1874 'RepeatIndicator': options.RepeatIndicatorField, 1875 'UserID': options.UserIDField, 1876 'Spare': '0', 1877 'dac': '1', 1878 'fid': '11', 1879 'latitude': options.latitudeField, 1880 'longitude': options.longitudeField, 1881 'day': options.dayField, 1882 'hour': options.hourField, 1883 'min': options.minField, 1884 'avewind': options.avewindField, 1885 'windgust': options.windgustField, 1886 'winddir': options.winddirField, 1887 'windgustdir': options.windgustdirField, 1888 'airtemp': options.airtempField, 1889 'relhumid': options.relhumidField, 1890 'dewpoint': options.dewpointField, 1891 'airpressure': options.airpressureField, 1892 'airpressuretrend': options.airpressuretrendField, 1893 'horizvis': options.horizvisField, 1894 'waterlevel': options.waterlevelField, 1895 'waterleveltrend': options.waterleveltrendField, 1896 'surfcurspeed': options.surfcurspeedField, 1897 'surfcurdir': options.surfcurdirField, 1898 'curspeed2': options.curspeed2Field, 1899 'curdir2': options.curdir2Field, 1900 'curlevel2': options.curlevel2Field, 1901 'curspeed3': options.curspeed3Field, 1902 'curdir3': options.curdir3Field, 1903 'curlevel3': options.curlevel3Field, 1904 'sigwaveheight': options.sigwaveheightField, 1905 'waveperiod': options.waveperiodField, 1906 'wavedir': options.wavedirField, 1907 'swellheight': options.swellheightField, 1908 'swellperiod': options.swellperiodField, 1909 'swelldir': options.swelldirField, 1910 'seastate': options.seastateField, 1911 'watertemp': options.watertempField, 1912 'preciptype': options.preciptypeField, 1913 'salinity': options.salinityField, 1914 'ice': options.iceField, 1915 'Spare': '0', 1916 } 1917 1918 bits = encode(msgDict) 1919 if 'binary'==options.ioType: print str(bits) 1920 elif 'nmeapayload'==options.ioType: 1921 # FIX: figure out if this might be necessary at compile time 1922 print "bitLen",len(bits) 1923 bitLen=len(bits) 1924 if bitLen%6!=0: 1925 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 1926 print "result:",binary.bitvectoais6(bits)[0] 1927 1928 1929 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 1930 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 1931 else: sys.exit('ERROR: unknown ioType. Help!') 1932 1933 1934 if options.sqlCreate: 1935 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 1936 1937 if options.latexDefinitionTable: 1938 latexDefinitionTable(outfile) 1939 1940 # For conversion to word tables 1941 if options.textDefinitionTable: 1942 textDefinitionTable(outfile,options.delimTextDefinitionTable) 1943 1944 if options.printCsvfieldList: 1945 # Make a csv separated list of fields that will be displayed for csv 1946 if None == options.fieldList: options.fieldList = fieldList 1947 import StringIO 1948 buf = StringIO.StringIO() 1949 for field in options.fieldList: 1950 buf.write(field+',') 1951 result = buf.getvalue() 1952 if result[-1] == ',': print result[:-1] 1953 else: print result 1954 1955 if options.doDecode: 1956 if len(args)==0: args = sys.stdin 1957 for msg in args: 1958 bv = None 1959 1960 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 1961 # Found nmea 1962 # FIX: do checksum 1963 bv = binary.ais6tobitvec(msg.split(',')[5]) 1964 else: # either binary or nmeapayload... expect mostly nmeapayloads 1965 # assumes that an all 0 and 1 string can not be a nmeapayload 1966 binaryMsg=True 1967 for c in msg: 1968 if c not in ('0','1'): 1969 binaryMsg=False 1970 break 1971 if binaryMsg: 1972 bv = BitVector(bitstring=msg) 1973 else: # nmeapayload 1974 bv = binary.ais6tobitvec(msg) 1975 1976 printFields(decode(bv) 1977 ,out=outfile 1978 ,format=options.outputType 1979 ,fieldList=options.fieldList 1980 ,dbType=options.dbType 1981 ) 1982