1
2
3 __version__ = '$Revision: 4791 $'.split()[1]
4 __date__ = '$Date: 2007-02-05 $'.split()[1]
5 __author__ = 'xmlbinmsg'
6
7 __doc__='''
8
9 Autogenerated python functions to serialize/deserialize binary messages.
10
11 Generated by: ./aisxmlbinmsg2py.py
12
13 Need to then wrap these functions with the outer AIS packet and then
14 convert the whole binary blob to a NMEA string. Those functions are
15 not currently provided in this file.
16
17 serialize: python to ais binary
18 deserialize: ais binary to python
19
20 The generated code uses translators.py, binary.py, and aisstring.py
21 which should be packaged with the resulting files.
22
23
24 @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3
25 @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>}
26
27 @author: '''+__author__+'''
28 @version: ''' + __version__ +'''
29 @var __date__: Date of last svn commit
30 @undocumented: __version__ __author__ __doc__ parser
31 @status: under development
32 @license: Generated code has no license
33 '''
34
35 import sys
36 from decimal import Decimal
37 from BitVector import BitVector
38
39 import binary, aisstring
40
41
42 TrueBV = BitVector(bitstring="1")
43 "Why always rebuild the True bit? This should speed things up a bunch"
44 FalseBV = BitVector(bitstring="0")
45 "Why always rebuild the False bit? This should speed things up a bunch"
46
47
48 fieldList = [
49 'dac',
50 'fid',
51 'efid',
52 'timetag_month',
53 'timetag_day',
54 'timetag_hour',
55 'timetag_min',
56 'timetag_sec',
57 'stationid',
58 'station_longitude',
59 'station_latitude',
60 'whale_longitude',
61 'whale_latitude',
62 'timetoexpire',
63 'radius',
64 'heading',
65 'numWhales',
66 ]
67
68 -def encode(params, validate=False):
69 '''Create a whalenotice binary message payload to pack into an AIS Msg whalenotice.
70
71 Fields in params:
72 - dac(uint): Designated Area Code (field automatically set to "366")
73 - fid(uint): Functional Identifier (field automatically set to "1")
74 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2")
75 - timetag_month(uint): Time whale was last recorded month 1..12
76 - timetag_day(uint): Time whale was last recorded day of the month 1..31
77 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23
78 - timetag_min(uint): Time whale was last recorded minutes
79 - timetag_sec(uint): Time whale was last recorded seconds
80 - stationid(aisstr6): Character identifier of the station. Usually a number.
81 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location
82 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location
83 - whale_longitude(decimal): Where was the whale East West location
84 - whale_latitude(decimal): Where was the whale North South location
85 - timetoexpire(uint): Seconds until this notice expires
86 - radius(uint): Distance of the required exclusion/slow zone
87 - heading(uint): Direction the whale is traveling
88 - numWhales(uint): Number of whales detected
89 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing
90 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
91 @rtype: BitVector
92 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8
93 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits.
94 '''
95
96 bvList = []
97 bvList.append(binary.setBitVectorSize(BitVector(intVal=366),16))
98 bvList.append(binary.setBitVectorSize(BitVector(intVal=1),4))
99 bvList.append(binary.setBitVectorSize(BitVector(intVal=2),12))
100 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_month']),4))
101 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_day']),5))
102 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_hour']),5))
103 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_min']),6))
104 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetag_sec']),6))
105 if 'stationid' in params:
106 bvList.append(aisstring.encode(params['stationid'],42))
107 else:
108 bvList.append(aisstring.encode('@@@@@@@',42))
109 if 'station_longitude' in params:
110 bvList.append(binary.bvFromSignedInt(int(Decimal(params['station_longitude'])*Decimal('600000')),28))
111 else:
112 bvList.append(binary.bvFromSignedInt(108600000,28))
113 if 'station_latitude' in params:
114 bvList.append(binary.bvFromSignedInt(int(Decimal(params['station_latitude'])*Decimal('600000')),27))
115 else:
116 bvList.append(binary.bvFromSignedInt(54600000,27))
117 if 'whale_longitude' in params:
118 bvList.append(binary.bvFromSignedInt(int(Decimal(params['whale_longitude'])*Decimal('600000')),28))
119 else:
120 bvList.append(binary.bvFromSignedInt(108600000,28))
121 if 'whale_latitude' in params:
122 bvList.append(binary.bvFromSignedInt(int(Decimal(params['whale_latitude'])*Decimal('600000')),27))
123 else:
124 bvList.append(binary.bvFromSignedInt(54600000,27))
125 if 'timetoexpire' in params:
126 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['timetoexpire']),16))
127 else:
128 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),16))
129 if 'radius' in params:
130 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['radius']),16))
131 else:
132 bvList.append(binary.setBitVectorSize(BitVector(intVal=65534),16))
133 if 'heading' in params:
134 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['heading']),9))
135 else:
136 bvList.append(binary.setBitVectorSize(BitVector(intVal=511),9))
137 if 'numWhales' in params:
138 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['numWhales']),8))
139 else:
140 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),8))
141
142 return binary.joinBV(bvList)
143
144 -def decode(bv, validate=False):
145 '''Unpack a whalenotice message
146
147 Fields in params:
148 - dac(uint): Designated Area Code (field automatically set to "366")
149 - fid(uint): Functional Identifier (field automatically set to "1")
150 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2")
151 - timetag_month(uint): Time whale was last recorded month 1..12
152 - timetag_day(uint): Time whale was last recorded day of the month 1..31
153 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23
154 - timetag_min(uint): Time whale was last recorded minutes
155 - timetag_sec(uint): Time whale was last recorded seconds
156 - stationid(aisstr6): Character identifier of the station. Usually a number.
157 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location
158 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location
159 - whale_longitude(decimal): Where was the whale East West location
160 - whale_latitude(decimal): Where was the whale North South location
161 - timetoexpire(uint): Seconds until this notice expires
162 - radius(uint): Distance of the required exclusion/slow zone
163 - heading(uint): Direction the whale is traveling
164 - numWhales(uint): Number of whales detected
165 @type bv: BitVector
166 @param bv: Bits defining a message
167 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented.
168 @rtype: dict
169 @return: params
170 '''
171
172
173
174
175 r = {}
176 r['dac']=366
177 r['fid']=1
178 r['efid']=2
179 r['timetag_month']=int(bv[32:36])
180 r['timetag_day']=int(bv[36:41])
181 r['timetag_hour']=int(bv[41:46])
182 r['timetag_min']=int(bv[46:52])
183 r['timetag_sec']=int(bv[52:58])
184 r['stationid']=aisstring.decode(bv[58:100])
185 r['station_longitude']=Decimal(binary.signedIntFromBV(bv[100:128]))/Decimal('600000')
186 r['station_latitude']=Decimal(binary.signedIntFromBV(bv[128:155]))/Decimal('600000')
187 r['whale_longitude']=Decimal(binary.signedIntFromBV(bv[155:183]))/Decimal('600000')
188 r['whale_latitude']=Decimal(binary.signedIntFromBV(bv[183:210]))/Decimal('600000')
189 r['timetoexpire']=int(bv[210:226])
190 r['radius']=int(bv[226:242])
191 r['heading']=int(bv[242:251])
192 r['numWhales']=int(bv[251:259])
193 return r
194
196 return 366
197
199 return 1
200
202 return 2
203
206
209
212
215
218
221
224
227
230
233
235 return int(bv[210:226])
236
238 return int(bv[226:242])
239
241 return int(bv[242:251])
242
244 return int(bv[251:259])
245
246
248 out.write("<h3>whalenotice<h3>\n")
249 out.write("<table border=\"1\">\n")
250 out.write("<tr bgcolor=\"orange\">\n")
251 out.write("<th align=\"left\">Field Name</th>\n")
252 out.write("<th align=\"left\">Type</th>\n")
253 out.write("<th align=\"left\">Value</th>\n")
254 out.write("<th align=\"left\">Value in Lookup Table</th>\n")
255 out.write("<th align=\"left\">Units</th>\n")
256 out.write("\n")
257 out.write("<tr>\n")
258 out.write("<td>dac</td>\n")
259 out.write("<td>uint</td>\n")
260 if 'dac' in params:
261 out.write(" <td>"+str(params['dac'])+"</td>\n")
262 out.write(" <td>"+str(params['dac'])+"</td>\n")
263 out.write("</tr>\n")
264 out.write("\n")
265 out.write("<tr>\n")
266 out.write("<td>fid</td>\n")
267 out.write("<td>uint</td>\n")
268 if 'fid' in params:
269 out.write(" <td>"+str(params['fid'])+"</td>\n")
270 out.write(" <td>"+str(params['fid'])+"</td>\n")
271 out.write("</tr>\n")
272 out.write("\n")
273 out.write("<tr>\n")
274 out.write("<td>efid</td>\n")
275 out.write("<td>uint</td>\n")
276 if 'efid' in params:
277 out.write(" <td>"+str(params['efid'])+"</td>\n")
278 out.write(" <td>"+str(params['efid'])+"</td>\n")
279 out.write("</tr>\n")
280 out.write("\n")
281 out.write("<tr>\n")
282 out.write("<td>timetag_month</td>\n")
283 out.write("<td>uint</td>\n")
284 if 'timetag_month' in params:
285 out.write(" <td>"+str(params['timetag_month'])+"</td>\n")
286 out.write(" <td>"+str(params['timetag_month'])+"</td>\n")
287 out.write("</tr>\n")
288 out.write("\n")
289 out.write("<tr>\n")
290 out.write("<td>timetag_day</td>\n")
291 out.write("<td>uint</td>\n")
292 if 'timetag_day' in params:
293 out.write(" <td>"+str(params['timetag_day'])+"</td>\n")
294 out.write(" <td>"+str(params['timetag_day'])+"</td>\n")
295 out.write("</tr>\n")
296 out.write("\n")
297 out.write("<tr>\n")
298 out.write("<td>timetag_hour</td>\n")
299 out.write("<td>uint</td>\n")
300 if 'timetag_hour' in params:
301 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n")
302 out.write(" <td>"+str(params['timetag_hour'])+"</td>\n")
303 out.write("</tr>\n")
304 out.write("\n")
305 out.write("<tr>\n")
306 out.write("<td>timetag_min</td>\n")
307 out.write("<td>uint</td>\n")
308 if 'timetag_min' in params:
309 out.write(" <td>"+str(params['timetag_min'])+"</td>\n")
310 out.write(" <td>"+str(params['timetag_min'])+"</td>\n")
311 out.write("</tr>\n")
312 out.write("\n")
313 out.write("<tr>\n")
314 out.write("<td>timetag_sec</td>\n")
315 out.write("<td>uint</td>\n")
316 if 'timetag_sec' in params:
317 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n")
318 out.write(" <td>"+str(params['timetag_sec'])+"</td>\n")
319 out.write("</tr>\n")
320 out.write("\n")
321 out.write("<tr>\n")
322 out.write("<td>stationid</td>\n")
323 out.write("<td>aisstr6</td>\n")
324 if 'stationid' in params:
325 out.write(" <td>"+str(params['stationid'])+"</td>\n")
326 out.write(" <td>"+str(params['stationid'])+"</td>\n")
327 out.write("</tr>\n")
328 out.write("\n")
329 out.write("<tr>\n")
330 out.write("<td>station_longitude</td>\n")
331 out.write("<td>decimal</td>\n")
332 if 'station_longitude' in params:
333 out.write(" <td>"+str(params['station_longitude'])+"</td>\n")
334 out.write(" <td>"+str(params['station_longitude'])+"</td>\n")
335 out.write("<td>degrees</td>\n")
336 out.write("</tr>\n")
337 out.write("\n")
338 out.write("<tr>\n")
339 out.write("<td>station_latitude</td>\n")
340 out.write("<td>decimal</td>\n")
341 if 'station_latitude' in params:
342 out.write(" <td>"+str(params['station_latitude'])+"</td>\n")
343 out.write(" <td>"+str(params['station_latitude'])+"</td>\n")
344 out.write("<td>degrees</td>\n")
345 out.write("</tr>\n")
346 out.write("\n")
347 out.write("<tr>\n")
348 out.write("<td>whale_longitude</td>\n")
349 out.write("<td>decimal</td>\n")
350 if 'whale_longitude' in params:
351 out.write(" <td>"+str(params['whale_longitude'])+"</td>\n")
352 out.write(" <td>"+str(params['whale_longitude'])+"</td>\n")
353 out.write("<td>degrees</td>\n")
354 out.write("</tr>\n")
355 out.write("\n")
356 out.write("<tr>\n")
357 out.write("<td>whale_latitude</td>\n")
358 out.write("<td>decimal</td>\n")
359 if 'whale_latitude' in params:
360 out.write(" <td>"+str(params['whale_latitude'])+"</td>\n")
361 out.write(" <td>"+str(params['whale_latitude'])+"</td>\n")
362 out.write("<td>degrees</td>\n")
363 out.write("</tr>\n")
364 out.write("\n")
365 out.write("<tr>\n")
366 out.write("<td>timetoexpire</td>\n")
367 out.write("<td>uint</td>\n")
368 if 'timetoexpire' in params:
369 out.write(" <td>"+str(params['timetoexpire'])+"</td>\n")
370 out.write(" <td>"+str(params['timetoexpire'])+"</td>\n")
371 out.write("<td>seconds</td>\n")
372 out.write("</tr>\n")
373 out.write("\n")
374 out.write("<tr>\n")
375 out.write("<td>radius</td>\n")
376 out.write("<td>uint</td>\n")
377 if 'radius' in params:
378 out.write(" <td>"+str(params['radius'])+"</td>\n")
379 out.write(" <td>"+str(params['radius'])+"</td>\n")
380 out.write("<td>m</td>\n")
381 out.write("</tr>\n")
382 out.write("\n")
383 out.write("<tr>\n")
384 out.write("<td>heading</td>\n")
385 out.write("<td>uint</td>\n")
386 if 'heading' in params:
387 out.write(" <td>"+str(params['heading'])+"</td>\n")
388 out.write(" <td>"+str(params['heading'])+"</td>\n")
389 out.write("<td>degrees true north</td>\n")
390 out.write("</tr>\n")
391 out.write("\n")
392 out.write("<tr>\n")
393 out.write("<td>numWhales</td>\n")
394 out.write("<td>uint</td>\n")
395 if 'numWhales' in params:
396 out.write(" <td>"+str(params['numWhales'])+"</td>\n")
397 out.write(" <td>"+str(params['numWhales'])+"</td>\n")
398 out.write("</tr>\n")
399 out.write("</table>\n")
400
401
403 '''KML (Keyhole Markup Language) for Google Earth, but without the header/footer'''
404 out.write("\ <Placemark>\n")
405 out.write("\t <name>"+str(params['stationsid'])+"</name>\n")
406 out.write("\t\t<description>\n")
407 import StringIO
408 buf = StringIO.StringIO()
409 printHtml(params,buf)
410 import cgi
411 out.write(cgi.escape(buf.getvalue()))
412 out.write("\t\t</description>\n")
413 out.write("\t\t<styleUrl>#m_ylw-pushpin_copy0</styleUrl>\n")
414 out.write("\t\t<Point>\n")
415 out.write("\t\t\t<coordinates>")
416 out.write(str(params['station_longitude']))
417 out.write(',')
418 out.write(str(params['station_latitude']))
419 out.write(",0</coordinates>\n")
420 out.write("\t\t</Point>\n")
421 out.write("\t</Placemark>\n")
422
423 -def printFields(params, out=sys.stdout, format='std', fieldList=None):
424 '''Print a numWhales message to stdout.
425
426 Fields in params:
427 - dac(uint): Designated Area Code (field automatically set to "366")
428 - fid(uint): Functional Identifier (field automatically set to "1")
429 - efid(uint): extended functional identifier (dac+fid+id defines which message) (field automatically set to "2")
430 - timetag_month(uint): Time whale was last recorded month 1..12
431 - timetag_day(uint): Time whale was last recorded day of the month 1..31
432 - timetag_hour(uint): Time whale was last recorded UTC hours 0..23
433 - timetag_min(uint): Time whale was last recorded minutes
434 - timetag_sec(uint): Time whale was last recorded seconds
435 - stationid(aisstr6): Character identifier of the station. Usually a number.
436 - station_longitude(decimal): Location of the sensor taking the water level measurement or position of prediction East West location
437 - station_latitude(decimal): Location of the sensor taking the water level measurement or position of prediction North South location
438 - whale_longitude(decimal): Where was the whale East West location
439 - whale_latitude(decimal): Where was the whale North South location
440 - timetoexpire(uint): Seconds until this notice expires
441 - radius(uint): Distance of the required exclusion/slow zone
442 - heading(uint): Direction the whale is traveling
443 - numWhales(uint): Number of whales detected
444 @param params: Dictionary of field names/values.
445 @param out: File like object to write to
446 @rtype: stdout
447 @return: text to out
448 '''
449
450 if 'std'==format:
451 out.write("numWhales:\n")
452 if 'dac' in params: out.write(" dac: "+str(params['dac'])+"\n")
453 if 'fid' in params: out.write(" fid: "+str(params['fid'])+"\n")
454 if 'efid' in params: out.write(" efid: "+str(params['efid'])+"\n")
455 if 'timetag_month' in params: out.write(" timetag_month: "+str(params['timetag_month'])+"\n")
456 if 'timetag_day' in params: out.write(" timetag_day: "+str(params['timetag_day'])+"\n")
457 if 'timetag_hour' in params: out.write(" timetag_hour: "+str(params['timetag_hour'])+"\n")
458 if 'timetag_min' in params: out.write(" timetag_min: "+str(params['timetag_min'])+"\n")
459 if 'timetag_sec' in params: out.write(" timetag_sec: "+str(params['timetag_sec'])+"\n")
460 if 'stationid' in params: out.write(" stationid: "+str(params['stationid'])+"\n")
461 if 'station_longitude' in params: out.write(" station_longitude: "+str(params['station_longitude'])+"\n")
462 if 'station_latitude' in params: out.write(" station_latitude: "+str(params['station_latitude'])+"\n")
463 if 'whale_longitude' in params: out.write(" whale_longitude: "+str(params['whale_longitude'])+"\n")
464 if 'whale_latitude' in params: out.write(" whale_latitude: "+str(params['whale_latitude'])+"\n")
465 if 'timetoexpire' in params: out.write(" timetoexpire: "+str(params['timetoexpire'])+"\n")
466 if 'radius' in params: out.write(" radius: "+str(params['radius'])+"\n")
467 if 'heading' in params: out.write(" heading: "+str(params['heading'])+"\n")
468 if 'numWhales' in params: out.write(" numWhales: "+str(params['numWhales'])+"\n")
469 elif 'csv'==format:
470 if None == options.fieldList:
471 options.fieldList = fieldList
472 needComma = False;
473 for field in fieldList:
474 if needComma: out.write(',')
475 needComma = True
476 if field in params:
477 out.write(str(params[field]))
478
479 out.write("\n")
480 elif 'html'==format:
481 printHtml(params,out)
482 elif 'sql'==format:
483 sqlInsertStr(params,out)
484 elif 'kml'==format:
485 printKml(params,out)
486 elif 'kml-full'==format:
487 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
488 out.write("<kml xmlns=\"http://earth.google.com/kml/2.1\">\n")
489 out.write("<Document>\n")
490 out.write(" <name>whalenotice</name>\n")
491 printKml(params,out)
492 out.write("</Document>\n")
493 out.write("</kml>\n")
494 else:
495 print "ERROR: unknown format:",format
496 assert False
497
498 return
499
500
501
502
503
504 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None):
505 '''
506 Return the SQL CREATE command for this message type
507 @param outfile: file like object to print to.
508 @param fields: which fields to put in the create. Defaults to all.
509 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields
510 @return: sql create string
511 @rtype: str
512
513 @see: sqlCreate
514 '''
515 outfile.write(str(sqlCreate(fields,extraFields)))
516
517 -def sqlCreate(fields=None, extraFields=None):
518 '''
519 Return the sqlhelp object to create the table.
520
521 @param fields: which fields to put in the create. Defaults to all.
522 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields
523 @return: An object that can be used to generate a return
524 @rtype: sqlhelp.create
525 '''
526 if None == fields: fields = fieldList
527 import sqlhelp
528 c = sqlhelp.create('whalenotice')
529 if 'dac' in fields: c.addInt ('dac')
530 if 'fid' in fields: c.addInt ('fid')
531 if 'efid' in fields: c.addInt ('efid')
532 if 'timetag_month' in fields: c.addInt ('timetag_month')
533 if 'timetag_day' in fields: c.addInt ('timetag_day')
534 if 'timetag_hour' in fields: c.addInt ('timetag_hour')
535 if 'timetag_min' in fields: c.addInt ('timetag_min')
536 if 'timetag_sec' in fields: c.addInt ('timetag_sec')
537 if 'stationid' in fields: c.addVarChar(stationid,7)
538 if 'station_longitude' in fields: c.addDecimal('station_longitude',8,5)
539 if 'station_latitude' in fields: c.addDecimal('station_latitude',8,5)
540 if 'whale_longitude' in fields: c.addDecimal('whale_longitude',8,5)
541 if 'whale_latitude' in fields: c.addDecimal('whale_latitude',8,5)
542 if 'timetoexpire' in fields: c.addInt ('timetoexpire')
543 if 'radius' in fields: c.addInt ('radius')
544 if 'heading' in fields: c.addInt ('heading')
545 if 'numWhales' in fields: c.addInt ('numWhales')
546
547 return c
548
549 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None):
550 '''
551 Return the SQL CREATE command for this message type
552 @param params: dictionary of values keyed by field name
553 @param outfile: file like object to print to.
554 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields
555 @return: sql create string
556 @rtype: str
557
558 @see: sqlCreate
559 '''
560 outfile.write(str(sqlInsert(params,extraParams)))
561
562
564 '''
565 Give the SQL insert statement
566 @param params: dict keyed by field name of values
567 @param extraParams: any extra fields that you have created beyond the normal ais message fields
568 @rtype: sqlhelp.insert
569 @return: insert class instance
570 @todo: allow optional type checking of params?
571 @warning: this will take invalid keys happily and do what???
572 '''
573 import sqlhelp
574 i = sqlhelp.insert('whalenotice')
575 for key in params: i.add(key,params[key])
576 if None != extraParams:
577 for key in extraParams:
578 i.add(key,extraParams[key])
579
580 return i
581
582
583
584
585
586 import unittest
588 '''Return a params file base on the testvalue tags.
589 @rtype: dict
590 @return: params based on testvalue tags
591 '''
592 params = {}
593 params['dac'] = 366
594 params['fid'] = 1
595 params['efid'] = 2
596 params['timetag_month'] = 2
597 params['timetag_day'] = 28
598 params['timetag_hour'] = 23
599 params['timetag_min'] = 45
600 params['timetag_sec'] = 58
601 params['stationid'] = 'A234567'
602 params['station_longitude'] = Decimal('-122.16328055555556')
603 params['station_latitude'] = Decimal('37.424458333333334')
604 params['whale_longitude'] = Decimal('-122.16328055555556')
605 params['whale_latitude'] = Decimal('37.424458333333334')
606 params['timetoexpire'] = 1
607 params['radius'] = 5000
608 params['heading'] = 35
609 params['numWhales'] = 2
610
611 return params
612
614 '''Use testvalue tag text from each type to build test case the whalenotice message'''
616
617 params = testParams()
618 bits = encode(params)
619 r = decode(bits)
620
621
622 self.failUnlessEqual(r['dac'],params['dac'])
623 self.failUnlessEqual(r['fid'],params['fid'])
624 self.failUnlessEqual(r['efid'],params['efid'])
625 self.failUnlessEqual(r['timetag_month'],params['timetag_month'])
626 self.failUnlessEqual(r['timetag_day'],params['timetag_day'])
627 self.failUnlessEqual(r['timetag_hour'],params['timetag_hour'])
628 self.failUnlessEqual(r['timetag_min'],params['timetag_min'])
629 self.failUnlessEqual(r['timetag_sec'],params['timetag_sec'])
630 self.failUnlessEqual(r['stationid'],params['stationid'])
631 self.failUnlessAlmostEqual(r['station_longitude'],params['station_longitude'],5)
632 self.failUnlessAlmostEqual(r['station_latitude'],params['station_latitude'],5)
633 self.failUnlessAlmostEqual(r['whale_longitude'],params['whale_longitude'],5)
634 self.failUnlessAlmostEqual(r['whale_latitude'],params['whale_latitude'],5)
635 self.failUnlessEqual(r['timetoexpire'],params['timetoexpire'])
636 self.failUnlessEqual(r['radius'],params['radius'])
637 self.failUnlessEqual(r['heading'],params['heading'])
638 self.failUnlessEqual(r['numWhales'],params['numWhales'])
639
641 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true',
642 help='decode a "whalenotice" AIS message')
643 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true',
644 help='encode a "whalenotice" AIS message')
645 parser.add_option('--timetag_month-field', dest='timetag_monthField',metavar='uint',type='int'
646 ,help='Field parameter value [default: %default]')
647 parser.add_option('--timetag_day-field', dest='timetag_dayField',metavar='uint',type='int'
648 ,help='Field parameter value [default: %default]')
649 parser.add_option('--timetag_hour-field', dest='timetag_hourField',metavar='uint',type='int'
650 ,help='Field parameter value [default: %default]')
651 parser.add_option('--timetag_min-field', dest='timetag_minField',metavar='uint',type='int'
652 ,help='Field parameter value [default: %default]')
653 parser.add_option('--timetag_sec-field', dest='timetag_secField',metavar='uint',type='int'
654 ,help='Field parameter value [default: %default]')
655 parser.add_option('--stationid-field', dest='stationidField',default='@@@@@@@',metavar='aisstr6',type='string'
656 ,help='Field parameter value [default: %default]')
657 parser.add_option('--station_longitude-field', dest='station_longitudeField',default=Decimal('181'),metavar='decimal',type='string'
658 ,help='Field parameter value [default: %default]')
659 parser.add_option('--station_latitude-field', dest='station_latitudeField',default=Decimal('91'),metavar='decimal',type='string'
660 ,help='Field parameter value [default: %default]')
661 parser.add_option('--whale_longitude-field', dest='whale_longitudeField',default=Decimal('181'),metavar='decimal',type='string'
662 ,help='Field parameter value [default: %default]')
663 parser.add_option('--whale_latitude-field', dest='whale_latitudeField',default=Decimal('91'),metavar='decimal',type='string'
664 ,help='Field parameter value [default: %default]')
665 parser.add_option('--timetoexpire-field', dest='timetoexpireField',default=0,metavar='uint',type='int'
666 ,help='Field parameter value [default: %default]')
667 parser.add_option('--radius-field', dest='radiusField',default=65534,metavar='uint',type='int'
668 ,help='Field parameter value [default: %default]')
669 parser.add_option('--heading-field', dest='headingField',default=511,metavar='uint',type='int'
670 ,help='Field parameter value [default: %default]')
671 parser.add_option('--numWhales-field', dest='numWhalesField',default=0,metavar='uint',type='int'
672 ,help='Field parameter value [default: %default]')
673
674
675 if __name__=='__main__':
676
677 from optparse import OptionParser
678 parser = OptionParser(usage="%prog [options]",
679 version="%prog "+__version__)
680
681 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true',
682 help='run the documentation tests')
683 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true',
684 help='run the unit tests')
685 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true',
686 help='Make the test output verbose')
687
688
689
690 typeChoices = ('binary','nmeapayload','nmea')
691 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType'
692 ,default='nmeapayload'
693 ,help='What kind of string to expect ('+', '.join(typeChoices)+') [default: %default]')
694
695
696 outputChoices = ('std','html','csv','sql' , 'kml','kml-full')
697 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType'
698 ,default='std'
699 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]')
700
701 parser.add_option('-o','--output',dest='outputFileName',default=None,
702 help='Name of the python file to write [default: stdout]')
703
704 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append',
705 choices=fieldList,
706 help='Which fields to include in the output. Currently only for csv output [default: all]')
707
708 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true',
709 help='Print the field name for csv')
710
711 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true',
712 help='Print out an sql create command for the table.')
713
714 addMsgOptions(parser)
715
716 (options,args) = parser.parse_args()
717 success=True
718
719 if options.doctest:
720 import os; print os.path.basename(sys.argv[0]), 'doctests ...',
721 sys.argv= [sys.argv[0]]
722 if options.verbose: sys.argv.append('-v')
723 import doctest
724 numfail,numtests=doctest.testmod()
725 if numfail==0: print 'ok'
726 else:
727 print 'FAILED'
728 success=False
729
730 if not success: sys.exit('Something Failed')
731 del success
732
733 if options.unittest:
734 sys.argv = [sys.argv[0]]
735 if options.verbose: sys.argv.append('-v')
736 unittest.main()
737
738 outfile = sys.stdout
739 if None!=options.outputFileName:
740 outfile = file(options.outputFileName,'w')
741
742
743 if options.doEncode:
744
745 if None==options.timetag_monthField: parser.error("missing value for timetag_monthField")
746 if None==options.timetag_dayField: parser.error("missing value for timetag_dayField")
747 if None==options.timetag_hourField: parser.error("missing value for timetag_hourField")
748 if None==options.timetag_minField: parser.error("missing value for timetag_minField")
749 if None==options.timetag_secField: parser.error("missing value for timetag_secField")
750 if None==options.stationidField: parser.error("missing value for stationidField")
751 if None==options.station_longitudeField: parser.error("missing value for station_longitudeField")
752 if None==options.station_latitudeField: parser.error("missing value for station_latitudeField")
753 if None==options.whale_longitudeField: parser.error("missing value for whale_longitudeField")
754 if None==options.whale_latitudeField: parser.error("missing value for whale_latitudeField")
755 if None==options.timetoexpireField: parser.error("missing value for timetoexpireField")
756 if None==options.radiusField: parser.error("missing value for radiusField")
757 if None==options.headingField: parser.error("missing value for headingField")
758 if None==options.numWhalesField: parser.error("missing value for numWhalesField")
759 msgDict={
760 'dac': '366',
761 'fid': '1',
762 'efid': '2',
763 'timetag_month': options.timetag_monthField,
764 'timetag_day': options.timetag_dayField,
765 'timetag_hour': options.timetag_hourField,
766 'timetag_min': options.timetag_minField,
767 'timetag_sec': options.timetag_secField,
768 'stationid': options.stationidField,
769 'station_longitude': options.station_longitudeField,
770 'station_latitude': options.station_latitudeField,
771 'whale_longitude': options.whale_longitudeField,
772 'whale_latitude': options.whale_latitudeField,
773 'timetoexpire': options.timetoexpireField,
774 'radius': options.radiusField,
775 'heading': options.headingField,
776 'numWhales': options.numWhalesField,
777 }
778
779 bits = encode(msgDict)
780 if 'binary'==options.ioType: print str(bits)
781 elif 'nmeapayload'==options.ioType:
782
783 print "bitLen",len(bits)
784 bitLen=len(bits)
785 if bitLen%6!=0:
786 bits = bits + BitVector(size=(6 - (bitLen%6)))
787 print "result:",binary.bitvectoais6(bits)[0]
788
789
790
791 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability")
792 else: sys.exit('ERROR: unknown ioType. Help!')
793
794
795 if options.sqlCreate:
796 sqlCreateStr(outfile,options.fieldList)
797
798 if options.printCsvfieldList:
799
800 if None == options.fieldList: options.fieldList = fieldList
801 import StringIO
802 buf = StringIO.StringIO()
803 for field in options.fieldList:
804 buf.write(field+',')
805 result = buf.getvalue()
806 if result[-1] == ',': print result[:-1]
807 else: print result
808
809 if options.doDecode:
810 for msg in args:
811 bv = None
812 if 'binary' == options.ioType: bv = BitVector(bitstring=msg)
813 elif 'nmeapayload'== options.ioType: bv = binary.ais6tobitvec(msg)
814 elif 'nmea' == options.ioType: bv = binary.ais6tobitvec(msg.split(',')[5])
815 else: sys.exit('ERROR: unknown ioType. Help!')
816
817 printFields(decode(bv),out=outfile,format=options.outputType,fieldList=options.fieldList)
818