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