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 -def encode(params, validate=False):
49 '''Create a sls_weatherreport binary message payload to pack into an AIS Msg sls_weatherreport.
50
51 Fields in params:
52 - time_month(uint): Time tag of measurement month 1..12
53 - time_day(uint): Time tag of measurement day of the month 1..31
54 - time_hour(uint): Time tag of measurement UTC hours 0..23
55 - time_min(uint): Time tag of measurement minutes
56 - stationid(aisstr6): Character identifier of the station
57 - pos_longitude(decimal): Location of measurement East West location
58 - pos_latitude(decimal): Location of measurement North South location
59 - speed(udecimal): Average wind speed
60 - gust(udecimal): Wind gust
61 - direction(uint): Wind direction
62 - atmpressure(udecimal): Atmospheric pressure
63 - airtemp(decimal): Air temperature
64 - dewpoint(decimal): Dew Point
65 - visibility(udecimal): Visibility
66 - watertemp(decimal): Water Temperature
67 - reserved(uint): Reserved bits for future use (field automatically set to "0")
68 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing
69 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
70 @rtype: BitVector
71 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8
72 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits.
73 '''
74
75 bvList = []
76 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_month']),4))
77 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_day']),5))
78 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_hour']),5))
79 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_min']),6))
80 if 'stationid' in params:
81 bvList.append(aisstring.encode(params['stationid'],42))
82 else:
83 bvList.append(aisstring.encode('@@@@@@@',42))
84 if 'pos_longitude' in params:
85 bvList.append(binary.bvFromSignedInt(int(Decimal(params['pos_longitude'])*Decimal('60000')),25))
86 else:
87 bvList.append(binary.bvFromSignedInt(10860000,25))
88 if 'pos_latitude' in params:
89 bvList.append(binary.bvFromSignedInt(int(Decimal(params['pos_latitude'])*Decimal('60000')),24))
90 else:
91 bvList.append(binary.bvFromSignedInt(5460000,24))
92 if 'speed' in params:
93 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['speed'])*Decimal('10')))),10))
94 else:
95 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(1023)),10))
96 if 'gust' in params:
97 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['gust'])*Decimal('10')))),10))
98 else:
99 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(1023)),10))
100 if 'direction' in params:
101 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['direction']),9))
102 else:
103 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9))
104 if 'atmpressure' in params:
105 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['atmpressure'])*Decimal('10')))),14))
106 else:
107 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(163830)),14))
108 if 'airtemp' in params:
109 bvList.append(binary.bvFromSignedInt(int(Decimal(params['airtemp'])*Decimal('10')),10))
110 else:
111 bvList.append(binary.bvFromSignedInt(-512,10))
112 if 'dewpoint' in params:
113 bvList.append(binary.bvFromSignedInt(int(Decimal(params['dewpoint'])*Decimal('10')),10))
114 else:
115 bvList.append(binary.bvFromSignedInt(-512,10))
116 if 'visibility' in params:
117 bvList.append(binary.setBitVectorSize(BitVector(intVal=int((Decimal(params['visibility'])*Decimal('10')))),8))
118 else:
119 bvList.append(binary.setBitVectorSize(BitVector(intVal=int(255)),8))
120 if 'watertemp' in params:
121 bvList.append(binary.bvFromSignedInt(int(Decimal(params['watertemp'])*Decimal('10')),10))
122 else:
123 bvList.append(binary.bvFromSignedInt(-512,10))
124 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),4))
125
126 return binary.joinBV(bvList)
127
128 -def decode(bv, validate=False):
129 '''Unpack a sls_weatherreport message
130
131 Fields in params:
132 - time_month(uint): Time tag of measurement month 1..12
133 - time_day(uint): Time tag of measurement day of the month 1..31
134 - time_hour(uint): Time tag of measurement UTC hours 0..23
135 - time_min(uint): Time tag of measurement minutes
136 - stationid(aisstr6): Character identifier of the station
137 - pos_longitude(decimal): Location of measurement East West location
138 - pos_latitude(decimal): Location of measurement North South location
139 - speed(udecimal): Average wind speed
140 - gust(udecimal): Wind gust
141 - direction(uint): Wind direction
142 - atmpressure(udecimal): Atmospheric pressure
143 - airtemp(decimal): Air temperature
144 - dewpoint(decimal): Dew Point
145 - visibility(udecimal): Visibility
146 - watertemp(decimal): Water Temperature
147 - reserved(uint): Reserved bits for future use (field automatically set to "0")
148 @type bv: BitVector
149 @param bv: Bits defining a message
150 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
151 @rtype: dict
152 @return: params
153 '''
154
155
156
157
158 r = {}
159 r['time_month']=int(bv[0:4])
160 r['time_day']=int(bv[4:9])
161 r['time_hour']=int(bv[9:14])
162 r['time_min']=int(bv[14:20])
163 r['stationid']=aisstring.decode(bv[20:62])
164 r['pos_longitude']=Decimal(binary.signedIntFromBV(bv[62:87]))/Decimal('60000')
165 r['pos_latitude']=Decimal(binary.signedIntFromBV(bv[87:111]))/Decimal('60000')
166 r['speed']=Decimal(int(bv[111:121]))/Decimal('10')
167 r['gust']=Decimal(int(bv[121:131]))/Decimal('10')
168 r['direction']=int(bv[131:140])
169 r['atmpressure']=Decimal(int(bv[140:154]))/Decimal('10')
170 r['airtemp']=Decimal(binary.signedIntFromBV(bv[154:164]))/Decimal('10')
171 r['dewpoint']=Decimal(binary.signedIntFromBV(bv[164:174]))/Decimal('10')
172 r['visibility']=Decimal(int(bv[174:182]))/Decimal('10')
173 r['watertemp']=Decimal(binary.signedIntFromBV(bv[182:192]))/Decimal('10')
174 r['reserved']=0
175 return r
176
179
182
185
187 return int(bv[14:20])
188
191
194
197
199 return Decimal(int(bv[111:121]))/Decimal('10')
200
202 return Decimal(int(bv[121:131]))/Decimal('10')
203
205 return int(bv[131:140])
206
208 return Decimal(int(bv[140:154]))/Decimal('10')
209
212
215
217 return Decimal(int(bv[174:182]))/Decimal('10')
218
221
223 return 0
224
225
227 out.write("<h3>sls_weatherreport<h3>\n")
228 out.write("<table border=\"1\">\n")
229 out.write("<tr bgcolor=\"orange\">\n")
230 out.write("<th align=\"left\">Field Name</th>\n")
231 out.write("<th align=\"left\">Type</th>\n")
232 out.write("<th align=\"left\">Value</th>\n")
233 out.write("<th align=\"left\">Value in Lookup Table</th>\n")
234 out.write("<th align=\"left\">Units</th>\n")
235 out.write("\n")
236 out.write("<tr>\n")
237 out.write("<td>time_month</td>\n")
238 out.write("<td>uint</td>\n")
239 if 'time_month' in params:
240 out.write(" <td>"+str(params['time_month'])+"</td>\n")
241 out.write(" <td>"+str(params['time_month'])+"</td>\n")
242 out.write("</tr>\n")
243 out.write("\n")
244 out.write("<tr>\n")
245 out.write("<td>time_day</td>\n")
246 out.write("<td>uint</td>\n")
247 if 'time_day' in params:
248 out.write(" <td>"+str(params['time_day'])+"</td>\n")
249 out.write(" <td>"+str(params['time_day'])+"</td>\n")
250 out.write("</tr>\n")
251 out.write("\n")
252 out.write("<tr>\n")
253 out.write("<td>time_hour</td>\n")
254 out.write("<td>uint</td>\n")
255 if 'time_hour' in params:
256 out.write(" <td>"+str(params['time_hour'])+"</td>\n")
257 out.write(" <td>"+str(params['time_hour'])+"</td>\n")
258 out.write("</tr>\n")
259 out.write("\n")
260 out.write("<tr>\n")
261 out.write("<td>time_min</td>\n")
262 out.write("<td>uint</td>\n")
263 if 'time_min' in params:
264 out.write(" <td>"+str(params['time_min'])+"</td>\n")
265 out.write(" <td>"+str(params['time_min'])+"</td>\n")
266 out.write("</tr>\n")
267 out.write("\n")
268 out.write("<tr>\n")
269 out.write("<td>stationid</td>\n")
270 out.write("<td>aisstr6</td>\n")
271 if 'stationid' in params:
272 out.write(" <td>"+str(params['stationid'])+"</td>\n")
273 out.write(" <td>"+str(params['stationid'])+"</td>\n")
274 out.write("</tr>\n")
275 out.write("\n")
276 out.write("<tr>\n")
277 out.write("<td>pos_longitude</td>\n")
278 out.write("<td>decimal</td>\n")
279 if 'pos_longitude' in params:
280 out.write(" <td>"+str(params['pos_longitude'])+"</td>\n")
281 out.write(" <td>"+str(params['pos_longitude'])+"</td>\n")
282 out.write("<td>degrees</td>\n")
283 out.write("</tr>\n")
284 out.write("\n")
285 out.write("<tr>\n")
286 out.write("<td>pos_latitude</td>\n")
287 out.write("<td>decimal</td>\n")
288 if 'pos_latitude' in params:
289 out.write(" <td>"+str(params['pos_latitude'])+"</td>\n")
290 out.write(" <td>"+str(params['pos_latitude'])+"</td>\n")
291 out.write("<td>degrees</td>\n")
292 out.write("</tr>\n")
293 out.write("\n")
294 out.write("<tr>\n")
295 out.write("<td>speed</td>\n")
296 out.write("<td>udecimal</td>\n")
297 if 'speed' in params:
298 out.write(" <td>"+str(params['speed'])+"</td>\n")
299 if str(params['speed']) in speedDecodeLut:
300 out.write("<td>"+speedDecodeLut[str(params['speed'])]+"</td>")
301 else:
302 out.write("<td><i>Missing LUT entry</i></td>")
303 out.write("<td>kts</td>\n")
304 out.write("</tr>\n")
305 out.write("\n")
306 out.write("<tr>\n")
307 out.write("<td>gust</td>\n")
308 out.write("<td>udecimal</td>\n")
309 if 'gust' in params:
310 out.write(" <td>"+str(params['gust'])+"</td>\n")
311 if str(params['gust']) in gustDecodeLut:
312 out.write("<td>"+gustDecodeLut[str(params['gust'])]+"</td>")
313 else:
314 out.write("<td><i>Missing LUT entry</i></td>")
315 out.write("<td>kts</td>\n")
316 out.write("</tr>\n")
317 out.write("\n")
318 out.write("<tr>\n")
319 out.write("<td>direction</td>\n")
320 out.write("<td>uint</td>\n")
321 if 'direction' in params:
322 out.write(" <td>"+str(params['direction'])+"</td>\n")
323 out.write(" <td>"+str(params['direction'])+"</td>\n")
324 out.write("<td>degrees</td>\n")
325 out.write("</tr>\n")
326 out.write("\n")
327 out.write("<tr>\n")
328 out.write("<td>atmpressure</td>\n")
329 out.write("<td>udecimal</td>\n")
330 if 'atmpressure' in params:
331 out.write(" <td>"+str(params['atmpressure'])+"</td>\n")
332 out.write(" <td>"+str(params['atmpressure'])+"</td>\n")
333 out.write("<td>millibars</td>\n")
334 out.write("</tr>\n")
335 out.write("\n")
336 out.write("<tr>\n")
337 out.write("<td>airtemp</td>\n")
338 out.write("<td>decimal</td>\n")
339 if 'airtemp' in params:
340 out.write(" <td>"+str(params['airtemp'])+"</td>\n")
341 if str(params['airtemp']) in airtempDecodeLut:
342 out.write("<td>"+airtempDecodeLut[str(params['airtemp'])]+"</td>")
343 else:
344 out.write("<td><i>Missing LUT entry</i></td>")
345 out.write("<td>Celsius</td>\n")
346 out.write("</tr>\n")
347 out.write("\n")
348 out.write("<tr>\n")
349 out.write("<td>dewpoint</td>\n")
350 out.write("<td>decimal</td>\n")
351 if 'dewpoint' in params:
352 out.write(" <td>"+str(params['dewpoint'])+"</td>\n")
353 if str(params['dewpoint']) in dewpointDecodeLut:
354 out.write("<td>"+dewpointDecodeLut[str(params['dewpoint'])]+"</td>")
355 else:
356 out.write("<td><i>Missing LUT entry</i></td>")
357 out.write("<td>Celsius</td>\n")
358 out.write("</tr>\n")
359 out.write("\n")
360 out.write("<tr>\n")
361 out.write("<td>visibility</td>\n")
362 out.write("<td>udecimal</td>\n")
363 if 'visibility' in params:
364 out.write(" <td>"+str(params['visibility'])+"</td>\n")
365 if str(params['visibility']) in visibilityDecodeLut:
366 out.write("<td>"+visibilityDecodeLut[str(params['visibility'])]+"</td>")
367 else:
368 out.write("<td><i>Missing LUT entry</i></td>")
369 out.write("<td>km</td>\n")
370 out.write("</tr>\n")
371 out.write("\n")
372 out.write("<tr>\n")
373 out.write("<td>watertemp</td>\n")
374 out.write("<td>decimal</td>\n")
375 if 'watertemp' in params:
376 out.write(" <td>"+str(params['watertemp'])+"</td>\n")
377 if str(params['watertemp']) in watertempDecodeLut:
378 out.write("<td>"+watertempDecodeLut[str(params['watertemp'])]+"</td>")
379 else:
380 out.write("<td><i>Missing LUT entry</i></td>")
381 out.write("<td>Celsius</td>\n")
382 out.write("</tr>\n")
383 out.write("\n")
384 out.write("<tr>\n")
385 out.write("<td>reserved</td>\n")
386 out.write("<td>uint</td>\n")
387 if 'reserved' in params:
388 out.write(" <td>"+str(params['reserved'])+"</td>\n")
389 out.write(" <td>"+str(params['reserved'])+"</td>\n")
390 out.write("</tr>\n")
391 out.write("</table>\n")
392
394 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer'''
395 out.write("\ <Placemark>\n")
396 out.write("\t <name>"+str(params['stationid'])+"</name>\n")
397 out.write("\t\t<description>\n")
398 import StringIO
399 buf = StringIO.StringIO()
400 printHtml(params,buf)
401 import cgi
402 out.write(cgi.escape(buf.getvalue()))
403 out.write("\t\t</description>\n")
404 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n")
405 out.write("\t\t<Point>\n")
406 out.write("\t\t\t<coordinates>")
407 out.write(str(params['pos_longitude']))
408 out.write(',')
409 out.write(str(params['pos_latitude']))
410 out.write(",0</coordinates>\n")
411 out.write("\t\t</Point>\n")
412 out.write("\t</Placemark>\n")
413
415 '''Print a reserved message to stdout.
416
417 Fields in params:
418 - time_month(uint): Time tag of measurement month 1..12
419 - time_day(uint): Time tag of measurement day of the month 1..31
420 - time_hour(uint): Time tag of measurement UTC hours 0..23
421 - time_min(uint): Time tag of measurement minutes
422 - stationid(aisstr6): Character identifier of the station
423 - pos_longitude(decimal): Location of measurement East West location
424 - pos_latitude(decimal): Location of measurement North South location
425 - speed(udecimal): Average wind speed
426 - gust(udecimal): Wind gust
427 - direction(uint): Wind direction
428 - atmpressure(udecimal): Atmospheric pressure
429 - airtemp(decimal): Air temperature
430 - dewpoint(decimal): Dew Point
431 - visibility(udecimal): Visibility
432 - watertemp(decimal): Water Temperature
433 - reserved(uint): Reserved bits for future use (field automatically set to "0")
434 @param params: Dictionary of field names/values.
435 @param out: File like object to write to
436 @rtype: stdout
437 @return: text to out
438 '''
439
440 if 'std'==format:
441 out.write("reserved:\n")
442 if 'time_month' in params: out.write(" time_month: "+str(params['time_month'])+"\n")
443 if 'time_day' in params: out.write(" time_day: "+str(params['time_day'])+"\n")
444 if 'time_hour' in params: out.write(" time_hour: "+str(params['time_hour'])+"\n")
445 if 'time_min' in params: out.write(" time_min: "+str(params['time_min'])+"\n")
446 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n")
447 if 'pos_longitude' in params: out.write(" pos_longitude: "+str(params['pos_longitude'])+"\n")
448 if 'pos_latitude' in params: out.write(" pos_latitude: "+str(params['pos_latitude'])+"\n")
449 if 'speed' in params: out.write(" speed: "+str(params['speed'])+"\n")
450 if 'gust' in params: out.write(" gust: "+str(params['gust'])+"\n")
451 if 'direction' in params: out.write(" direction: "+str(params['direction'])+"\n")
452 if 'atmpressure' in params: out.write(" atmpressure: "+str(params['atmpressure'])+"\n")
453 if 'airtemp' in params: out.write(" airtemp: "+str(params['airtemp'])+"\n")
454 if 'dewpoint' in params: out.write(" dewpoint: "+str(params['dewpoint'])+"\n")
455 if 'visibility' in params: out.write(" visibility: "+str(params['visibility'])+"\n")
456 if 'watertemp' in params: out.write(" watertemp: "+str(params['watertemp'])+"\n")
457 if 'reserved' in params: out.write(" reserved: "+str(params['reserved'])+"\n")
458 elif 'html'==format:
459 printHtml(params,out)
460 elif 'kml'==format:
461 printKml(params,out)
462 elif 'kml-full'==format:
463 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
464 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n")
465 out.write("<Document>\n")
466 out.write(" <name>Position</name>\n")
467 printKml(params,out)
468 out.write("</Document>\n")
469 out.write("</kml>\n")
470 else:
471 print "ERROR: unknown format:",format
472 assert False
473
474 return
475
476 speedEncodeLut = {
477 '102.2 kts or greater':'102.2',
478 }
479
480 speedDecodeLut = {
481 '102.2':'102.2 kts or greater',
482 }
483
484 gustEncodeLut = {
485 '102.2 kts or greater':'102.2',
486 }
487
488 gustDecodeLut = {
489 '102.2':'102.2 kts or greater',
490 }
491
492 airtempEncodeLut = {
493 '-51.1 degrees C or lower':'-51.1',
494 '51.1 degrees C or greater':'51.1',
495 }
496
497 airtempDecodeLut = {
498 '-51.1':'-51.1 degrees C or lower',
499 '51.1':'51.1 degrees C or greater',
500 }
501
502 dewpointEncodeLut = {
503 '-51.1 degrees C or lower':'-51.1',
504 '51.1 degrees C or greater':'51.1',
505 }
506
507 dewpointDecodeLut = {
508 '-51.1':'-51.1 degrees C or lower',
509 '51.1':'51.1 degrees C or greater',
510 }
511
512 visibilityEncodeLut = {
513 '25.4 km or greater':'25.4',
514 }
515
516 visibilityDecodeLut = {
517 '25.4':'25.4 km or greater',
518 }
519
520 watertempEncodeLut = {
521 '-51.1 degrees C or lower':'-51.1',
522 '51.1 degrees C or greater':'51.1',
523 }
524
525 watertempDecodeLut = {
526 '-51.1':'-51.1 degrees C or lower',
527 '51.1':'51.1 degrees C or greater',
528 }
529
530
531
532
533
534
535 import unittest
537 '''Return a params file base on the testvalue tags.
538 @rtype: dict
539 @return: params based on testvalue tags
540 '''
541 params = {}
542 params['time_month'] = 2
543 params['time_day'] = 28
544 params['time_hour'] = 23
545 params['time_min'] = 45
546 params['stationid'] = 'A345678'
547 params['pos_longitude'] = Decimal('-122.16328')
548 params['pos_latitude'] = Decimal('37.42446')
549 params['speed'] = Decimal('0.7')
550 params['gust'] = Decimal('0.7')
551 params['direction'] = 41
552 params['atmpressure'] = Decimal('0.7')
553 params['airtemp'] = Decimal('-8')
554 params['dewpoint'] = Decimal('-7')
555 params['visibility'] = Decimal('12.3')
556 params['watertemp'] = Decimal('-0.2')
557 params['reserved'] = 0
558
559 return params
560
562 '''Use testvalue tag text from each type to build test case the sls_weatherreport message'''
564
565 params = testParams()
566 bits = encode(params)
567 r = decode(bits)
568
569
570 self.failUnlessEqual(r['time_month'],params['time_month'])
571 self.failUnlessEqual(r['time_day'],params['time_day'])
572 self.failUnlessEqual(r['time_hour'],params['time_hour'])
573 self.failUnlessEqual(r['time_min'],params['time_min'])
574 self.failUnlessEqual(r['stationid'],params['stationid'])
575 self.failUnlessAlmostEqual(r['pos_longitude'],params['pos_longitude'],4)
576 self.failUnlessAlmostEqual(r['pos_latitude'],params['pos_latitude'],4)
577 self.failUnlessAlmostEqual(r['speed'],params['speed'],3)
578 self.failUnlessAlmostEqual(r['gust'],params['gust'],3)
579 self.failUnlessEqual(r['direction'],params['direction'])
580 self.failUnlessAlmostEqual(r['atmpressure'],params['atmpressure'],3)
581 self.failUnlessAlmostEqual(r['airtemp'],params['airtemp'],3)
582 self.failUnlessAlmostEqual(r['dewpoint'],params['dewpoint'],3)
583 self.failUnlessAlmostEqual(r['visibility'],params['visibility'],3)
584 self.failUnlessAlmostEqual(r['watertemp'],params['watertemp'],3)
585 self.failUnlessEqual(r['reserved'],params['reserved'])
586
588 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true',
589 help='decode a "sls_weatherreport" AIS message')
590 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true',
591 help='encode a "sls_weatherreport" AIS message')
592 parser.add_option('--time_month-field', dest='time_monthField',metavar='uint',type='int'
593 ,help='Field parameter value [default: %default]')
594 parser.add_option('--time_day-field', dest='time_dayField',metavar='uint',type='int'
595 ,help='Field parameter value [default: %default]')
596 parser.add_option('--time_hour-field', dest='time_hourField',metavar='uint',type='int'
597 ,help='Field parameter value [default: %default]')
598 parser.add_option('--time_min-field', dest='time_minField',metavar='uint',type='int'
599 ,help='Field parameter value [default: %default]')
600 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string'
601 ,help='Field parameter value [default: %default]')
602 parser.add_option('--pos_longitude-field', dest='pos_longitudeField',default=Decimal('181'),metavar='decimal',type='string'
603 ,help='Field parameter value [default: %default]')
604 parser.add_option('--pos_latitude-field', dest='pos_latitudeField',default=Decimal('91'),metavar='decimal',type='string'
605 ,help='Field parameter value [default: %default]')
606 parser.add_option('--speed-field', dest='speedField',default=Decimal('102.3'),metavar='udecimal',type='string'
607 ,help='Field parameter value [default: %default]')
608 parser.add_option('--gust-field', dest='gustField',default=Decimal('102.3'),metavar='udecimal',type='string'
609 ,help='Field parameter value [default: %default]')
610 parser.add_option('--direction-field', dest='directionField',default=511,metavar='uint',type='int'
611 ,help='Field parameter value [default: %default]')
612 parser.add_option('--atmpressure-field', dest='atmpressureField',default=Decimal('16383'),metavar='udecimal',type='string'
613 ,help='Field parameter value [default: %default]')
614 parser.add_option('--airtemp-field', dest='airtempField',default=Decimal('-51.2'),metavar='decimal',type='string'
615 ,help='Field parameter value [default: %default]')
616 parser.add_option('--dewpoint-field', dest='dewpointField',default=Decimal('-51.2'),metavar='decimal',type='string'
617 ,help='Field parameter value [default: %default]')
618 parser.add_option('--visibility-field', dest='visibilityField',default=Decimal('25.5'),metavar='udecimal',type='string'
619 ,help='Field parameter value [default: %default]')
620 parser.add_option('--watertemp-field', dest='watertempField',default=Decimal('-51.2'),metavar='decimal',type='string'
621 ,help='Field parameter value [default: %default]')
622
623
624 if __name__=='__main__':
625
626 from optparse import OptionParser
627 parser = OptionParser(usage="%prog [options]",
628 version="%prog "+__version__)
629
630 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true',
631 help='run the documentation tests')
632 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true',
633 help='run the unit tests')
634 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true',
635 help='Make the test output verbose')
636
637
638
639 typeChoices = ('binary','nmeapayload','nmea')
640 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType'
641 ,default='nmeapayload'
642 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]')
643
644
645 outputChoices = ('std','html','xml' , 'kml','kml-full')
646 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType'
647 ,default='std'
648 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]')
649
650 parser.add_option('-o','--output',dest='outputFileName',default=None,
651 help='Name of the python file to write [default: stdout]')
652
653 addMsgOptions(parser)
654
655 (options,args) = parser.parse_args()
656 success=True
657
658 if options.doctest:
659 import os; print os.path.basename(sys.argv[0]), 'doctests ...',
660 sys.argv= [sys.argv[0]]
661 if options.verbose: sys.argv.append('-v')
662 import doctest
663 numfail,numtests=doctest.testmod()
664 if numfail==0: print 'ok'
665 else:
666 print 'FAILED'
667 success=False
668
669 if not success: sys.exit('Something Failed')
670 del success
671
672 if options.unittest:
673 sys.argv = [sys.argv[0]]
674 if options.verbose: sys.argv.append('-v')
675 unittest.main()
676
677 outfile = sys.stdout
678 if None!=options.outputFileName:
679 outfile = file(options.outputFileName,'w')
680
681
682 if options.doEncode:
683
684 if None==options.time_monthField: parser.error("missing value for time_monthField")
685 if None==options.time_dayField: parser.error("missing value for time_dayField")
686 if None==options.time_hourField: parser.error("missing value for time_hourField")
687 if None==options.time_minField: parser.error("missing value for time_minField")
688 if None==options.stationidField: parser.error("missing value for stationidField")
689 if None==options.pos_longitudeField: parser.error("missing value for pos_longitudeField")
690 if None==options.pos_latitudeField: parser.error("missing value for pos_latitudeField")
691 if None==options.speedField: parser.error("missing value for speedField")
692 if None==options.gustField: parser.error("missing value for gustField")
693 if None==options.directionField: parser.error("missing value for directionField")
694 if None==options.atmpressureField: parser.error("missing value for atmpressureField")
695 if None==options.airtempField: parser.error("missing value for airtempField")
696 if None==options.dewpointField: parser.error("missing value for dewpointField")
697 if None==options.visibilityField: parser.error("missing value for visibilityField")
698 if None==options.watertempField: parser.error("missing value for watertempField")
699 msgDict={
700 'time_month': options.time_monthField,
701 'time_day': options.time_dayField,
702 'time_hour': options.time_hourField,
703 'time_min': options.time_minField,
704 'stationid': options.stationidField,
705 'pos_longitude': options.pos_longitudeField,
706 'pos_latitude': options.pos_latitudeField,
707 'speed': options.speedField,
708 'gust': options.gustField,
709 'direction': options.directionField,
710 'atmpressure': options.atmpressureField,
711 'airtemp': options.airtempField,
712 'dewpoint': options.dewpointField,
713 'visibility': options.visibilityField,
714 'watertemp': options.watertempField,
715 'reserved': '0',
716 }
717
718 bits = encode(msgDict)
719 if 'binary'==options.ioType: print str(bits)
720 elif 'nmeapayload'==options.ioType:
721
722 print "bitLen",len(bits)
723 bitLen=len(bits)
724 if bitLen%6!=0:
725 bits = bits + BitVector(size=(6 - (bitLen%6)))
726 print "result:",binary.bitvectoais6(bits)[0]
727
728
729
730 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability")
731 else: sys.exit('ERROR: unknown ioType. Help!')
732
733 if options.doDecode:
734 for msg in args:
735 bv = None
736 if 'binary' == options.ioType: bv = BitVector(bitstring=msg)
737 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg)
738 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5])
739 else: sys.exit('ERROR: unknown ioType. Help!')
740
741 printFields(decode(bv),out=outfile,format=options.outputType)
742