1
2
3 __version__ = '$Revision: 4791 $'.split()[1]
4 __date__ = '$Date: 2007-04-07 $'.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 'time_month',
51 'time_day',
52 'time_hour',
53 'time_min',
54 'stationid',
55 'pos_longitude',
56 'pos_latitude',
57 'flow',
58 'reserved',
59 )
60
61 fieldListPostgres = (
62 'time_month',
63 'time_day',
64 'time_hour',
65 'time_min',
66 'stationid',
67 'pos',
68 'flow',
69 'reserved',
70 )
71
72 toPgFields = {
73 'pos_longitude':'pos',
74 'pos_latitude':'pos',
75 }
76 '''
77 Go to the Postgis field names from the straight field name
78 '''
79
80 fromPgFields = {
81 'pos':('pos_longitude','pos_latitude',),
82 }
83 '''
84 Go from the Postgis field names to the straight field name
85 '''
86
87 pgTypes = {
88 'pos':'POINT',
89 }
90 '''
91 Lookup table for each postgis field name to get its type.
92 '''
93
94 -def encode(params, validate=False):
95 '''Create a sls_wind binary message payload to pack into an AIS Msg sls_wind.
96
97 Fields in params:
98 - time_month(uint): Time tag of measurement month 1..12
99 - time_day(uint): Time tag of measurement day of the month 1..31
100 - time_hour(uint): Time tag of measurement UTC hours 0..23
101 - time_min(uint): Time tag of measurement minutes
102 - stationid(aisstr6): Character identifier of the station
103 - pos_longitude(decimal): Location of measurement East West location
104 - pos_latitude(decimal): Location of measurement North South location
105 - flow(uint): Water flow
106 - reserved(uint): Reserved bits for future use (field automatically set to "0")
107 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing
108 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
109 @rtype: BitVector
110 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8
111 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits.
112 '''
113
114 bvList = []
115 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_month']),4))
116 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_day']),5))
117 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_hour']),5))
118 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['time_min']),6))
119 if 'stationid' in params:
120 bvList.append(aisstring.encode(params['stationid'],42))
121 else:
122 bvList.append(aisstring.encode('@@@@@@@',42))
123 if 'pos_longitude' in params:
124 bvList.append(binary.bvFromSignedInt(int(Decimal(params['pos_longitude'])*Decimal('60000')),25))
125 else:
126 bvList.append(binary.bvFromSignedInt(10860000,25))
127 if 'pos_latitude' in params:
128 bvList.append(binary.bvFromSignedInt(int(Decimal(params['pos_latitude'])*Decimal('60000')),24))
129 else:
130 bvList.append(binary.bvFromSignedInt(5460000,24))
131 if 'flow' in params:
132 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['flow']),10))
133 else:
134 bvList.append(binary.setBitVectorSize(BitVector(intVal=16383),10))
135 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),19))
136
137 return binary.joinBV(bvList)
138
139 -def decode(bv, validate=False):
140 '''Unpack a sls_wind message
141
142 Fields in params:
143 - time_month(uint): Time tag of measurement month 1..12
144 - time_day(uint): Time tag of measurement day of the month 1..31
145 - time_hour(uint): Time tag of measurement UTC hours 0..23
146 - time_min(uint): Time tag of measurement minutes
147 - stationid(aisstr6): Character identifier of the station
148 - pos_longitude(decimal): Location of measurement East West location
149 - pos_latitude(decimal): Location of measurement North South location
150 - flow(uint): Water flow
151 - reserved(uint): Reserved bits for future use (field automatically set to "0")
152 @type bv: BitVector
153 @param bv: Bits defining a message
154 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
155 @rtype: dict
156 @return: params
157 '''
158
159
160
161
162 r = {}
163 r['time_month']=int(bv[0:4])
164 r['time_day']=int(bv[4:9])
165 r['time_hour']=int(bv[9:14])
166 r['time_min']=int(bv[14:20])
167 r['stationid']=aisstring.decode(bv[20:62])
168 r['pos_longitude']=Decimal(binary.signedIntFromBV(bv[62:87]))/Decimal('60000')
169 r['pos_latitude']=Decimal(binary.signedIntFromBV(bv[87:111]))/Decimal('60000')
170 r['flow']=int(bv[111:121])
171 r['reserved']=0
172 return r
173
176
179
182
184 return int(bv[14:20])
185
188
191
194
196 return int(bv[111:121])
197
200
201
203 out.write("<h3>sls_wind<h3>\n")
204 out.write("<table border=\"1\">\n")
205 out.write("<tr bgcolor=\"orange\">\n")
206 out.write("<th align=\"left\">Field Name</th>\n")
207 out.write("<th align=\"left\">Type</th>\n")
208 out.write("<th align=\"left\">Value</th>\n")
209 out.write("<th align=\"left\">Value in Lookup Table</th>\n")
210 out.write("<th align=\"left\">Units</th>\n")
211 out.write("\n")
212 out.write("<tr>\n")
213 out.write("<td>time_month</td>\n")
214 out.write("<td>uint</td>\n")
215 if 'time_month' in params:
216 out.write(" <td>"+str(params['time_month'])+"</td>\n")
217 out.write(" <td>"+str(params['time_month'])+"</td>\n")
218 out.write("</tr>\n")
219 out.write("\n")
220 out.write("<tr>\n")
221 out.write("<td>time_day</td>\n")
222 out.write("<td>uint</td>\n")
223 if 'time_day' in params:
224 out.write(" <td>"+str(params['time_day'])+"</td>\n")
225 out.write(" <td>"+str(params['time_day'])+"</td>\n")
226 out.write("</tr>\n")
227 out.write("\n")
228 out.write("<tr>\n")
229 out.write("<td>time_hour</td>\n")
230 out.write("<td>uint</td>\n")
231 if 'time_hour' in params:
232 out.write(" <td>"+str(params['time_hour'])+"</td>\n")
233 out.write(" <td>"+str(params['time_hour'])+"</td>\n")
234 out.write("</tr>\n")
235 out.write("\n")
236 out.write("<tr>\n")
237 out.write("<td>time_min</td>\n")
238 out.write("<td>uint</td>\n")
239 if 'time_min' in params:
240 out.write(" <td>"+str(params['time_min'])+"</td>\n")
241 out.write(" <td>"+str(params['time_min'])+"</td>\n")
242 out.write("</tr>\n")
243 out.write("\n")
244 out.write("<tr>\n")
245 out.write("<td>stationid</td>\n")
246 out.write("<td>aisstr6</td>\n")
247 if 'stationid' in params:
248 out.write(" <td>"+str(params['stationid'])+"</td>\n")
249 out.write(" <td>"+str(params['stationid'])+"</td>\n")
250 out.write("</tr>\n")
251 out.write("\n")
252 out.write("<tr>\n")
253 out.write("<td>pos_longitude</td>\n")
254 out.write("<td>decimal</td>\n")
255 if 'pos_longitude' in params:
256 out.write(" <td>"+str(params['pos_longitude'])+"</td>\n")
257 out.write(" <td>"+str(params['pos_longitude'])+"</td>\n")
258 out.write("<td>degrees</td>\n")
259 out.write("</tr>\n")
260 out.write("\n")
261 out.write("<tr>\n")
262 out.write("<td>pos_latitude</td>\n")
263 out.write("<td>decimal</td>\n")
264 if 'pos_latitude' in params:
265 out.write(" <td>"+str(params['pos_latitude'])+"</td>\n")
266 out.write(" <td>"+str(params['pos_latitude'])+"</td>\n")
267 out.write("<td>degrees</td>\n")
268 out.write("</tr>\n")
269 out.write("\n")
270 out.write("<tr>\n")
271 out.write("<td>flow</td>\n")
272 out.write("<td>uint</td>\n")
273 if 'flow' in params:
274 out.write(" <td>"+str(params['flow'])+"</td>\n")
275 out.write(" <td>"+str(params['flow'])+"</td>\n")
276 out.write("<td>m^3/s</td>\n")
277 out.write("</tr>\n")
278 out.write("\n")
279 out.write("<tr>\n")
280 out.write("<td>reserved</td>\n")
281 out.write("<td>uint</td>\n")
282 if 'reserved' in params:
283 out.write(" <td>"+str(params['reserved'])+"</td>\n")
284 out.write(" <td>"+str(params['reserved'])+"</td>\n")
285 out.write("</tr>\n")
286 out.write("</table>\n")
287
288
290 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer'''
291 out.write("\ <Placemark>\n")
292 out.write("\t <name>"+str(params['stationid'])+"</name>\n")
293 out.write("\t\t<description>\n")
294 import StringIO
295 buf = StringIO.StringIO()
296 printHtml(params,buf)
297 import cgi
298 out.write(cgi.escape(buf.getvalue()))
299 out.write("\t\t</description>\n")
300 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n")
301 out.write("\t\t<Point>\n")
302 out.write("\t\t\t<coordinates>")
303 out.write(str(params['pos_longitude']))
304 out.write(',')
305 out.write(str(params['pos_latitude']))
306 out.write(",0</coordinates>\n")
307 out.write("\t\t</Point>\n")
308 out.write("\t</Placemark>\n")
309
310 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'):
311 '''Print a sls_wind message to stdout.
312
313 Fields in params:
314 - time_month(uint): Time tag of measurement month 1..12
315 - time_day(uint): Time tag of measurement day of the month 1..31
316 - time_hour(uint): Time tag of measurement UTC hours 0..23
317 - time_min(uint): Time tag of measurement minutes
318 - stationid(aisstr6): Character identifier of the station
319 - pos_longitude(decimal): Location of measurement East West location
320 - pos_latitude(decimal): Location of measurement North South location
321 - flow(uint): Water flow
322 - reserved(uint): Reserved bits for future use (field automatically set to "0")
323 @param params: Dictionary of field names/values.
324 @param out: File like object to write to
325 @rtype: stdout
326 @return: text to out
327 '''
328
329 if 'std'==format:
330 out.write("sls_wind:\n")
331 if 'time_month' in params: out.write(" time_month: "+str(params['time_month'])+"\n")
332 if 'time_day' in params: out.write(" time_day: "+str(params['time_day'])+"\n")
333 if 'time_hour' in params: out.write(" time_hour: "+str(params['time_hour'])+"\n")
334 if 'time_min' in params: out.write(" time_min: "+str(params['time_min'])+"\n")
335 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n")
336 if 'pos_longitude' in params: out.write(" pos_longitude: "+str(params['pos_longitude'])+"\n")
337 if 'pos_latitude' in params: out.write(" pos_latitude: "+str(params['pos_latitude'])+"\n")
338 if 'flow' in params: out.write(" flow: "+str(params['flow'])+"\n")
339 if 'reserved' in params: out.write(" reserved: "+str(params['reserved'])+"\n")
340 elif 'csv'==format:
341 if None == options.fieldList:
342 options.fieldList = fieldList
343 needComma = False;
344 for field in fieldList:
345 if needComma: out.write(',')
346 needComma = True
347 if field in params:
348 out.write(str(params[field]))
349
350 out.write("\n")
351 elif 'html'==format:
352 printHtml(params,out)
353 elif 'sql'==format:
354 sqlInsertStr(params,out,dbType=dbType)
355 elif 'kml'==format:
356 printKml(params,out)
357 elif 'kml-full'==format:
358 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
359 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n")
360 out.write("<Document>\n")
361 out.write(" <name>sls_wind</name>\n")
362 printKml(params,out)
363 out.write("</Document>\n")
364 out.write("</kml>\n")
365 else:
366 print "ERROR: unknown format:",format
367 assert False
368
369 return
370
371
372
373
374
375 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None
376 ,addCoastGuardFields=True
377 ,dbType='postgres'
378 ):
379 '''
380 Return the SQL CREATE command for this message type
381 @param outfile: file like object to print to.
382 @param fields: which fields to put in the create. Defaults to all.
383 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields
384 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format
385 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres')
386 @type addCoastGuardFields: bool
387 @return: sql create string
388 @rtype: str
389
390 @see: sqlCreate
391 '''
392
393 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
394
395 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
396 '''
397 Return the sqlhelp object to create the table.
398
399 @param fields: which fields to put in the create. Defaults to all.
400 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields
401 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format
402 @type addCoastGuardFields: bool
403 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres')
404 @return: An object that can be used to generate a return
405 @rtype: sqlhelp.create
406 '''
407 if None == fields: fields = fieldList
408 import sqlhelp
409 c = sqlhelp.create('sls_wind',dbType=dbType)
410 c.addPrimaryKey()
411 if 'time_month' in fields: c.addInt ('time_month')
412 if 'time_day' in fields: c.addInt ('time_day')
413 if 'time_hour' in fields: c.addInt ('time_hour')
414 if 'time_min' in fields: c.addInt ('time_min')
415 if 'stationid' in fields: c.addVarChar('stationid',7)
416 if dbType != 'postgres':
417 if 'pos_longitude' in fields: c.addDecimal('pos_longitude',7,4)
418 if dbType != 'postgres':
419 if 'pos_latitude' in fields: c.addDecimal('pos_latitude',7,4)
420 if 'flow' in fields: c.addInt ('flow')
421 if 'reserved' in fields: c.addInt ('reserved')
422
423 if addCoastGuardFields:
424
425
426
427
428
429 c.addVarChar('cg_r',15)
430 c.addInt('cg_sec')
431
432 c.addTimestamp('cg_timestamp')
433
434 if dbType == 'postgres':
435 c.addPostGIS('pos','POINT',2);
436
437 return c
438
439 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
440 '''
441 Return the SQL INSERT command for this message type
442 @param params: dictionary of values keyed by field name
443 @param outfile: file like object to print to.
444 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields
445 @return: sql create string
446 @rtype: str
447
448 @see: sqlCreate
449 '''
450 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
451
452
453 -def sqlInsert(params,extraParams=None,dbType='postgres'):
454 '''
455 Give the SQL INSERT statement
456 @param params: dict keyed by field name of values
457 @param extraParams: any extra fields that you have created beyond the normal ais message fields
458 @rtype: sqlhelp.insert
459 @return: insert class instance
460 @todo: allow optional type checking of params?
461 @warning: this will take invalid keys happily and do what???
462 '''
463 import sqlhelp
464 i = sqlhelp.insert('sls_wind',dbType=dbType)
465
466 if dbType=='postgres':
467 finished = []
468 for key in params:
469 if key in finished:
470 continue
471
472 if key not in toPgFields and key not in fromPgFields:
473 if type(params[key])==Decimal: i.add(key,float(params[key]))
474 else: i.add(key,params[key])
475 else:
476 if key in fromPgFields:
477 val = params[key]
478
479 i.addPostGIS(key,val)
480 finished.append(key)
481 else:
482
483 pgName = toPgFields[key]
484
485 valStr=pgTypes[pgName]+'('
486 vals = []
487 for nonPgKey in fromPgFields[pgName]:
488 vals.append(str(params[nonPgKey]))
489 finished.append(nonPgKey)
490 valStr+=' '.join(vals)+')'
491 i.addPostGIS(pgName,valStr)
492 else:
493 for key in params:
494 if type(params[key])==Decimal: i.add(key,float(params[key]))
495 else: i.add(key,params[key])
496
497 if None != extraParams:
498 for key in extraParams:
499 i.add(key,extraParams[key])
500
501 return i
502
503
504
505
506
509 '''
510 Return the LaTeX definition table for this message type
511 @param outfile: file like object to print to.
512 @type outfile: file obj
513 @return: LaTeX table string via the outfile
514 @rtype: str
515
516 '''
517 o = outfile
518
519 o.write('''
520 \\begin{table}%[htb]
521 \\centering
522 \\begin{tabular}{|l|c|l|}
523 \\hline
524 Parameter & Number of bits & Description
525 \\\\ \\hline\\hline
526 time\_month & 4 & Time tag of measurement month 1..12 \\\\ \hline
527 time\_day & 5 & Time tag of measurement day of the month 1..31 \\\\ \hline
528 time\_hour & 5 & Time tag of measurement UTC hours 0..23 \\\\ \hline
529 time\_min & 6 & Time tag of measurement minutes \\\\ \hline
530 stationid & 42 & Character identifier of the station \\\\ \hline
531 pos\_longitude & 25 & Location of measurement East West location \\\\ \hline
532 pos\_latitude & 24 & Location of measurement North South location \\\\ \hline
533 flow & 10 & Water flow \\\\ \hline
534 reserved & 19 & Reserved bits for future use\\\\ \\hline \\hline
535 Total bits & 140 & Appears to take 1 slot with 28 pad bits to fill the last slot \\\\ \\hline
536 \\end{tabular}
537 \\caption{AIS message number 8: St Lawrance Seaway wind information}
538 \\label{tab:sls_wind}
539 \\end{table}
540 ''')
541
542
543
544
545
546 -def textDefinitionTable(outfile=sys.stdout
547 ,delim='\t'
548 ):
549 '''
550 Return the text definition table for this message type
551 @param outfile: file like object to print to.
552 @type outfile: file obj
553 @return: text table string via the outfile
554 @rtype: str
555
556 '''
557 o = outfile
558 o.write('''Parameter'''+delim+'Number of bits'''+delim+'''Description
559 time_month'''+delim+'''4'''+delim+'''Time tag of measurement month 1..12
560 time_day'''+delim+'''5'''+delim+'''Time tag of measurement day of the month 1..31
561 time_hour'''+delim+'''5'''+delim+'''Time tag of measurement UTC hours 0..23
562 time_min'''+delim+'''6'''+delim+'''Time tag of measurement minutes
563 stationid'''+delim+'''42'''+delim+'''Character identifier of the station
564 pos_longitude'''+delim+'''25'''+delim+'''Location of measurement East West location
565 pos_latitude'''+delim+'''24'''+delim+'''Location of measurement North South location
566 flow'''+delim+'''10'''+delim+'''Water flow
567 reserved'''+delim+'''19'''+delim+'''Reserved bits for future use
568 Total bits'''+delim+'''140'''+delim+'''Appears to take 1 slot with 28 pad bits to fill the last slot''')
569
570
571
572
573
574 import unittest
576 '''Return a params file base on the testvalue tags.
577 @rtype: dict
578 @return: params based on testvalue tags
579 '''
580 params = {}
581 params['time_month'] = 2
582 params['time_day'] = 28
583 params['time_hour'] = 23
584 params['time_min'] = 45
585 params['stationid'] = 'A345678'
586 params['pos_longitude'] = Decimal('-122.16328')
587 params['pos_latitude'] = Decimal('37.42446')
588 params['flow'] = 43
589 params['reserved'] = 0
590
591 return params
592
594 '''Use testvalue tag text from each type to build test case the sls_wind message'''
596
597 params = testParams()
598 bits = encode(params)
599 r = decode(bits)
600
601
602 self.failUnlessEqual(r['time_month'],params['time_month'])
603 self.failUnlessEqual(r['time_day'],params['time_day'])
604 self.failUnlessEqual(r['time_hour'],params['time_hour'])
605 self.failUnlessEqual(r['time_min'],params['time_min'])
606 self.failUnlessEqual(r['stationid'],params['stationid'])
607 self.failUnlessAlmostEqual(r['pos_longitude'],params['pos_longitude'],4)
608 self.failUnlessAlmostEqual(r['pos_latitude'],params['pos_latitude'],4)
609 self.failUnlessEqual(r['flow'],params['flow'])
610 self.failUnlessEqual(r['reserved'],params['reserved'])
611
613 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true',
614 help='decode a "sls_wind" AIS message')
615 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true',
616 help='encode a "sls_wind" AIS message')
617 parser.add_option('--time_month-field', dest='time_monthField',metavar='uint',type='int'
618 ,help='Field parameter value [default: %default]')
619 parser.add_option('--time_day-field', dest='time_dayField',metavar='uint',type='int'
620 ,help='Field parameter value [default: %default]')
621 parser.add_option('--time_hour-field', dest='time_hourField',metavar='uint',type='int'
622 ,help='Field parameter value [default: %default]')
623 parser.add_option('--time_min-field', dest='time_minField',metavar='uint',type='int'
624 ,help='Field parameter value [default: %default]')
625 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string'
626 ,help='Field parameter value [default: %default]')
627 parser.add_option('--pos_longitude-field', dest='pos_longitudeField',default=Decimal('181'),metavar='decimal',type='string'
628 ,help='Field parameter value [default: %default]')
629 parser.add_option('--pos_latitude-field', dest='pos_latitudeField',default=Decimal('91'),metavar='decimal',type='string'
630 ,help='Field parameter value [default: %default]')
631 parser.add_option('--flow-field', dest='flowField',default=16383,metavar='uint',type='int'
632 ,help='Field parameter value [default: %default]')
633
634
635 if __name__=='__main__':
636
637 from optparse import OptionParser
638 parser = OptionParser(usage="%prog [options]",
639 version="%prog "+__version__)
640
641 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true',
642 help='run the documentation tests')
643 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true',
644 help='run the unit tests')
645 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true',
646 help='Make the test output verbose')
647
648
649
650 typeChoices = ('binary','nmeapayload','nmea')
651 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType'
652 ,default='nmeapayload'
653 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]')
654
655
656 outputChoices = ('std','html','csv','sql' , 'kml','kml-full')
657 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType'
658 ,default='std'
659 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]')
660
661 parser.add_option('-o','--output',dest='outputFileName',default=None,
662 help='Name of the python file to write [default: stdout]')
663
664 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append',
665 choices=fieldList,
666 help='Which fields to include in the output. Currently only for csv output [default: all]')
667
668 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true',
669 help='Print the field name for csv')
670
671 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true',
672 help='Print out an sql create command for the table.')
673
674 parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true',
675 help='Print a LaTeX table of the type')
676
677 parser.add_option('--text-table',dest='textDefinitionTable',default=False,action='store_true',
678 help='Print delimited table of the type (for Word table importing)')
679 parser.add_option('--delimt-text-table',dest='delimTextDefinitionTable',default='\t'
680 ,help='Delimiter for text table [default: \'%default\'](for Word table importing)')
681
682
683 dbChoices = ('sqlite','postgres')
684 parser.add_option('-D','--db-type',dest='dbType',default='postgres'
685 ,choices=dbChoices,type='choice'
686 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]')
687
688 addMsgOptions(parser)
689
690 (options,args) = parser.parse_args()
691 success=True
692
693 if options.doctest:
694 import os; print os.path.basename(sys.argv[0]), 'doctests ...',
695 sys.argv= [sys.argv[0]]
696 if options.verbose: sys.argv.append('-v')
697 import doctest
698 numfail,numtests=doctest.testmod()
699 if numfail==0: print 'ok'
700 else:
701 print 'FAILED'
702 success=False
703
704 if not success: sys.exit('Something Failed')
705 del success
706
707 if options.unittest:
708 sys.argv = [sys.argv[0]]
709 if options.verbose: sys.argv.append('-v')
710 unittest.main()
711
712 outfile = sys.stdout
713 if None!=options.outputFileName:
714 outfile = file(options.outputFileName,'w')
715
716
717 if options.doEncode:
718
719 if None==options.time_monthField: parser.error("missing value for time_monthField")
720 if None==options.time_dayField: parser.error("missing value for time_dayField")
721 if None==options.time_hourField: parser.error("missing value for time_hourField")
722 if None==options.time_minField: parser.error("missing value for time_minField")
723 if None==options.stationidField: parser.error("missing value for stationidField")
724 if None==options.pos_longitudeField: parser.error("missing value for pos_longitudeField")
725 if None==options.pos_latitudeField: parser.error("missing value for pos_latitudeField")
726 if None==options.flowField: parser.error("missing value for flowField")
727 msgDict={
728 'time_month': options.time_monthField,
729 'time_day': options.time_dayField,
730 'time_hour': options.time_hourField,
731 'time_min': options.time_minField,
732 'stationid': options.stationidField,
733 'pos_longitude': options.pos_longitudeField,
734 'pos_latitude': options.pos_latitudeField,
735 'flow': options.flowField,
736 'reserved': '0',
737 }
738
739 bits = encode(msgDict)
740 if 'binary'==options.ioType: print str(bits)
741 elif 'nmeapayload'==options.ioType:
742
743 print "bitLen",len(bits)
744 bitLen=len(bits)
745 if bitLen%6!=0:
746 bits = bits + BitVector(size=(6 - (bitLen%6)))
747 print "result:",binary.bitvectoais6(bits)[0]
748
749
750
751 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability")
752 else: sys.exit('ERROR: unknown ioType. Help!')
753
754
755 if options.sqlCreate:
756 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType)
757
758 if options.latexDefinitionTable:
759 latexDefinitionTable(outfile)
760
761
762 if options.textDefinitionTable:
763 textDefinitionTable(outfile,options.delimTextDefinitionTable)
764
765 if options.printCsvfieldList:
766
767 if None == options.fieldList: options.fieldList = fieldList
768 import StringIO
769 buf = StringIO.StringIO()
770 for field in options.fieldList:
771 buf.write(field+',')
772 result = buf.getvalue()
773 if result[-1] == ',': print result[:-1]
774 else: print result
775
776 if options.doDecode:
777 for msg in args:
778 bv = None
779
780 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'):
781
782
783 bv = binary.ais6tobitvec(msg.split(',')[5])
784 else:
785
786 binaryMsg=True
787 for c in msg:
788 if c not in ('0','1'):
789 binaryMsg=False
790 break
791 if binaryMsg:
792 bv = BitVector(bitstring=msg)
793 else:
794 bv = binary.ais6tobitvec(msg)
795
796 printFields(decode(bv)
797 ,out=outfile
798 ,format=options.outputType
799 ,fieldList=options.fieldList
800 ,dbType=options.dbType
801 )
802