1
2
3 __version__ = '$Revision: 4791 $'.split()[1]
4 __date__ = '$Date: 2007-01-18 $'.split()[1]
5 __author__ = 'xmlbinmsg'
6
7 __doc__='''
8
9 Autogenerated python functions to serialize/deserialize binary messages.
10
11 Generated by: ./aisxmlbinmsg2py.py
12
13 Need to then wrap these functions with the outer AIS packet and then
14 convert the whole binary blob to a NMEA string. Those functions are
15 not currently provided in this file.
16
17 serialize: python to ais binary
18 deserialize: ais binary to python
19
20 The generated code uses translators.py, binary.py, and aisstring.py
21 which should be packaged with the resulting files.
22
23
24 @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3
25 @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>}
26
27 @author: '''+__author__+'''
28 @version: ''' + __version__ +'''
29 @var __date__: Date of last svn commit
30 @undocumented: __version__ __author__ __doc__ parser
31 @status: under development
32 @license: Generated code has no license
33 '''
34
35 import sys
36 from decimal import Decimal
37 from BitVector import BitVector
38
39 import binary, aisstring
40
41
42 TrueBV = BitVector(bitstring="1")
43 "Why always rebuild the True bit? This should speed things up a bunch"
44 FalseBV = BitVector(bitstring="0")
45 "Why always rebuild the False bit? This should speed things up a bunch"
46
47
48 fieldList = [
49 'dac',
50 'fid',
51 'efid',
52 'timetag_month',
53 'timetag_day',
54 'timetag_hour',
55 'timetag_min',
56 'timetag_sec',
57 'stationid',
58 'stationloc_longitude',
59 'stationloc_latitude',
60 'waterlevel',
61 'datum',
62 'sigma',
63 'o',
64 'levelinferred',
65 'flat_tolerance_exceeded',
66 'rate_tolerance_exceeded',
67 'temp_tolerance_exceeded',
68 'expected_height_exceeded',
69 'link_down',
70 'timeLastMeasured_month',
71 'timeLastMeasured_day',
72 'timeLastMeasured_hour',
73 'timeLastMeasured_min',
74 'timeLastMeasured_sec',
75 ]
76
77 -def encode(params, validate=False):
78 '''Create a waterlevel binary message payload to pack into an AIS Msg waterlevel.
79
80 Fields in params:
81 - dac(uint): Designated Area Code (field automatically set to "366")
82 - fid(uint): Functional Identifier (field automatically set to "1")
83 - efid(uint): extended functional identifier (field automatically set to "1")
84 - timetag_month(uint): Time the measurement represents month 1..12
85 - timetag_day(uint): Time the measurement represents day of the month 1..31
86 - timetag_hour(uint): Time the measurement represents UTC hours 0..23
87 - timetag_min(uint): Time the measurement represents minutes
88 - timetag_sec(uint): Time the measurement represents seconds
89 - stationid(aisstr6): Character identifier of the station. Usually a number.
90 - stationloc_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location
91 - stationloc_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location
92 - waterlevel(int): Water level in centimeters
93 - datum(uint): What reference datum applies to the value
94 - sigma(float): Standard deviation of 1 second samples used to compute the water level height
95 - o(uint): Count of number of samples that fall outside a 3-sigma band about the mean
96 - levelinferred(bool): indicates that the water level value has been inferred
97 - flat_tolerance_exceeded(bool): flat tolerance limit was exceeded. Need better descr
98 - rate_tolerance_exceeded(bool): rate of change tolerance limit was exceeded
99 - temp_tolerance_exceeded(bool): temperature difference tolerance limit was exceeded
100 - expected_height_exceeded(bool): either the maximum or minimum expected water level height limit was exceeded
101 - link_down(bool): Unable to communicate with the tide system. All data invalid
102 - timeLastMeasured_month(uint): Time since last measured value was available month 1..12
103 - timeLastMeasured_day(uint): Time since last measured value was available day of the month 1..31
104 - timeLastMeasured_hour(uint): Time since last measured value was available UTC hours 0..23
105 - timeLastMeasured_min(uint): Time since last measured value was available minutes
106 - timeLastMeasured_sec(uint): Time since last measured value was available seconds
107 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing
108 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
109 @rtype: BitVector
110 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8
111 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits.
112 '''
113
114 bvList = []
115 bvList.append(binary.setBitVectorSize(BitVector(intVal=366),16))
116 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),4))
117 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),12))
118 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_month']),4))
119 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_day']),5))
120 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_hour']),5))
121 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_min']),6))
122 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_sec']),6))
123 if 'stationid' in params:
124 bvList.append(aisstring.encode(params['stationid'],42))
125 else:
126 bvList.append(aisstring.encode('@@@@@@@',42))
127 if 'stationloc_longitude' in params:
128 bvList.append(binary.bvFromSignedInt(int(Decimal(params['stationloc_longitude'])*Decimal('600000')),28))
129 else:
130 bvList.append(binary.bvFromSignedInt(108600000,28))
131 if 'stationloc_latitude' in params:
132 bvList.append(binary.bvFromSignedInt(int(Decimal(params['stationloc_latitude'])*Decimal('600000')),27))
133 else:
134 bvList.append(binary.bvFromSignedInt(54600000,27))
135 if 'waterlevel' in params:
136 bvList.append(binary.bvFromSignedInt(params['waterlevel'],16))
137 else:
138 bvList.append(binary.bvFromSignedInt(-32768,16))
139 if 'datum' in params:
140 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['datum']),5))
141 else:
142 bvList.append(binary.setBitVectorSize(BitVector(intVal=31),5))
143 bvList.append(binary.float2bitvec(params['sigma']))
144 if 'o' in params:
145 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['o']),8))
146 else:
147 bvList.append(binary.setBitVectorSize(BitVector(intVal=255),8))
148 if params["levelinferred"]: bvList.append(TrueBV)
149 else: bvList.append(FalseBV)
150 if params["flat_tolerance_exceeded"]: bvList.append(TrueBV)
151 else: bvList.append(FalseBV)
152 if params["rate_tolerance_exceeded"]: bvList.append(TrueBV)
153 else: bvList.append(FalseBV)
154 if params["temp_tolerance_exceeded"]: bvList.append(TrueBV)
155 else: bvList.append(FalseBV)
156 if params["expected_height_exceeded"]: bvList.append(TrueBV)
157 else: bvList.append(FalseBV)
158 if params["link_down"]: bvList.append(TrueBV)
159 else: bvList.append(FalseBV)
160 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_month']),4))
161 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_day']),5))
162 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_hour']),5))
163 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_min']),6))
164 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timeLastMeasured_sec']),6))
165
166 return binary.joinBV(bvList)
167
168 -def decode(bv, validate=False):
169 '''Unpack a waterlevel message
170
171 Fields in params:
172 - dac(uint): Designated Area Code (field automatically set to "366")
173 - fid(uint): Functional Identifier (field automatically set to "1")
174 - efid(uint): extended functional identifier (field automatically set to "1")
175 - timetag_month(uint): Time the measurement represents month 1..12
176 - timetag_day(uint): Time the measurement represents day of the month 1..31
177 - timetag_hour(uint): Time the measurement represents UTC hours 0..23
178 - timetag_min(uint): Time the measurement represents minutes
179 - timetag_sec(uint): Time the measurement represents seconds
180 - stationid(aisstr6): Character identifier of the station. Usually a number.
181 - stationloc_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location
182 - stationloc_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location
183 - waterlevel(int): Water level in centimeters
184 - datum(uint): What reference datum applies to the value
185 - sigma(float): Standard deviation of 1 second samples used to compute the water level height
186 - o(uint): Count of number of samples that fall outside a 3-sigma band about the mean
187 - levelinferred(bool): indicates that the water level value has been inferred
188 - flat_tolerance_exceeded(bool): flat tolerance limit was exceeded. Need better descr
189 - rate_tolerance_exceeded(bool): rate of change tolerance limit was exceeded
190 - temp_tolerance_exceeded(bool): temperature difference tolerance limit was exceeded
191 - expected_height_exceeded(bool): either the maximum or minimum expected water level height limit was exceeded
192 - link_down(bool): Unable to communicate with the tide system. All data invalid
193 - timeLastMeasured_month(uint): Time since last measured value was available month 1..12
194 - timeLastMeasured_day(uint): Time since last measured value was available day of the month 1..31
195 - timeLastMeasured_hour(uint): Time since last measured value was available UTC hours 0..23
196 - timeLastMeasured_min(uint): Time since last measured value was available minutes
197 - timeLastMeasured_sec(uint): Time since last measured value was available seconds
198 @type bv: BitVector
199 @param bv: Bits defining a message
200 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
201 @rtype: dict
202 @return: params
203 '''
204
205
206
207
208 r = {}
209 r['dac']=366
210 r['fid']=1
211 r['efid']=1
212 r['timetag_month']=int(bv[32:36])
213 r['timetag_day']=int(bv[36:41])
214 r['timetag_hour']=int(bv[41:46])
215 r['timetag_min']=int(bv[46:52])
216 r['timetag_sec']=int(bv[52:58])
217 r['stationid']=aisstring.decode(bv[58:100])
218 r['stationloc_longitude']=Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000')
219 r['stationloc_latitude']=Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000')
220 r['waterlevel']=binary.signedIntFromBV(bv[155:171])
221 r['datum']=int(bv[171:176])
222 r['sigma']=binary.bitvec2float(bv[176:208])
223 r['o']=int(bv[208:216])
224 r['levelinferred']=bool(int(bv[216:217]))
225 r['flat_tolerance_exceeded']=bool(int(bv[217:218]))
226 r['rate_tolerance_exceeded']=bool(int(bv[218:219]))
227 r['temp_tolerance_exceeded']=bool(int(bv[219:220]))
228 r['expected_height_exceeded']=bool(int(bv[220:221]))
229 r['link_down']=bool(int(bv[221:222]))
230 r['timeLastMeasured_month']=int(bv[222:226])
231 r['timeLastMeasured_day']=int(bv[226:231])
232 r['timeLastMeasured_hour']=int(bv[231:236])
233 r['timeLastMeasured_min']=int(bv[236:242])
234 r['timeLastMeasured_sec']=int(bv[242:248])
235 return r
236
238 return 366
239
241 return 1
242
244 return 1
245
248
251
254
257
260
263
266
269
272
274 return int(bv[171:176])
275
278
280 return int(bv[208:216])
281
283 return bool(int(bv[216:217]))
284
286 return bool(int(bv[217:218]))
287
289 return bool(int(bv[218:219]))
290
292 return bool(int(bv[219:220]))
293
295 return bool(int(bv[220:221]))
296
298 return bool(int(bv[221:222]))
299
301 return int(bv[222:226])
302
304 return int(bv[226:231])
305
307 return int(bv[231:236])
308
310 return int(bv[236:242])
311
313 return int(bv[242:248])
314
315
317 out.write("<h3>waterlevel<h3>\n")
318 out.write("<table border=\"1\">\n")
319 out.write("<tr bgcolor=\"orange\">\n")
320 out.write("<th align=\"left\">Field Name</th>\n")
321 out.write("<th align=\"left\">Type</th>\n")
322 out.write("<th align=\"left\">Value</th>\n")
323 out.write("<th align=\"left\">Value in Lookup Table</th>\n")
324 out.write("<th align=\"left\">Units</th>\n")
325 out.write("\n")
326 out.write("<tr>\n")
327 out.write("<td>dac</td>\n")
328 out.write("<td>uint</td>\n")
329 if 'dac' in params:
330 out.write(" <td>"+str(params['dac'])+"</td>\n")
331 out.write(" <td>"+str(params['dac'])+"</td>\n")
332 out.write("</tr>\n")
333 out.write("\n")
334 out.write("<tr>\n")
335 out.write("<td>fid</td>\n")
336 out.write("<td>uint</td>\n")
337 if 'fid' in params:
338 out.write(" <td>"+str(params['fid'])+"</td>\n")
339 out.write(" <td>"+str(params['fid'])+"</td>\n")
340 out.write("</tr>\n")
341 out.write("\n")
342 out.write("<tr>\n")
343 out.write("<td>efid</td>\n")
344 out.write("<td>uint</td>\n")
345 if 'efid' in params:
346 out.write(" <td>"+str(params['efid'])+"</td>\n")
347 out.write(" <td>"+str(params['efid'])+"</td>\n")
348 out.write("</tr>\n")
349 out.write("\n")
350 out.write("<tr>\n")
351 out.write("<td>timetag_month</td>\n")
352 out.write("<td>uint</td>\n")
353 if 'timetag_month' in params:
354 out.write(" <td>"+str(params['timetag_month'])+"</td>\n")
355 out.write(" <td>"+str(params['timetag_month'])+"</td>\n")
356 out.write("</tr>\n")
357 out.write("\n")
358 out.write("<tr>\n")
359 out.write("<td>timetag_day</td>\n")
360 out.write("<td>uint</td>\n")
361 if 'timetag_day' in params:
362 out.write(" <td>"+str(params['timetag_day'])+"</td>\n")
363 out.write(" <td>"+str(params['timetag_day'])+"</td>\n")
364 out.write("</tr>\n")
365 out.write("\n")
366 out.write("<tr>\n")
367 out.write("<td>timetag_hour</td>\n")
368 out.write("<td>uint</td>\n")
369 if 'timetag_hour' in params:
370 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n")
371 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n")
372 out.write("</tr>\n")
373 out.write("\n")
374 out.write("<tr>\n")
375 out.write("<td>timetag_min</td>\n")
376 out.write("<td>uint</td>\n")
377 if 'timetag_min' in params:
378 out.write(" <td>"+str(params['timetag_min'])+"</td>\n")
379 out.write(" <td>"+str(params['timetag_min'])+"</td>\n")
380 out.write("</tr>\n")
381 out.write("\n")
382 out.write("<tr>\n")
383 out.write("<td>timetag_sec</td>\n")
384 out.write("<td>uint</td>\n")
385 if 'timetag_sec' in params:
386 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n")
387 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n")
388 out.write("</tr>\n")
389 out.write("\n")
390 out.write("<tr>\n")
391 out.write("<td>stationid</td>\n")
392 out.write("<td>aisstr6</td>\n")
393 if 'stationid' in params:
394 out.write(" <td>"+str(params['stationid'])+"</td>\n")
395 out.write(" <td>"+str(params['stationid'])+"</td>\n")
396 out.write("</tr>\n")
397 out.write("\n")
398 out.write("<tr>\n")
399 out.write("<td>stationloc_longitude</td>\n")
400 out.write("<td>decimal</td>\n")
401 if 'stationloc_longitude' in params:
402 out.write(" <td>"+str(params['stationloc_longitude'])+"</td>\n")
403 out.write(" <td>"+str(params['stationloc_longitude'])+"</td>\n")
404 out.write("<td>degrees</td>\n")
405 out.write("</tr>\n")
406 out.write("\n")
407 out.write("<tr>\n")
408 out.write("<td>stationloc_latitude</td>\n")
409 out.write("<td>decimal</td>\n")
410 if 'stationloc_latitude' in params:
411 out.write(" <td>"+str(params['stationloc_latitude'])+"</td>\n")
412 out.write(" <td>"+str(params['stationloc_latitude'])+"</td>\n")
413 out.write("<td>degrees</td>\n")
414 out.write("</tr>\n")
415 out.write("\n")
416 out.write("<tr>\n")
417 out.write("<td>waterlevel</td>\n")
418 out.write("<td>int</td>\n")
419 if 'waterlevel' in params:
420 out.write(" <td>"+str(params['waterlevel'])+"</td>\n")
421 out.write(" <td>"+str(params['waterlevel'])+"</td>\n")
422 out.write("<td>cm</td>\n")
423 out.write("</tr>\n")
424 out.write("\n")
425 out.write("<tr>\n")
426 out.write("<td>datum</td>\n")
427 out.write("<td>uint</td>\n")
428 if 'datum' in params:
429 out.write(" <td>"+str(params['datum'])+"</td>\n")
430 if str(params['datum']) in datumDecodeLut:
431 out.write("<td>"+datumDecodeLut[str(params['datum'])]+"</td>")
432 else:
433 out.write("<td><i>Missing LUT entry</i></td>")
434 out.write("</tr>\n")
435 out.write("\n")
436 out.write("<tr>\n")
437 out.write("<td>sigma</td>\n")
438 out.write("<td>float</td>\n")
439 if 'sigma' in params:
440 out.write(" <td>"+str(params['sigma'])+"</td>\n")
441 out.write(" <td>"+str(params['sigma'])+"</td>\n")
442 out.write("<td>m</td>\n")
443 out.write("</tr>\n")
444 out.write("\n")
445 out.write("<tr>\n")
446 out.write("<td>o</td>\n")
447 out.write("<td>uint</td>\n")
448 if 'o' in params:
449 out.write(" <td>"+str(params['o'])+"</td>\n")
450 out.write(" <td>"+str(params['o'])+"</td>\n")
451 out.write("</tr>\n")
452 out.write("\n")
453 out.write("<tr>\n")
454 out.write("<td>levelinferred</td>\n")
455 out.write("<td>bool</td>\n")
456 if 'levelinferred' in params:
457 out.write(" <td>"+str(params['levelinferred'])+"</td>\n")
458 out.write(" <td>"+str(params['levelinferred'])+"</td>\n")
459 out.write("</tr>\n")
460 out.write("\n")
461 out.write("<tr>\n")
462 out.write("<td>flat_tolerance_exceeded</td>\n")
463 out.write("<td>bool</td>\n")
464 if 'flat_tolerance_exceeded' in params:
465 out.write(" <td>"+str(params['flat_tolerance_exceeded'])+"</td>\n")
466 out.write(" <td>"+str(params['flat_tolerance_exceeded'])+"</td>\n")
467 out.write("</tr>\n")
468 out.write("\n")
469 out.write("<tr>\n")
470 out.write("<td>rate_tolerance_exceeded</td>\n")
471 out.write("<td>bool</td>\n")
472 if 'rate_tolerance_exceeded' in params:
473 out.write(" <td>"+str(params['rate_tolerance_exceeded'])+"</td>\n")
474 out.write(" <td>"+str(params['rate_tolerance_exceeded'])+"</td>\n")
475 out.write("</tr>\n")
476 out.write("\n")
477 out.write("<tr>\n")
478 out.write("<td>temp_tolerance_exceeded</td>\n")
479 out.write("<td>bool</td>\n")
480 if 'temp_tolerance_exceeded' in params:
481 out.write(" <td>"+str(params['temp_tolerance_exceeded'])+"</td>\n")
482 out.write(" <td>"+str(params['temp_tolerance_exceeded'])+"</td>\n")
483 out.write("</tr>\n")
484 out.write("\n")
485 out.write("<tr>\n")
486 out.write("<td>expected_height_exceeded</td>\n")
487 out.write("<td>bool</td>\n")
488 if 'expected_height_exceeded' in params:
489 out.write(" <td>"+str(params['expected_height_exceeded'])+"</td>\n")
490 out.write(" <td>"+str(params['expected_height_exceeded'])+"</td>\n")
491 out.write("</tr>\n")
492 out.write("\n")
493 out.write("<tr>\n")
494 out.write("<td>link_down</td>\n")
495 out.write("<td>bool</td>\n")
496 if 'link_down' in params:
497 out.write(" <td>"+str(params['link_down'])+"</td>\n")
498 out.write(" <td>"+str(params['link_down'])+"</td>\n")
499 out.write("</tr>\n")
500 out.write("\n")
501 out.write("<tr>\n")
502 out.write("<td>timeLastMeasured_month</td>\n")
503 out.write("<td>uint</td>\n")
504 if 'timeLastMeasured_month' in params:
505 out.write(" <td>"+str(params['timeLastMeasured_month'])+"</td>\n")
506 out.write(" <td>"+str(params['timeLastMeasured_month'])+"</td>\n")
507 out.write("</tr>\n")
508 out.write("\n")
509 out.write("<tr>\n")
510 out.write("<td>timeLastMeasured_day</td>\n")
511 out.write("<td>uint</td>\n")
512 if 'timeLastMeasured_day' in params:
513 out.write(" <td>"+str(params['timeLastMeasured_day'])+"</td>\n")
514 out.write(" <td>"+str(params['timeLastMeasured_day'])+"</td>\n")
515 out.write("</tr>\n")
516 out.write("\n")
517 out.write("<tr>\n")
518 out.write("<td>timeLastMeasured_hour</td>\n")
519 out.write("<td>uint</td>\n")
520 if 'timeLastMeasured_hour' in params:
521 out.write(" <td>"+str(params['timeLastMeasured_hour'])+"</td>\n")
522 out.write(" <td>"+str(params['timeLastMeasured_hour'])+"</td>\n")
523 out.write("</tr>\n")
524 out.write("\n")
525 out.write("<tr>\n")
526 out.write("<td>timeLastMeasured_min</td>\n")
527 out.write("<td>uint</td>\n")
528 if 'timeLastMeasured_min' in params:
529 out.write(" <td>"+str(params['timeLastMeasured_min'])+"</td>\n")
530 out.write(" <td>"+str(params['timeLastMeasured_min'])+"</td>\n")
531 out.write("</tr>\n")
532 out.write("\n")
533 out.write("<tr>\n")
534 out.write("<td>timeLastMeasured_sec</td>\n")
535 out.write("<td>uint</td>\n")
536 if 'timeLastMeasured_sec' in params:
537 out.write(" <td>"+str(params['timeLastMeasured_sec'])+"</td>\n")
538 out.write(" <td>"+str(params['timeLastMeasured_sec'])+"</td>\n")
539 out.write("</tr>\n")
540 out.write("</table>\n")
541
542
544 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer'''
545 out.write("\ <Placemark>\n")
546 out.write("\t <name>"+str(params['stationid'])+"</name>\n")
547 out.write("\t\t<description>\n")
548 import StringIO
549 buf = StringIO.StringIO()
550 printHtml(params,buf)
551 import cgi
552 out.write(cgi.escape(buf.getvalue()))
553 out.write("\t\t</description>\n")
554 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n")
555 out.write("\t\t<Point>\n")
556 out.write("\t\t\t<coordinates>")
557 out.write(str(params['stationloc_longitude']))
558 out.write(',')
559 out.write(str(params['stationloc_latitude']))
560 out.write(",0</coordinates>\n")
561 out.write("\t\t</Point>\n")
562 out.write("\t</Placemark>\n")
563
564 -def printFields(params, out=sys.stdout, format='std', fieldList=None):
565 '''Print a timeLastMeasured_sec message to stdout.
566
567 Fields in params:
568 - dac(uint): Designated Area Code (field automatically set to "366")
569 - fid(uint): Functional Identifier (field automatically set to "1")
570 - efid(uint): extended functional identifier (field automatically set to "1")
571 - timetag_month(uint): Time the measurement represents month 1..12
572 - timetag_day(uint): Time the measurement represents day of the month 1..31
573 - timetag_hour(uint): Time the measurement represents UTC hours 0..23
574 - timetag_min(uint): Time the measurement represents minutes
575 - timetag_sec(uint): Time the measurement represents seconds
576 - stationid(aisstr6): Character identifier of the station. Usually a number.
577 - stationloc_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location
578 - stationloc_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location
579 - waterlevel(int): Water level in centimeters
580 - datum(uint): What reference datum applies to the value
581 - sigma(float): Standard deviation of 1 second samples used to compute the water level height
582 - o(uint): Count of number of samples that fall outside a 3-sigma band about the mean
583 - levelinferred(bool): indicates that the water level value has been inferred
584 - flat_tolerance_exceeded(bool): flat tolerance limit was exceeded. Need better descr
585 - rate_tolerance_exceeded(bool): rate of change tolerance limit was exceeded
586 - temp_tolerance_exceeded(bool): temperature difference tolerance limit was exceeded
587 - expected_height_exceeded(bool): either the maximum or minimum expected water level height limit was exceeded
588 - link_down(bool): Unable to communicate with the tide system. All data invalid
589 - timeLastMeasured_month(uint): Time since last measured value was available month 1..12
590 - timeLastMeasured_day(uint): Time since last measured value was available day of the month 1..31
591 - timeLastMeasured_hour(uint): Time since last measured value was available UTC hours 0..23
592 - timeLastMeasured_min(uint): Time since last measured value was available minutes
593 - timeLastMeasured_sec(uint): Time since last measured value was available seconds
594 @param params: Dictionary of field names/values.
595 @param out: File like object to write to
596 @rtype: stdout
597 @return: text to out
598 '''
599
600 if 'std'==format:
601 out.write("timeLastMeasured_sec:\n")
602 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n")
603 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n")
604 if 'efid' in params: out.write(" efid: "+str(params['efid'])+"\n")
605 if 'timetag_month' in params: out.write(" timetag_month: "+str(params['timetag_month'])+"\n")
606 if 'timetag_day' in params: out.write(" timetag_day: "+str(params['timetag_day'])+"\n")
607 if 'timetag_hour' in params: out.write(" timetag_hour: "+str(params['timetag_hour'])+"\n")
608 if 'timetag_min' in params: out.write(" timetag_min: "+str(params['timetag_min'])+"\n")
609 if 'timetag_sec' in params: out.write(" timetag_sec: "+str(params['timetag_sec'])+"\n")
610 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n")
611 if 'stationloc_longitude' in params: out.write(" stationloc_longitude: "+str(params['stationloc_longitude'])+"\n")
612 if 'stationloc_latitude' in params: out.write(" stationloc_latitude: "+str(params['stationloc_latitude'])+"\n")
613 if 'waterlevel' in params: out.write(" waterlevel: "+str(params['waterlevel'])+"\n")
614 if 'datum' in params: out.write(" datum: "+str(params['datum'])+"\n")
615 if 'sigma' in params: out.write(" sigma: "+str(params['sigma'])+"\n")
616 if 'o' in params: out.write(" o: "+str(params['o'])+"\n")
617 if 'levelinferred' in params: out.write(" levelinferred: "+str(params['levelinferred'])+"\n")
618 if 'flat_tolerance_exceeded' in params: out.write(" flat_tolerance_exceeded: "+str(params['flat_tolerance_exceeded'])+"\n")
619 if 'rate_tolerance_exceeded' in params: out.write(" rate_tolerance_exceeded: "+str(params['rate_tolerance_exceeded'])+"\n")
620 if 'temp_tolerance_exceeded' in params: out.write(" temp_tolerance_exceeded: "+str(params['temp_tolerance_exceeded'])+"\n")
621 if 'expected_height_exceeded' in params: out.write(" expected_height_exceeded: "+str(params['expected_height_exceeded'])+"\n")
622 if 'link_down' in params: out.write(" link_down: "+str(params['link_down'])+"\n")
623 if 'timeLastMeasured_month' in params: out.write(" timeLastMeasured_month: "+str(params['timeLastMeasured_month'])+"\n")
624 if 'timeLastMeasured_day' in params: out.write(" timeLastMeasured_day: "+str(params['timeLastMeasured_day'])+"\n")
625 if 'timeLastMeasured_hour' in params: out.write(" timeLastMeasured_hour: "+str(params['timeLastMeasured_hour'])+"\n")
626 if 'timeLastMeasured_min' in params: out.write(" timeLastMeasured_min: "+str(params['timeLastMeasured_min'])+"\n")
627 if 'timeLastMeasured_sec' in params: out.write(" timeLastMeasured_sec: "+str(params['timeLastMeasured_sec'])+"\n")
628 elif 'csv'==format:
629 if None == options.fieldList:
630 options.fieldList = fieldList
631 needComma = False;
632 for field in fieldList:
633 if needComma: out.write(',')
634 needComma = True
635 if field in params:
636 out.write(str(params[field]))
637
638 out.write("\n")
639 elif 'html'==format:
640 printHtml(params,out)
641 elif 'kml'==format:
642 printKml(params,out)
643 elif 'kml-full'==format:
644 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
645 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n")
646 out.write("<Document>\n")
647 out.write(" <name>Position</name>\n")
648 printKml(params,out)
649 out.write("</Document>\n")
650 out.write("</kml>\n")
651 else:
652 print "ERROR: unknown format:",format
653 assert False
654
655 return
656
657 datumEncodeLut = {
658 'MLLW':'0',
659 'IGLD-85':'1',
660 'WaterDepth':'2',
661 'STND':'3',
662 'MHW':'4',
663 'MLS':'5',
664 'NGVD':'6',
665 'NAVD':'7',
666 'WGS-84':'8',
667 'LAT':'9',
668 }
669
670 datumDecodeLut = {
671 '0':'MLLW',
672 '1':'IGLD-85',
673 '2':'WaterDepth',
674 '3':'STND',
675 '4':'MHW',
676 '5':'MLS',
677 '6':'NGVD',
678 '7':'NAVD',
679 '8':'WGS-84',
680 '9':'LAT',
681 }
682
683
684
685
686
687
688 import unittest
690 '''Return a params file base on the testvalue tags.
691 @rtype: dict
692 @return: params based on testvalue tags
693 '''
694 params = {}
695 params['dac'] = 366
696 params['fid'] = 1
697 params['efid'] = 1
698 params['timetag_month'] = 2
699 params['timetag_day'] = 28
700 params['timetag_hour'] = 23
701 params['timetag_min'] = 45
702 params['timetag_sec'] = 58
703 params['stationid'] = 'A234567'
704 params['stationloc_longitude'] = Decimal('-122.16328055555556')
705 params['stationloc_latitude'] = Decimal('37.424458333333334')
706 params['waterlevel'] = -97
707 params['datum'] = 0
708 params['sigma'] = -1.234
709 params['o'] = 240
710 params['levelinferred'] = False
711 params['flat_tolerance_exceeded'] = True
712 params['rate_tolerance_exceeded'] = False
713 params['temp_tolerance_exceeded'] = False
714 params['expected_height_exceeded'] = True
715 params['link_down'] = False
716 params['timeLastMeasured_month'] = 2
717 params['timeLastMeasured_day'] = 28
718 params['timeLastMeasured_hour'] = 23
719 params['timeLastMeasured_min'] = 45
720 params['timeLastMeasured_sec'] = 58
721
722 return params
723
725 '''Use testvalue tag text from each type to build test case the waterlevel message'''
727
728 params = testParams()
729 bits = encode(params)
730 r = decode(bits)
731
732
733 self.failUnlessEqual(r['dac'],params['dac'])
734 self.failUnlessEqual(r['fid'],params['fid'])
735 self.failUnlessEqual(r['efid'],params['efid'])
736 self.failUnlessEqual(r['timetag_month'],params['timetag_month'])
737 self.failUnlessEqual(r['timetag_day'],params['timetag_day'])
738 self.failUnlessEqual(r['timetag_hour'],params['timetag_hour'])
739 self.failUnlessEqual(r['timetag_min'],params['timetag_min'])
740 self.failUnlessEqual(r['timetag_sec'],params['timetag_sec'])
741 self.failUnlessEqual(r['stationid'],params['stationid'])
742 self.failUnlessAlmostEqual(r['stationloc_longitude'],params['stationloc_longitude'],5)
743 self.failUnlessAlmostEqual(r['stationloc_latitude'],params['stationloc_latitude'],5)
744 self.failUnlessEqual(r['waterlevel'],params['waterlevel'])
745 self.failUnlessEqual(r['datum'],params['datum'])
746 self.failUnlessAlmostEqual(r['sigma'],params['sigma'],3)
747 self.failUnlessEqual(r['o'],params['o'])
748 self.failUnlessEqual(r['levelinferred'],params['levelinferred'])
749 self.failUnlessEqual(r['flat_tolerance_exceeded'],params['flat_tolerance_exceeded'])
750 self.failUnlessEqual(r['rate_tolerance_exceeded'],params['rate_tolerance_exceeded'])
751 self.failUnlessEqual(r['temp_tolerance_exceeded'],params['temp_tolerance_exceeded'])
752 self.failUnlessEqual(r['expected_height_exceeded'],params['expected_height_exceeded'])
753 self.failUnlessEqual(r['link_down'],params['link_down'])
754 self.failUnlessEqual(r['timeLastMeasured_month'],params['timeLastMeasured_month'])
755 self.failUnlessEqual(r['timeLastMeasured_day'],params['timeLastMeasured_day'])
756 self.failUnlessEqual(r['timeLastMeasured_hour'],params['timeLastMeasured_hour'])
757 self.failUnlessEqual(r['timeLastMeasured_min'],params['timeLastMeasured_min'])
758 self.failUnlessEqual(r['timeLastMeasured_sec'],params['timeLastMeasured_sec'])
759
761 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true',
762 help='decode a "waterlevel" AIS message')
763 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true',
764 help='encode a "waterlevel" AIS message')
765 parser.add_option('--timetag_month-field', dest='timetag_monthField',metavar='uint',type='int'
766 ,help='Field parameter value [default: %default]')
767 parser.add_option('--timetag_day-field', dest='timetag_dayField',metavar='uint',type='int'
768 ,help='Field parameter value [default: %default]')
769 parser.add_option('--timetag_hour-field', dest='timetag_hourField',metavar='uint',type='int'
770 ,help='Field parameter value [default: %default]')
771 parser.add_option('--timetag_min-field', dest='timetag_minField',metavar='uint',type='int'
772 ,help='Field parameter value [default: %default]')
773 parser.add_option('--timetag_sec-field', dest='timetag_secField',metavar='uint',type='int'
774 ,help='Field parameter value [default: %default]')
775 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string'
776 ,help='Field parameter value [default: %default]')
777 parser.add_option('--stationloc_longitude-field', dest='stationloc_longitudeField',default=Decimal('181'),metavar='decimal',type='string'
778 ,help='Field parameter value [default: %default]')
779 parser.add_option('--stationloc_latitude-field', dest='stationloc_latitudeField',default=Decimal('91'),metavar='decimal',type='string'
780 ,help='Field parameter value [default: %default]')
781 parser.add_option('--waterlevel-field', dest='waterlevelField',default=-32768,metavar='int',type='int'
782 ,help='Field parameter value [default: %default]')
783 parser.add_option('--datum-field', dest='datumField',default=31,metavar='uint',type='int'
784 ,help='Field parameter value [default: %default]')
785 parser.add_option('--sigma-field', dest='sigmaField',metavar='float',type='float'
786 ,help='Field parameter value [default: %default]')
787 parser.add_option('--o-field', dest='oField',default=255,metavar='uint',type='int'
788 ,help='Field parameter value [default: %default]')
789 parser.add_option('--levelinferred-field', dest='levelinferredField',metavar='bool',type='int'
790 ,help='Field parameter value [default: %default]')
791 parser.add_option('--flat_tolerance_exceeded-field', dest='flat_tolerance_exceededField',metavar='bool',type='int'
792 ,help='Field parameter value [default: %default]')
793 parser.add_option('--rate_tolerance_exceeded-field', dest='rate_tolerance_exceededField',metavar='bool',type='int'
794 ,help='Field parameter value [default: %default]')
795 parser.add_option('--temp_tolerance_exceeded-field', dest='temp_tolerance_exceededField',metavar='bool',type='int'
796 ,help='Field parameter value [default: %default]')
797 parser.add_option('--expected_height_exceeded-field', dest='expected_height_exceededField',metavar='bool',type='int'
798 ,help='Field parameter value [default: %default]')
799 parser.add_option('--link_down-field', dest='link_downField',metavar='bool',type='int'
800 ,help='Field parameter value [default: %default]')
801 parser.add_option('--timeLastMeasured_month-field', dest='timeLastMeasured_monthField',metavar='uint',type='int'
802 ,help='Field parameter value [default: %default]')
803 parser.add_option('--timeLastMeasured_day-field', dest='timeLastMeasured_dayField',metavar='uint',type='int'
804 ,help='Field parameter value [default: %default]')
805 parser.add_option('--timeLastMeasured_hour-field', dest='timeLastMeasured_hourField',metavar='uint',type='int'
806 ,help='Field parameter value [default: %default]')
807 parser.add_option('--timeLastMeasured_min-field', dest='timeLastMeasured_minField',metavar='uint',type='int'
808 ,help='Field parameter value [default: %default]')
809 parser.add_option('--timeLastMeasured_sec-field', dest='timeLastMeasured_secField',metavar='uint',type='int'
810 ,help='Field parameter value [default: %default]')
811
812
813 if __name__=='__main__':
814
815 from optparse import OptionParser
816 parser = OptionParser(usage="%prog [options]",
817 version="%prog "+__version__)
818
819 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true',
820 help='run the documentation tests')
821 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true',
822 help='run the unit tests')
823 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true',
824 help='Make the test output verbose')
825
826
827
828 typeChoices = ('binary','nmeapayload','nmea')
829 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType'
830 ,default='nmeapayload'
831 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]')
832
833
834 outputChoices = ('std','html','csv' , 'kml','kml-full')
835 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType'
836 ,default='std'
837 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]')
838
839 parser.add_option('-o','--output',dest='outputFileName',default=None,
840 help='Name of the python file to write [default: stdout]')
841
842 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append',
843 choices=fieldList,
844 help='Which fields to include in the output. Currently only for csv output [default: all]')
845
846 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true',
847 help='Print the field name for csv')
848
849 addMsgOptions(parser)
850
851 (options,args) = parser.parse_args()
852 success=True
853
854 if options.doctest:
855 import os; print os.path.basename(sys.argv[0]), 'doctests ...',
856 sys.argv= [sys.argv[0]]
857 if options.verbose: sys.argv.append('-v')
858 import doctest
859 numfail,numtests=doctest.testmod()
860 if numfail==0: print 'ok'
861 else:
862 print 'FAILED'
863 success=False
864
865 if not success: sys.exit('Something Failed')
866 del success
867
868 if options.unittest:
869 sys.argv = [sys.argv[0]]
870 if options.verbose: sys.argv.append('-v')
871 unittest.main()
872
873 outfile = sys.stdout
874 if None!=options.outputFileName:
875 outfile = file(options.outputFileName,'w')
876
877
878 if options.doEncode:
879
880 if None==options.timetag_monthField: parser.error("missing value for timetag_monthField")
881 if None==options.timetag_dayField: parser.error("missing value for timetag_dayField")
882 if None==options.timetag_hourField: parser.error("missing value for timetag_hourField")
883 if None==options.timetag_minField: parser.error("missing value for timetag_minField")
884 if None==options.timetag_secField: parser.error("missing value for timetag_secField")
885 if None==options.stationidField: parser.error("missing value for stationidField")
886 if None==options.stationloc_longitudeField: parser.error("missing value for stationloc_longitudeField")
887 if None==options.stationloc_latitudeField: parser.error("missing value for stationloc_latitudeField")
888 if None==options.waterlevelField: parser.error("missing value for waterlevelField")
889 if None==options.datumField: parser.error("missing value for datumField")
890 if None==options.sigmaField: parser.error("missing value for sigmaField")
891 if None==options.oField: parser.error("missing value for oField")
892 if None==options.levelinferredField: parser.error("missing value for levelinferredField")
893 if None==options.flat_tolerance_exceededField: parser.error("missing value for flat_tolerance_exceededField")
894 if None==options.rate_tolerance_exceededField: parser.error("missing value for rate_tolerance_exceededField")
895 if None==options.temp_tolerance_exceededField: parser.error("missing value for temp_tolerance_exceededField")
896 if None==options.expected_height_exceededField: parser.error("missing value for expected_height_exceededField")
897 if None==options.link_downField: parser.error("missing value for link_downField")
898 if None==options.timeLastMeasured_monthField: parser.error("missing value for timeLastMeasured_monthField")
899 if None==options.timeLastMeasured_dayField: parser.error("missing value for timeLastMeasured_dayField")
900 if None==options.timeLastMeasured_hourField: parser.error("missing value for timeLastMeasured_hourField")
901 if None==options.timeLastMeasured_minField: parser.error("missing value for timeLastMeasured_minField")
902 if None==options.timeLastMeasured_secField: parser.error("missing value for timeLastMeasured_secField")
903 msgDict={
904 'dac': '366',
905 'fid': '1',
906 'efid': '1',
907 'timetag_month': options.timetag_monthField,
908 'timetag_day': options.timetag_dayField,
909 'timetag_hour': options.timetag_hourField,
910 'timetag_min': options.timetag_minField,
911 'timetag_sec': options.timetag_secField,
912 'stationid': options.stationidField,
913 'stationloc_longitude': options.stationloc_longitudeField,
914 'stationloc_latitude': options.stationloc_latitudeField,
915 'waterlevel': options.waterlevelField,
916 'datum': options.datumField,
917 'sigma': options.sigmaField,
918 'o': options.oField,
919 'levelinferred': options.levelinferredField,
920 'flat_tolerance_exceeded': options.flat_tolerance_exceededField,
921 'rate_tolerance_exceeded': options.rate_tolerance_exceededField,
922 'temp_tolerance_exceeded': options.temp_tolerance_exceededField,
923 'expected_height_exceeded': options.expected_height_exceededField,
924 'link_down': options.link_downField,
925 'timeLastMeasured_month': options.timeLastMeasured_monthField,
926 'timeLastMeasured_day': options.timeLastMeasured_dayField,
927 'timeLastMeasured_hour': options.timeLastMeasured_hourField,
928 'timeLastMeasured_min': options.timeLastMeasured_minField,
929 'timeLastMeasured_sec': options.timeLastMeasured_secField,
930 }
931
932 bits = encode(msgDict)
933 if 'binary'==options.ioType: print str(bits)
934 elif 'nmeapayload'==options.ioType:
935
936 print "bitLen",len(bits)
937 bitLen=len(bits)
938 if bitLen%6!=0:
939 bits = bits + BitVector(size=(6 - (bitLen%6)))
940 print "result:",binary.bitvectoais6(bits)[0]
941
942
943
944 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability")
945 else: sys.exit('ERROR: unknown ioType. Help!')
946
947 if options.printCsvfieldList:
948
949 if None == options.fieldList: options.fieldList = fieldList
950 import StringIO
951 buf = StringIO.StringIO()
952 for field in options.fieldList:
953 buf.write(field+',')
954 result = buf.getvalue()
955 if result[-1] == ',': print result[:-1]
956 else: print result
957
958 if options.doDecode:
959 for msg in args:
960 bv = None
961 if 'binary' == options.ioType: bv = BitVector(bitstring=msg)
962 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg)
963 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5])
964 else: sys.exit('ERROR: unknown ioType. Help!')
965
966 printFields(decode(bv),out=outfile,format=options.outputType,fieldList=options.fieldList)
967