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