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

Source Code for Module ais.waterlevel

   1  #!/usr/bin/env python 
   2   
   3  __version__ = '$Revision: 4791 $'.split()[1] 
   4  __date__ = '$Date: 2007-02-18 $'.split()[1] 
   5  __author__ = 'xmlbinmsg' 
   6   
   7  __doc__=''' 
   8   
   9  Autogenerated python functions to serialize/deserialize binary messages. 
  10   
  11  Generated by: ./aisxmlbinmsg2py.py 
  12   
  13  Need to then wrap these functions with the outer AIS packet and then 
  14  convert the whole binary blob to a NMEA string.  Those functions are 
  15  not currently provided in this file. 
  16   
  17  serialize: python to ais binary 
  18  deserialize: ais binary to python 
  19   
  20  The generated code uses translators.py, binary.py, and aisstring.py 
  21  which should be packaged with the resulting files. 
  22   
  23   
  24  @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3 
  25  @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>} 
  26   
  27  @author: '''+__author__+''' 
  28  @version: ''' + __version__ +''' 
  29  @var __date__: Date of last svn commit 
  30  @undocumented: __version__ __author__ __doc__ parser 
  31  @status: under development 
  32  @license: Generated code has no license 
  33  @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          'dac', 
  51          'fid', 
  52          'efid', 
  53          'timetag_month', 
  54          'timetag_day', 
  55          'timetag_hour', 
  56          'timetag_min', 
  57          'timetag_sec', 
  58          'stationid', 
  59          'stationloc_longitude', 
  60          'stationloc_latitude', 
  61          'waterlevel', 
  62          'datum', 
  63          'sigma', 
  64          'o', 
  65          'levelinferred', 
  66          'flat_tolerance_exceeded', 
  67          'rate_tolerance_exceeded', 
  68          'temp_tolerance_exceeded', 
  69          'expected_height_exceeded', 
  70          'link_down', 
  71          'timeLastMeasured_month', 
  72          'timeLastMeasured_day', 
  73          'timeLastMeasured_hour', 
  74          'timeLastMeasured_min', 
  75          'timeLastMeasured_sec', 
  76  ) 
  77   
  78  fieldListPostgres = ( 
  79          'dac', 
  80          'fid', 
  81          'efid', 
  82          'timetag_month', 
  83          'timetag_day', 
  84          'timetag_hour', 
  85          'timetag_min', 
  86          'timetag_sec', 
  87          'stationid', 
  88          'stationloc_longitude', 
  89          'stationloc_latitude', 
  90          'waterlevel', 
  91          'datum', 
  92          'sigma', 
  93          'o', 
  94          'levelinferred', 
  95          'flat_tolerance_exceeded', 
  96          'rate_tolerance_exceeded', 
  97          'temp_tolerance_exceeded', 
  98          'expected_height_exceeded', 
  99          'link_down', 
 100          'timeLastMeasured_month', 
 101          'timeLastMeasured_day', 
 102          'timeLastMeasured_hour', 
 103          'timeLastMeasured_min', 
 104          'timeLastMeasured_sec', 
 105  ) 
 106   
 107  toPgFields = { 
 108  } 
 109  ''' 
 110  Go to the Postgis field names from the straight field name 
 111  ''' 
 112   
 113  fromPgFields = { 
 114  } 
 115  ''' 
 116  Go from the Postgis field names to the straight field name 
 117  ''' 
 118   
 119  pgTypes = { 
 120  } 
 121  ''' 
 122  Lookup table for each postgis field name to get its type. 
 123  ''' 
 124   
125 -def encode(params, validate=False):
126 '''Create a waterlevel binary message payload to pack into an AIS Msg waterlevel. 127 128 Fields in params: 129 - dac(uint): Designated Area Code (field automatically set to "366") 130 - fid(uint): Functional Identifier (field automatically set to "1") 131 - efid(uint): extended functional identifier (field automatically set to "1") 132 - timetag_month(uint): Time the measurement represents month 1..12 133 - timetag_day(uint): Time the measurement represents day of the month 1..31 134 - timetag_hour(uint): Time the measurement represents UTC hours 0..23 135 - timetag_min(uint): Time the measurement represents minutes 136 - timetag_sec(uint): Time the measurement represents seconds 137 - stationid(aisstr6): Character identifier of the station. Usually a number. 138 - stationloc_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 139 - stationloc_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 140 - waterlevel(int): Water level in centimeters 141 - datum(uint): What reference datum applies to the value 142 - sigma(float): Standard deviation of 1 second samples used to compute the water level height 143 - o(uint): Count of number of samples that fall outside a 3-sigma band about the mean 144 - levelinferred(bool): indicates that the water level value has been inferred 145 - flat_tolerance_exceeded(bool): flat tolerance limit was exceeded. Need better descr 146 - rate_tolerance_exceeded(bool): rate of change tolerance limit was exceeded 147 - temp_tolerance_exceeded(bool): temperature difference tolerance limit was exceeded 148 - expected_height_exceeded(bool): either the maximum or minimum expected water level height limit was exceeded 149 - link_down(bool): Unable to communicate with the tide system. All data invalid 150 - timeLastMeasured_month(uint): Time since last measured value was available month 1..12 151 - timeLastMeasured_day(uint): Time since last measured value was available day of the month 1..31 152 - timeLastMeasured_hour(uint): Time since last measured value was available UTC hours 0..23 153 - timeLastMeasured_min(uint): Time since last measured value was available minutes 154 - timeLastMeasured_sec(uint): Time since last measured value was available seconds 155 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing 156 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 157 @rtype: BitVector 158 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 159 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits. 160 ''' 161 162 bvList = [] 163 bvList.append(binary.setBitVectorSize(BitVector(intVal=366),16)) 164 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),4)) 165 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),12)) 166 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_month']),4)) 167 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_day']),5)) 168 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_hour']),5)) 169 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_min']),6)) 170 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_sec']),6)) 171 if 'stationid' in params: 172 bvList.append(aisstring.encode(params['stationid'],42)) 173 else: 174 bvList.append(aisstring.encode('@@@@@@@',42)) 175 if 'stationloc_longitude' in params: 176 bvList.append(binary.bvFromSignedInt(int(Decimal(params['stationloc_longitude'])*Decimal('600000')),28)) 177 else: 178 bvList.append(binary.bvFromSignedInt(108600000,28)) 179 if 'stationloc_latitude' in params: 180 bvList.append(binary.bvFromSignedInt(int(Decimal(params['stationloc_latitude'])*Decimal('600000')),27)) 181 else: 182 bvList.append(binary.bvFromSignedInt(54600000,27)) 183 if 'waterlevel' in params: 184 bvList.append(binary.bvFromSignedInt(params['waterlevel'],16)) 185 else: 186 bvList.append(binary.bvFromSignedInt(-32768,16)) 187 if 'datum' in params: 188 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['datum']),5)) 189 else: 190 bvList.append(binary.setBitVectorSize(BitVector(intVal=31),5)) 191 bvList.append(binary.float2bitvec(params['sigma'])) 192 if 'o' in params: 193 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['o']),8)) 194 else: 195 bvList.append(binary.setBitVectorSize(BitVector(intVal=255),8)) 196 if params["levelinferred"]: bvList.append(TrueBV) 197 else: bvList.append(FalseBV) 198 if params["flat_tolerance_exceeded"]: bvList.append(TrueBV) 199 else: bvList.append(FalseBV) 200 if params["rate_tolerance_exceeded"]: bvList.append(TrueBV) 201 else: bvList.append(FalseBV) 202 if params["temp_tolerance_exceeded"]: bvList.append(TrueBV) 203 else: bvList.append(FalseBV) 204 if params["expected_height_exceeded"]: bvList.append(TrueBV) 205 else: bvList.append(FalseBV) 206 if params["link_down"]: bvList.append(TrueBV) 207 else: bvList.append(FalseBV) 208 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_month']),4)) 209 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_day']),5)) 210 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_hour']),5)) 211 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_min']),6)) 212 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_sec']),6)) 213 214 return binary.joinBV(bvList)
215
216 -def decode(bv, validate=False):
217 '''Unpack a waterlevel message 218 219 Fields in params: 220 - dac(uint): Designated Area Code (field automatically set to "366") 221 - fid(uint): Functional Identifier (field automatically set to "1") 222 - efid(uint): extended functional identifier (field automatically set to "1") 223 - timetag_month(uint): Time the measurement represents month 1..12 224 - timetag_day(uint): Time the measurement represents day of the month 1..31 225 - timetag_hour(uint): Time the measurement represents UTC hours 0..23 226 - timetag_min(uint): Time the measurement represents minutes 227 - timetag_sec(uint): Time the measurement represents seconds 228 - stationid(aisstr6): Character identifier of the station. Usually a number. 229 - stationloc_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 230 - stationloc_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 231 - waterlevel(int): Water level in centimeters 232 - datum(uint): What reference datum applies to the value 233 - sigma(float): Standard deviation of 1 second samples used to compute the water level height 234 - o(uint): Count of number of samples that fall outside a 3-sigma band about the mean 235 - levelinferred(bool): indicates that the water level value has been inferred 236 - flat_tolerance_exceeded(bool): flat tolerance limit was exceeded. Need better descr 237 - rate_tolerance_exceeded(bool): rate of change tolerance limit was exceeded 238 - temp_tolerance_exceeded(bool): temperature difference tolerance limit was exceeded 239 - expected_height_exceeded(bool): either the maximum or minimum expected water level height limit was exceeded 240 - link_down(bool): Unable to communicate with the tide system. All data invalid 241 - timeLastMeasured_month(uint): Time since last measured value was available month 1..12 242 - timeLastMeasured_day(uint): Time since last measured value was available day of the month 1..31 243 - timeLastMeasured_hour(uint): Time since last measured value was available UTC hours 0..23 244 - timeLastMeasured_min(uint): Time since last measured value was available minutes 245 - timeLastMeasured_sec(uint): Time since last measured value was available seconds 246 @type bv: BitVector 247 @param bv: Bits defining a message 248 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 249 @rtype: dict 250 @return: params 251 ''' 252 253 #Would be nice to check the bit count here.. 254 #if validate: 255 # assert (len(bv)==FIX: SOME NUMBER) 256 r = {} 257 r['dac']=366 258 r['fid']=1 259 r['efid']=1 260 r['timetag_month']=int(bv[32:36]) 261 r['timetag_day']=int(bv[36:41]) 262 r['timetag_hour']=int(bv[41:46]) 263 r['timetag_min']=int(bv[46:52]) 264 r['timetag_sec']=int(bv[52:58]) 265 r['stationid']=aisstring.decode(bv[58:100]) 266 r['stationloc_longitude']=Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000') 267 r['stationloc_latitude']=Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000') 268 r['waterlevel']=binary.signedIntFromBV(bv[155:171]) 269 r['datum']=int(bv[171:176]) 270 r['sigma']=binary.bitvec2float(bv[176:208]) 271 r['o']=int(bv[208:216]) 272 r['levelinferred']=bool(int(bv[216:217])) 273 r['flat_tolerance_exceeded']=bool(int(bv[217:218])) 274 r['rate_tolerance_exceeded']=bool(int(bv[218:219])) 275 r['temp_tolerance_exceeded']=bool(int(bv[219:220])) 276 r['expected_height_exceeded']=bool(int(bv[220:221])) 277 r['link_down']=bool(int(bv[221:222])) 278 r['timeLastMeasured_month']=int(bv[222:226]) 279 r['timeLastMeasured_day']=int(bv[226:231]) 280 r['timeLastMeasured_hour']=int(bv[231:236]) 281 r['timeLastMeasured_min']=int(bv[236:242]) 282 r['timeLastMeasured_sec']=int(bv[242:248]) 283 return r
284
285 -def decodedac(bv, validate=False):
286 return 366
287
288 -def decodefid(bv, validate=False):
289 return 1
290
291 -def decodeefid(bv, validate=False):
292 return 1
293
294 -def decodetimetag_month(bv, validate=False):
295 return int(bv[32:36])
296
297 -def decodetimetag_day(bv, validate=False):
298 return int(bv[36:41])
299
300 -def decodetimetag_hour(bv, validate=False):
301 return int(bv[41:46])
302
303 -def decodetimetag_min(bv, validate=False):
304 return int(bv[46:52])
305
306 -def decodetimetag_sec(bv, validate=False):
307 return int(bv[52:58])
308
309 -def decodestationid(bv, validate=False):
310 return aisstring.decode(bv[58:100])
311
312 -def decodestationloc_longitude(bv, validate=False):
313 return Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000')
314
315 -def decodestationloc_latitude(bv, validate=False):
316 return Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000')
317
318 -def decodewaterlevel(bv, validate=False):
319 return binary.signedIntFromBV(bv[155:171])
320
321 -def decodedatum(bv, validate=False):
322 return int(bv[171:176])
323
324 -def decodesigma(bv, validate=False):
325 return binary.bitvec2float(bv[176:208])
326
327 -def decodeo(bv, validate=False):
328 return int(bv[208:216])
329
330 -def decodelevelinferred(bv, validate=False):
331 return bool(int(bv[216:217]))
332
333 -def decodeflat_tolerance_exceeded(bv, validate=False):
334 return bool(int(bv[217:218]))
335
336 -def decoderate_tolerance_exceeded(bv, validate=False):
337 return bool(int(bv[218:219]))
338
339 -def decodetemp_tolerance_exceeded(bv, validate=False):
340 return bool(int(bv[219:220]))
341
342 -def decodeexpected_height_exceeded(bv, validate=False):
343 return bool(int(bv[220:221]))
344 347
348 -def decodetimeLastMeasured_month(bv, validate=False):
349 return int(bv[222:226])
350
351 -def decodetimeLastMeasured_day(bv, validate=False):
352 return int(bv[226:231])
353
354 -def decodetimeLastMeasured_hour(bv, validate=False):
355 return int(bv[231:236])
356
357 -def decodetimeLastMeasured_min(bv, validate=False):
358 return int(bv[236:242])
359
360 -def decodetimeLastMeasured_sec(bv, validate=False):
361 return int(bv[242:248])
362 363
364 -def printHtml(params, out=sys.stdout):
365 out.write("<h3>waterlevel<h3>\n") 366 out.write("<table border=\"1\">\n") 367 out.write("<tr bgcolor=\"orange\">\n") 368 out.write("<th align=\"left\">Field Name</th>\n") 369 out.write("<th align=\"left\">Type</th>\n") 370 out.write("<th align=\"left\">Value</th>\n") 371 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 372 out.write("<th align=\"left\">Units</th>\n") 373 out.write("\n") 374 out.write("<tr>\n") 375 out.write("<td>dac</td>\n") 376 out.write("<td>uint</td>\n") 377 if 'dac' in params: 378 out.write(" <td>"+str(params['dac'])+"</td>\n") 379 out.write(" <td>"+str(params['dac'])+"</td>\n") 380 out.write("</tr>\n") 381 out.write("\n") 382 out.write("<tr>\n") 383 out.write("<td>fid</td>\n") 384 out.write("<td>uint</td>\n") 385 if 'fid' in params: 386 out.write(" <td>"+str(params['fid'])+"</td>\n") 387 out.write(" <td>"+str(params['fid'])+"</td>\n") 388 out.write("</tr>\n") 389 out.write("\n") 390 out.write("<tr>\n") 391 out.write("<td>efid</td>\n") 392 out.write("<td>uint</td>\n") 393 if 'efid' in params: 394 out.write(" <td>"+str(params['efid'])+"</td>\n") 395 out.write(" <td>"+str(params['efid'])+"</td>\n") 396 out.write("</tr>\n") 397 out.write("\n") 398 out.write("<tr>\n") 399 out.write("<td>timetag_month</td>\n") 400 out.write("<td>uint</td>\n") 401 if 'timetag_month' in params: 402 out.write(" <td>"+str(params['timetag_month'])+"</td>\n") 403 out.write(" <td>"+str(params['timetag_month'])+"</td>\n") 404 out.write("</tr>\n") 405 out.write("\n") 406 out.write("<tr>\n") 407 out.write("<td>timetag_day</td>\n") 408 out.write("<td>uint</td>\n") 409 if 'timetag_day' in params: 410 out.write(" <td>"+str(params['timetag_day'])+"</td>\n") 411 out.write(" <td>"+str(params['timetag_day'])+"</td>\n") 412 out.write("</tr>\n") 413 out.write("\n") 414 out.write("<tr>\n") 415 out.write("<td>timetag_hour</td>\n") 416 out.write("<td>uint</td>\n") 417 if 'timetag_hour' in params: 418 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n") 419 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n") 420 out.write("</tr>\n") 421 out.write("\n") 422 out.write("<tr>\n") 423 out.write("<td>timetag_min</td>\n") 424 out.write("<td>uint</td>\n") 425 if 'timetag_min' in params: 426 out.write(" <td>"+str(params['timetag_min'])+"</td>\n") 427 out.write(" <td>"+str(params['timetag_min'])+"</td>\n") 428 out.write("</tr>\n") 429 out.write("\n") 430 out.write("<tr>\n") 431 out.write("<td>timetag_sec</td>\n") 432 out.write("<td>uint</td>\n") 433 if 'timetag_sec' in params: 434 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n") 435 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n") 436 out.write("</tr>\n") 437 out.write("\n") 438 out.write("<tr>\n") 439 out.write("<td>stationid</td>\n") 440 out.write("<td>aisstr6</td>\n") 441 if 'stationid' in params: 442 out.write(" <td>"+str(params['stationid'])+"</td>\n") 443 out.write(" <td>"+str(params['stationid'])+"</td>\n") 444 out.write("</tr>\n") 445 out.write("\n") 446 out.write("<tr>\n") 447 out.write("<td>stationloc_longitude</td>\n") 448 out.write("<td>decimal</td>\n") 449 if 'stationloc_longitude' in params: 450 out.write(" <td>"+str(params['stationloc_longitude'])+"</td>\n") 451 out.write(" <td>"+str(params['stationloc_longitude'])+"</td>\n") 452 out.write("<td>degrees</td>\n") 453 out.write("</tr>\n") 454 out.write("\n") 455 out.write("<tr>\n") 456 out.write("<td>stationloc_latitude</td>\n") 457 out.write("<td>decimal</td>\n") 458 if 'stationloc_latitude' in params: 459 out.write(" <td>"+str(params['stationloc_latitude'])+"</td>\n") 460 out.write(" <td>"+str(params['stationloc_latitude'])+"</td>\n") 461 out.write("<td>degrees</td>\n") 462 out.write("</tr>\n") 463 out.write("\n") 464 out.write("<tr>\n") 465 out.write("<td>waterlevel</td>\n") 466 out.write("<td>int</td>\n") 467 if 'waterlevel' in params: 468 out.write(" <td>"+str(params['waterlevel'])+"</td>\n") 469 out.write(" <td>"+str(params['waterlevel'])+"</td>\n") 470 out.write("<td>cm</td>\n") 471 out.write("</tr>\n") 472 out.write("\n") 473 out.write("<tr>\n") 474 out.write("<td>datum</td>\n") 475 out.write("<td>uint</td>\n") 476 if 'datum' in params: 477 out.write(" <td>"+str(params['datum'])+"</td>\n") 478 if str(params['datum']) in datumDecodeLut: 479 out.write("<td>"+datumDecodeLut[str(params['datum'])]+"</td>") 480 else: 481 out.write("<td><i>Missing LUT entry</i></td>") 482 out.write("</tr>\n") 483 out.write("\n") 484 out.write("<tr>\n") 485 out.write("<td>sigma</td>\n") 486 out.write("<td>float</td>\n") 487 if 'sigma' in params: 488 out.write(" <td>"+str(params['sigma'])+"</td>\n") 489 out.write(" <td>"+str(params['sigma'])+"</td>\n") 490 out.write("<td>m</td>\n") 491 out.write("</tr>\n") 492 out.write("\n") 493 out.write("<tr>\n") 494 out.write("<td>o</td>\n") 495 out.write("<td>uint</td>\n") 496 if 'o' in params: 497 out.write(" <td>"+str(params['o'])+"</td>\n") 498 out.write(" <td>"+str(params['o'])+"</td>\n") 499 out.write("</tr>\n") 500 out.write("\n") 501 out.write("<tr>\n") 502 out.write("<td>levelinferred</td>\n") 503 out.write("<td>bool</td>\n") 504 if 'levelinferred' in params: 505 out.write(" <td>"+str(params['levelinferred'])+"</td>\n") 506 out.write(" <td>"+str(params['levelinferred'])+"</td>\n") 507 out.write("</tr>\n") 508 out.write("\n") 509 out.write("<tr>\n") 510 out.write("<td>flat_tolerance_exceeded</td>\n") 511 out.write("<td>bool</td>\n") 512 if 'flat_tolerance_exceeded' in params: 513 out.write(" <td>"+str(params['flat_tolerance_exceeded'])+"</td>\n") 514 out.write(" <td>"+str(params['flat_tolerance_exceeded'])+"</td>\n") 515 out.write("</tr>\n") 516 out.write("\n") 517 out.write("<tr>\n") 518 out.write("<td>rate_tolerance_exceeded</td>\n") 519 out.write("<td>bool</td>\n") 520 if 'rate_tolerance_exceeded' in params: 521 out.write(" <td>"+str(params['rate_tolerance_exceeded'])+"</td>\n") 522 out.write(" <td>"+str(params['rate_tolerance_exceeded'])+"</td>\n") 523 out.write("</tr>\n") 524 out.write("\n") 525 out.write("<tr>\n") 526 out.write("<td>temp_tolerance_exceeded</td>\n") 527 out.write("<td>bool</td>\n") 528 if 'temp_tolerance_exceeded' in params: 529 out.write(" <td>"+str(params['temp_tolerance_exceeded'])+"</td>\n") 530 out.write(" <td>"+str(params['temp_tolerance_exceeded'])+"</td>\n") 531 out.write("</tr>\n") 532 out.write("\n") 533 out.write("<tr>\n") 534 out.write("<td>expected_height_exceeded</td>\n") 535 out.write("<td>bool</td>\n") 536 if 'expected_height_exceeded' in params: 537 out.write(" <td>"+str(params['expected_height_exceeded'])+"</td>\n") 538 out.write(" <td>"+str(params['expected_height_exceeded'])+"</td>\n") 539 out.write("</tr>\n") 540 out.write("\n") 541 out.write("<tr>\n") 542 out.write("<td>link_down</td>\n") 543 out.write("<td>bool</td>\n") 544 if 'link_down' in params: 545 out.write(" <td>"+str(params['link_down'])+"</td>\n") 546 out.write(" <td>"+str(params['link_down'])+"</td>\n") 547 out.write("</tr>\n") 548 out.write("\n") 549 out.write("<tr>\n") 550 out.write("<td>timeLastMeasured_month</td>\n") 551 out.write("<td>uint</td>\n") 552 if 'timeLastMeasured_month' in params: 553 out.write(" <td>"+str(params['timeLastMeasured_month'])+"</td>\n") 554 out.write(" <td>"+str(params['timeLastMeasured_month'])+"</td>\n") 555 out.write("</tr>\n") 556 out.write("\n") 557 out.write("<tr>\n") 558 out.write("<td>timeLastMeasured_day</td>\n") 559 out.write("<td>uint</td>\n") 560 if 'timeLastMeasured_day' in params: 561 out.write(" <td>"+str(params['timeLastMeasured_day'])+"</td>\n") 562 out.write(" <td>"+str(params['timeLastMeasured_day'])+"</td>\n") 563 out.write("</tr>\n") 564 out.write("\n") 565 out.write("<tr>\n") 566 out.write("<td>timeLastMeasured_hour</td>\n") 567 out.write("<td>uint</td>\n") 568 if 'timeLastMeasured_hour' in params: 569 out.write(" <td>"+str(params['timeLastMeasured_hour'])+"</td>\n") 570 out.write(" <td>"+str(params['timeLastMeasured_hour'])+"</td>\n") 571 out.write("</tr>\n") 572 out.write("\n") 573 out.write("<tr>\n") 574 out.write("<td>timeLastMeasured_min</td>\n") 575 out.write("<td>uint</td>\n") 576 if 'timeLastMeasured_min' in params: 577 out.write(" <td>"+str(params['timeLastMeasured_min'])+"</td>\n") 578 out.write(" <td>"+str(params['timeLastMeasured_min'])+"</td>\n") 579 out.write("</tr>\n") 580 out.write("\n") 581 out.write("<tr>\n") 582 out.write("<td>timeLastMeasured_sec</td>\n") 583 out.write("<td>uint</td>\n") 584 if 'timeLastMeasured_sec' in params: 585 out.write(" <td>"+str(params['timeLastMeasured_sec'])+"</td>\n") 586 out.write(" <td>"+str(params['timeLastMeasured_sec'])+"</td>\n") 587 out.write("</tr>\n") 588 out.write("</table>\n")
589 590
591 -def printKml(params, out=sys.stdout):
592 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer''' 593 out.write("\ <Placemark>\n") 594 out.write("\t <name>"+str(params['stationid'])+"</name>\n") 595 out.write("\t\t<description>\n") 596 import StringIO 597 buf = StringIO.StringIO() 598 printHtml(params,buf) 599 import cgi 600 out.write(cgi.escape(buf.getvalue())) 601 out.write("\t\t</description>\n") 602 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n") 603 out.write("\t\t<Point>\n") 604 out.write("\t\t\t<coordinates>") 605 out.write(str(params['stationloc_longitude'])) 606 out.write(',') 607 out.write(str(params['stationloc_latitude'])) 608 out.write(",0</coordinates>\n") 609 out.write("\t\t</Point>\n") 610 out.write("\t</Placemark>\n")
611
612 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'):
613 '''Print a waterlevel message to stdout. 614 615 Fields in params: 616 - dac(uint): Designated Area Code (field automatically set to "366") 617 - fid(uint): Functional Identifier (field automatically set to "1") 618 - efid(uint): extended functional identifier (field automatically set to "1") 619 - timetag_month(uint): Time the measurement represents month 1..12 620 - timetag_day(uint): Time the measurement represents day of the month 1..31 621 - timetag_hour(uint): Time the measurement represents UTC hours 0..23 622 - timetag_min(uint): Time the measurement represents minutes 623 - timetag_sec(uint): Time the measurement represents seconds 624 - stationid(aisstr6): Character identifier of the station. Usually a number. 625 - stationloc_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location 626 - stationloc_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location 627 - waterlevel(int): Water level in centimeters 628 - datum(uint): What reference datum applies to the value 629 - sigma(float): Standard deviation of 1 second samples used to compute the water level height 630 - o(uint): Count of number of samples that fall outside a 3-sigma band about the mean 631 - levelinferred(bool): indicates that the water level value has been inferred 632 - flat_tolerance_exceeded(bool): flat tolerance limit was exceeded. Need better descr 633 - rate_tolerance_exceeded(bool): rate of change tolerance limit was exceeded 634 - temp_tolerance_exceeded(bool): temperature difference tolerance limit was exceeded 635 - expected_height_exceeded(bool): either the maximum or minimum expected water level height limit was exceeded 636 - link_down(bool): Unable to communicate with the tide system. All data invalid 637 - timeLastMeasured_month(uint): Time since last measured value was available month 1..12 638 - timeLastMeasured_day(uint): Time since last measured value was available day of the month 1..31 639 - timeLastMeasured_hour(uint): Time since last measured value was available UTC hours 0..23 640 - timeLastMeasured_min(uint): Time since last measured value was available minutes 641 - timeLastMeasured_sec(uint): Time since last measured value was available seconds 642 @param params: Dictionary of field names/values. 643 @param out: File like object to write to 644 @rtype: stdout 645 @return: text to out 646 ''' 647 648 if 'std'==format: 649 out.write("waterlevel:\n") 650 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n") 651 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n") 652 if 'efid' in params: out.write(" efid: "+str(params['efid'])+"\n") 653 if 'timetag_month' in params: out.write(" timetag_month: "+str(params['timetag_month'])+"\n") 654 if 'timetag_day' in params: out.write(" timetag_day: "+str(params['timetag_day'])+"\n") 655 if 'timetag_hour' in params: out.write(" timetag_hour: "+str(params['timetag_hour'])+"\n") 656 if 'timetag_min' in params: out.write(" timetag_min: "+str(params['timetag_min'])+"\n") 657 if 'timetag_sec' in params: out.write(" timetag_sec: "+str(params['timetag_sec'])+"\n") 658 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n") 659 if 'stationloc_longitude' in params: out.write(" stationloc_longitude: "+str(params['stationloc_longitude'])+"\n") 660 if 'stationloc_latitude' in params: out.write(" stationloc_latitude: "+str(params['stationloc_latitude'])+"\n") 661 if 'waterlevel' in params: out.write(" waterlevel: "+str(params['waterlevel'])+"\n") 662 if 'datum' in params: out.write(" datum: "+str(params['datum'])+"\n") 663 if 'sigma' in params: out.write(" sigma: "+str(params['sigma'])+"\n") 664 if 'o' in params: out.write(" o: "+str(params['o'])+"\n") 665 if 'levelinferred' in params: out.write(" levelinferred: "+str(params['levelinferred'])+"\n") 666 if 'flat_tolerance_exceeded' in params: out.write(" flat_tolerance_exceeded: "+str(params['flat_tolerance_exceeded'])+"\n") 667 if 'rate_tolerance_exceeded' in params: out.write(" rate_tolerance_exceeded: "+str(params['rate_tolerance_exceeded'])+"\n") 668 if 'temp_tolerance_exceeded' in params: out.write(" temp_tolerance_exceeded: "+str(params['temp_tolerance_exceeded'])+"\n") 669 if 'expected_height_exceeded' in params: out.write(" expected_height_exceeded: "+str(params['expected_height_exceeded'])+"\n") 670 if 'link_down' in params: out.write(" link_down: "+str(params['link_down'])+"\n") 671 if 'timeLastMeasured_month' in params: out.write(" timeLastMeasured_month: "+str(params['timeLastMeasured_month'])+"\n") 672 if 'timeLastMeasured_day' in params: out.write(" timeLastMeasured_day: "+str(params['timeLastMeasured_day'])+"\n") 673 if 'timeLastMeasured_hour' in params: out.write(" timeLastMeasured_hour: "+str(params['timeLastMeasured_hour'])+"\n") 674 if 'timeLastMeasured_min' in params: out.write(" timeLastMeasured_min: "+str(params['timeLastMeasured_min'])+"\n") 675 if 'timeLastMeasured_sec' in params: out.write(" timeLastMeasured_sec: "+str(params['timeLastMeasured_sec'])+"\n") 676 elif 'csv'==format: 677 if None == options.fieldList: 678 options.fieldList = fieldList 679 needComma = False; 680 for field in fieldList: 681 if needComma: out.write(',') 682 needComma = True 683 if field in params: 684 out.write(str(params[field])) 685 # else: leave it empty 686 out.write("\n") 687 elif 'html'==format: 688 printHtml(params,out) 689 elif 'sql'==format: 690 sqlInsertStr(params,out,dbType=dbType) 691 elif 'kml'==format: 692 printKml(params,out) 693 elif 'kml-full'==format: 694 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") 695 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n") 696 out.write("<Document>\n") 697 out.write(" <name>waterlevel</name>\n") 698 printKml(params,out) 699 out.write("</Document>\n") 700 out.write("</kml>\n") 701 else: 702 print "ERROR: unknown format:",format 703 assert False 704 705 return # Nothing to return
706 707 datumEncodeLut = { 708 'MLLW':'0', 709 'IGLD-85':'1', 710 'WaterDepth':'2', 711 'STND':'3', 712 'MHW':'4', 713 'MLS':'5', 714 'NGVD':'6', 715 'NAVD':'7', 716 'WGS-84':'8', 717 'LAT':'9', 718 } #datumEncodeLut 719 720 datumDecodeLut = { 721 '0':'MLLW', 722 '1':'IGLD-85', 723 '2':'WaterDepth', 724 '3':'STND', 725 '4':'MHW', 726 '5':'MLS', 727 '6':'NGVD', 728 '7':'NAVD', 729 '8':'WGS-84', 730 '9':'LAT', 731 } # datumEncodeLut 732 733 ###################################################################### 734 # SQL SUPPORT 735 ###################################################################### 736
737 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 738 ,addCoastGuardFields=True 739 ,dbType='postgres' 740 ):
741 ''' 742 Return the SQL CREATE command for this message type 743 @param outfile: file like object to print to. 744 @param fields: which fields to put in the create. Defaults to all. 745 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 746 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 747 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 748 @type addCoastGuardFields: bool 749 @return: sql create string 750 @rtype: str 751 752 @see: sqlCreate 753 ''' 754 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
755
756 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
757 ''' 758 Return the sqlhelp object to create the table. 759 760 @param fields: which fields to put in the create. Defaults to all. 761 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 762 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 763 @type addCoastGuardFields: bool 764 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 765 @return: An object that can be used to generate a return 766 @rtype: sqlhelp.create 767 ''' 768 if None == fields: fields = fieldList 769 import sqlhelp 770 c = sqlhelp.create('waterlevel',dbType=dbType) 771 c.addPrimaryKey() 772 if 'dac' in fields: c.addInt ('dac') 773 if 'fid' in fields: c.addInt ('fid') 774 if 'efid' in fields: c.addInt ('efid') 775 if 'timetag_month' in fields: c.addInt ('timetag_month') 776 if 'timetag_day' in fields: c.addInt ('timetag_day') 777 if 'timetag_hour' in fields: c.addInt ('timetag_hour') 778 if 'timetag_min' in fields: c.addInt ('timetag_min') 779 if 'timetag_sec' in fields: c.addInt ('timetag_sec') 780 if 'stationid' in fields: c.addVarChar('stationid',7) 781 if 'stationloc_longitude' in fields: c.addDecimal('stationloc_longitude',8,5) 782 if 'stationloc_latitude' in fields: c.addDecimal('stationloc_latitude',8,5) 783 if 'waterlevel' in fields: c.addInt ('waterlevel') 784 if 'datum' in fields: c.addInt ('datum') 785 if 'sigma' in fields: c.addReal('sigma') 786 if 'o' in fields: c.addInt ('o') 787 if 'levelinferred' in fields: c.addBool('levelinferred') 788 if 'flat_tolerance_exceeded' in fields: c.addBool('flat_tolerance_exceeded') 789 if 'rate_tolerance_exceeded' in fields: c.addBool('rate_tolerance_exceeded') 790 if 'temp_tolerance_exceeded' in fields: c.addBool('temp_tolerance_exceeded') 791 if 'expected_height_exceeded' in fields: c.addBool('expected_height_exceeded') 792 if 'link_down' in fields: c.addBool('link_down') 793 if 'timeLastMeasured_month' in fields: c.addInt ('timeLastMeasured_month') 794 if 'timeLastMeasured_day' in fields: c.addInt ('timeLastMeasured_day') 795 if 'timeLastMeasured_hour' in fields: c.addInt ('timeLastMeasured_hour') 796 if 'timeLastMeasured_min' in fields: c.addInt ('timeLastMeasured_min') 797 if 'timeLastMeasured_sec' in fields: c.addInt ('timeLastMeasured_sec') 798 799 if addCoastGuardFields: 800 # c.addInt('cg_rssi') # Relative signal strength indicator 801 # c.addInt('cg_d') # dBm receive strength 802 # c.addInt('cg_T') # Receive timestamp from the AIS equipment 803 # c.addInt('cg_S') # Slot received in 804 # c.addVarChar('cg_x',10) # Idonno 805 c.addVarChar('cg_r',15) # Receiver station ID - should usually be an MMSI, but sometimes is a string 806 c.addInt('cg_sec') # UTC seconds since the epoch 807 808 c.addTimestamp('cg_timestamp') # UTC decoded cg_sec - not actually in the data stream 809 810 return c
811
812 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
813 ''' 814 Return the SQL INSERT command for this message type 815 @param params: dictionary of values keyed by field name 816 @param outfile: file like object to print to. 817 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 818 @return: sql create string 819 @rtype: str 820 821 @see: sqlCreate 822 ''' 823 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
824 825
826 -def sqlInsert(params,extraParams=None,dbType='postgres'):
827 ''' 828 Give the SQL INSERT statement 829 @param params: dict keyed by field name of values 830 @param extraParams: any extra fields that you have created beyond the normal ais message fields 831 @rtype: sqlhelp.insert 832 @return: insert class instance 833 @todo: allow optional type checking of params? 834 @warning: this will take invalid keys happily and do what??? 835 ''' 836 import sqlhelp 837 i = sqlhelp.insert('waterlevel',dbType=dbType) 838 839 if dbType=='postgres': 840 finished = [] 841 for key in params: 842 if key in finished: 843 continue 844 845 if key not in toPgFields and key not in fromPgFields: 846 if type(params[key])==Decimal: i.add(key,float(params[key])) 847 else: i.add(key,params[key]) 848 else: 849 if key in fromPgFields: 850 val = params[key] 851 # Had better be a WKT type like POINT(-88.1 30.321) 852 i.addPostGIS(key,val) 853 finished.append(key) 854 else: 855 # Need to construct the type. 856 pgName = toPgFields[key] 857 #valStr='GeomFromText(\''+pgTypes[pgName]+'(' 858 valStr=pgTypes[pgName]+'(' 859 vals = [] 860 for nonPgKey in fromPgFields[pgName]: 861 vals.append(str(params[nonPgKey])) 862 finished.append(nonPgKey) 863 valStr+=' '.join(vals)+')' 864 i.addPostGIS(pgName,valStr) 865 else: 866 for key in params: 867 if type(params[key])==Decimal: i.add(key,float(params[key])) 868 else: i.add(key,params[key]) 869 870 if None != extraParams: 871 for key in extraParams: 872 i.add(key,extraParams[key]) 873 874 return i
875 876 877 ###################################################################### 878 # UNIT TESTING 879 ###################################################################### 880 import unittest
881 -def testParams():
882 '''Return a params file base on the testvalue tags. 883 @rtype: dict 884 @return: params based on testvalue tags 885 ''' 886 params = {} 887 params['dac'] = 366 888 params['fid'] = 1 889 params['efid'] = 1 890 params['timetag_month'] = 2 891 params['timetag_day'] = 28 892 params['timetag_hour'] = 23 893 params['timetag_min'] = 45 894 params['timetag_sec'] = 58 895 params['stationid'] = 'A234567' 896 params['stationloc_longitude'] = Decimal('-122.16328055555556') 897 params['stationloc_latitude'] = Decimal('37.424458333333334') 898 params['waterlevel'] = -97 899 params['datum'] = 0 900 params['sigma'] = -1.234 901 params['o'] = 240 902 params['levelinferred'] = False 903 params['flat_tolerance_exceeded'] = True 904 params['rate_tolerance_exceeded'] = False 905 params['temp_tolerance_exceeded'] = False 906 params['expected_height_exceeded'] = True 907 params['link_down'] = False 908 params['timeLastMeasured_month'] = 2 909 params['timeLastMeasured_day'] = 28 910 params['timeLastMeasured_hour'] = 23 911 params['timeLastMeasured_min'] = 45 912 params['timeLastMeasured_sec'] = 58 913 914 return params
915
916 -class Testwaterlevel(unittest.TestCase):
917 '''Use testvalue tag text from each type to build test case the waterlevel message'''
918 - def testEncodeDecode(self):
919 920 params = testParams() 921 bits = encode(params) 922 r = decode(bits) 923 924 # Check that each parameter came through ok. 925 self.failUnlessEqual(r['dac'],params['dac']) 926 self.failUnlessEqual(r['fid'],params['fid']) 927 self.failUnlessEqual(r['efid'],params['efid']) 928 self.failUnlessEqual(r['timetag_month'],params['timetag_month']) 929 self.failUnlessEqual(r['timetag_day'],params['timetag_day']) 930 self.failUnlessEqual(r['timetag_hour'],params['timetag_hour']) 931 self.failUnlessEqual(r['timetag_min'],params['timetag_min']) 932 self.failUnlessEqual(r['timetag_sec'],params['timetag_sec']) 933 self.failUnlessEqual(r['stationid'],params['stationid']) 934 self.failUnlessAlmostEqual(r['stationloc_longitude'],params['stationloc_longitude'],5) 935 self.failUnlessAlmostEqual(r['stationloc_latitude'],params['stationloc_latitude'],5) 936 self.failUnlessEqual(r['waterlevel'],params['waterlevel']) 937 self.failUnlessEqual(r['datum'],params['datum']) 938 self.failUnlessAlmostEqual(r['sigma'],params['sigma'],3) 939 self.failUnlessEqual(r['o'],params['o']) 940 self.failUnlessEqual(r['levelinferred'],params['levelinferred']) 941 self.failUnlessEqual(r['flat_tolerance_exceeded'],params['flat_tolerance_exceeded']) 942 self.failUnlessEqual(r['rate_tolerance_exceeded'],params['rate_tolerance_exceeded']) 943 self.failUnlessEqual(r['temp_tolerance_exceeded'],params['temp_tolerance_exceeded']) 944 self.failUnlessEqual(r['expected_height_exceeded'],params['expected_height_exceeded']) 945 self.failUnlessEqual(r['link_down'],params['link_down']) 946 self.failUnlessEqual(r['timeLastMeasured_month'],params['timeLastMeasured_month']) 947 self.failUnlessEqual(r['timeLastMeasured_day'],params['timeLastMeasured_day']) 948 self.failUnlessEqual(r['timeLastMeasured_hour'],params['timeLastMeasured_hour']) 949 self.failUnlessEqual(r['timeLastMeasured_min'],params['timeLastMeasured_min']) 950 self.failUnlessEqual(r['timeLastMeasured_sec'],params['timeLastMeasured_sec'])
951
952 -def addMsgOptions(parser):
953 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 954 help='decode a "waterlevel" AIS message') 955 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 956 help='encode a "waterlevel" AIS message') 957 parser.add_option('--timetag_month-field', dest='timetag_monthField',metavar='uint',type='int' 958 ,help='Field parameter value [default: %default]') 959 parser.add_option('--timetag_day-field', dest='timetag_dayField',metavar='uint',type='int' 960 ,help='Field parameter value [default: %default]') 961 parser.add_option('--timetag_hour-field', dest='timetag_hourField',metavar='uint',type='int' 962 ,help='Field parameter value [default: %default]') 963 parser.add_option('--timetag_min-field', dest='timetag_minField',metavar='uint',type='int' 964 ,help='Field parameter value [default: %default]') 965 parser.add_option('--timetag_sec-field', dest='timetag_secField',metavar='uint',type='int' 966 ,help='Field parameter value [default: %default]') 967 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string' 968 ,help='Field parameter value [default: %default]') 969 parser.add_option('--stationloc_longitude-field', dest='stationloc_longitudeField',default=Decimal('181'),metavar='decimal',type='string' 970 ,help='Field parameter value [default: %default]') 971 parser.add_option('--stationloc_latitude-field', dest='stationloc_latitudeField',default=Decimal('91'),metavar='decimal',type='string' 972 ,help='Field parameter value [default: %default]') 973 parser.add_option('--waterlevel-field', dest='waterlevelField',default=-32768,metavar='int',type='int' 974 ,help='Field parameter value [default: %default]') 975 parser.add_option('--datum-field', dest='datumField',default=31,metavar='uint',type='int' 976 ,help='Field parameter value [default: %default]') 977 parser.add_option('--sigma-field', dest='sigmaField',metavar='float',type='float' 978 ,help='Field parameter value [default: %default]') 979 parser.add_option('--o-field', dest='oField',default=255,metavar='uint',type='int' 980 ,help='Field parameter value [default: %default]') 981 parser.add_option('--levelinferred-field', dest='levelinferredField',metavar='bool',type='int' 982 ,help='Field parameter value [default: %default]') 983 parser.add_option('--flat_tolerance_exceeded-field', dest='flat_tolerance_exceededField',metavar='bool',type='int' 984 ,help='Field parameter value [default: %default]') 985 parser.add_option('--rate_tolerance_exceeded-field', dest='rate_tolerance_exceededField',metavar='bool',type='int' 986 ,help='Field parameter value [default: %default]') 987 parser.add_option('--temp_tolerance_exceeded-field', dest='temp_tolerance_exceededField',metavar='bool',type='int' 988 ,help='Field parameter value [default: %default]') 989 parser.add_option('--expected_height_exceeded-field', dest='expected_height_exceededField',metavar='bool',type='int' 990 ,help='Field parameter value [default: %default]') 991 parser.add_option('--link_down-field', dest='link_downField',metavar='bool',type='int' 992 ,help='Field parameter value [default: %default]') 993 parser.add_option('--timeLastMeasured_month-field', dest='timeLastMeasured_monthField',metavar='uint',type='int' 994 ,help='Field parameter value [default: %default]') 995 parser.add_option('--timeLastMeasured_day-field', dest='timeLastMeasured_dayField',metavar='uint',type='int' 996 ,help='Field parameter value [default: %default]') 997 parser.add_option('--timeLastMeasured_hour-field', dest='timeLastMeasured_hourField',metavar='uint',type='int' 998 ,help='Field parameter value [default: %default]') 999 parser.add_option('--timeLastMeasured_min-field', dest='timeLastMeasured_minField',metavar='uint',type='int' 1000 ,help='Field parameter value [default: %default]') 1001 parser.add_option('--timeLastMeasured_sec-field', dest='timeLastMeasured_secField',metavar='uint',type='int' 1002 ,help='Field parameter value [default: %default]')
1003 1004 ############################################################ 1005 if __name__=='__main__': 1006 1007 from optparse import OptionParser 1008 parser = OptionParser(usage="%prog [options]", 1009 version="%prog "+__version__) 1010 1011 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 1012 help='run the documentation tests') 1013 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 1014 help='run the unit tests') 1015 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 1016 help='Make the test output verbose') 1017 1018 # FIX: remove nmea from binary messages. No way to build the whole packet? 1019 # FIX: or build the surrounding msg 8 for a broadcast? 1020 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 1021 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 1022 ,default='nmeapayload' 1023 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 1024 1025 1026 outputChoices = ('std','html','csv','sql' , 'kml','kml-full') 1027 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 1028 ,default='std' 1029 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 1030 1031 parser.add_option('-o','--output',dest='outputFileName',default=None, 1032 help='Name of the python file to write [default: stdout]') 1033 1034 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 1035 choices=fieldList, 1036 help='Which fields to include in the output. Currently only for csv output [default: all]') 1037 1038 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 1039 help='Print the field name for csv') 1040 1041 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 1042 help='Print out an sql create command for the table.') 1043 1044 dbChoices = ('sqlite','postgres') 1045 parser.add_option('-D','--db-type',dest='dbType',default='postgres' 1046 ,choices=dbChoices,type='choice' 1047 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 1048 1049 addMsgOptions(parser) 1050 1051 (options,args) = parser.parse_args() 1052 success=True 1053 1054 if options.doctest: 1055 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 1056 sys.argv= [sys.argv[0]] 1057 if options.verbose: sys.argv.append('-v') 1058 import doctest 1059 numfail,numtests=doctest.testmod() 1060 if numfail==0: print 'ok' 1061 else: 1062 print 'FAILED' 1063 success=False 1064 1065 if not success: sys.exit('Something Failed') 1066 del success # Hide success from epydoc 1067 1068 if options.unittest: 1069 sys.argv = [sys.argv[0]] 1070 if options.verbose: sys.argv.append('-v') 1071 unittest.main() 1072 1073 outfile = sys.stdout 1074 if None!=options.outputFileName: 1075 outfile = file(options.outputFileName,'w') 1076 1077 1078 if options.doEncode: 1079 # First make sure all non required options are specified 1080 if None==options.timetag_monthField: parser.error("missing value for timetag_monthField") 1081 if None==options.timetag_dayField: parser.error("missing value for timetag_dayField") 1082 if None==options.timetag_hourField: parser.error("missing value for timetag_hourField") 1083 if None==options.timetag_minField: parser.error("missing value for timetag_minField") 1084 if None==options.timetag_secField: parser.error("missing value for timetag_secField") 1085 if None==options.stationidField: parser.error("missing value for stationidField") 1086 if None==options.stationloc_longitudeField: parser.error("missing value for stationloc_longitudeField") 1087 if None==options.stationloc_latitudeField: parser.error("missing value for stationloc_latitudeField") 1088 if None==options.waterlevelField: parser.error("missing value for waterlevelField") 1089 if None==options.datumField: parser.error("missing value for datumField") 1090 if None==options.sigmaField: parser.error("missing value for sigmaField") 1091 if None==options.oField: parser.error("missing value for oField") 1092 if None==options.levelinferredField: parser.error("missing value for levelinferredField") 1093 if None==options.flat_tolerance_exceededField: parser.error("missing value for flat_tolerance_exceededField") 1094 if None==options.rate_tolerance_exceededField: parser.error("missing value for rate_tolerance_exceededField") 1095 if None==options.temp_tolerance_exceededField: parser.error("missing value for temp_tolerance_exceededField") 1096 if None==options.expected_height_exceededField: parser.error("missing value for expected_height_exceededField") 1097 if None==options.link_downField: parser.error("missing value for link_downField") 1098 if None==options.timeLastMeasured_monthField: parser.error("missing value for timeLastMeasured_monthField") 1099 if None==options.timeLastMeasured_dayField: parser.error("missing value for timeLastMeasured_dayField") 1100 if None==options.timeLastMeasured_hourField: parser.error("missing value for timeLastMeasured_hourField") 1101 if None==options.timeLastMeasured_minField: parser.error("missing value for timeLastMeasured_minField") 1102 if None==options.timeLastMeasured_secField: parser.error("missing value for timeLastMeasured_secField") 1103 msgDict={ 1104 'dac': '366', 1105 'fid': '1', 1106 'efid': '1', 1107 'timetag_month': options.timetag_monthField, 1108 'timetag_day': options.timetag_dayField, 1109 'timetag_hour': options.timetag_hourField, 1110 'timetag_min': options.timetag_minField, 1111 'timetag_sec': options.timetag_secField, 1112 'stationid': options.stationidField, 1113 'stationloc_longitude': options.stationloc_longitudeField, 1114 'stationloc_latitude': options.stationloc_latitudeField, 1115 'waterlevel': options.waterlevelField, 1116 'datum': options.datumField, 1117 'sigma': options.sigmaField, 1118 'o': options.oField, 1119 'levelinferred': options.levelinferredField, 1120 'flat_tolerance_exceeded': options.flat_tolerance_exceededField, 1121 'rate_tolerance_exceeded': options.rate_tolerance_exceededField, 1122 'temp_tolerance_exceeded': options.temp_tolerance_exceededField, 1123 'expected_height_exceeded': options.expected_height_exceededField, 1124 'link_down': options.link_downField, 1125 'timeLastMeasured_month': options.timeLastMeasured_monthField, 1126 'timeLastMeasured_day': options.timeLastMeasured_dayField, 1127 'timeLastMeasured_hour': options.timeLastMeasured_hourField, 1128 'timeLastMeasured_min': options.timeLastMeasured_minField, 1129 'timeLastMeasured_sec': options.timeLastMeasured_secField, 1130 } 1131 1132 bits = encode(msgDict) 1133 if 'binary'==options.ioType: print str(bits) 1134 elif 'nmeapayload'==options.ioType: 1135 # FIX: figure out if this might be necessary at compile time 1136 print "bitLen",len(bits) 1137 bitLen=len(bits) 1138 if bitLen%6!=0: 1139 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 1140 print "result:",binary.bitvectoais6(bits)[0] 1141 1142 1143 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 1144 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 1145 else: sys.exit('ERROR: unknown ioType. Help!') 1146 1147 1148 if options.sqlCreate: 1149 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 1150 1151 if options.printCsvfieldList: 1152 # Make a csv separated list of fields that will be displayed for csv 1153 if None == options.fieldList: options.fieldList = fieldList 1154 import StringIO 1155 buf = StringIO.StringIO() 1156 for field in options.fieldList: 1157 buf.write(field+',') 1158 result = buf.getvalue() 1159 if result[-1] == ',': print result[:-1] 1160 else: print result 1161 1162 if options.doDecode: 1163 for msg in args: 1164 bv = None 1165 1166 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 1167 # Found nmea 1168 # FIX: do checksum 1169 bv = binary.ais6tobitvec(msg.split(',')[5]) 1170 else: # either binary or nmeapayload... expect mostly nmeapayloads 1171 # assumes that an all 0 and 1 string can not be a nmeapayload 1172 binaryMsg=True 1173 for c in msg: 1174 if c not in ('0','1'): 1175 binaryMsg=False 1176 break 1177 if binaryMsg: 1178 bv = BitVector(bitstring=msg) 1179 else: # nmeapayload 1180 bv = binary.ais6tobitvec(msg) 1181 1182 printFields(decode(bv) 1183 ,out=outfile 1184 ,format=options.outputType 1185 ,fieldList=options.fieldList 1186 ,dbType=options.dbType 1187 ) 1188