I used https://github.com/schwehr/noaadata/tree/master/ais to decode AIS messages with this package (Python) until I started to get a new message format. As you may know, AIS messages are mainly of two types. one part (one message) or two parts (many messages). Message No. 5 always consists of two parts. Example:
I used to decode this just fine using the following code snippet:
nmeamsg = fields.split(',') if nmeamsg[0] != '!AIVDM': return total = eval(nmeamsg[1]) part = eval(nmeamsg[2]) aismsg = nmeamsg[5] nmeastring = string.join(nmeamsg[0:-1],',') bv = binary.ais6tobitvec(aismsg) msgnum = int(bv[0:6])
-
elif (total>1): # Multi Slot Messages: 5,6,8,12,14,17,19,20?,21,24,26 global multimsg if total==2: if msgnum==5: if nmeastring.count('!AIVDM')==2 and len(nmeamsg)==13: # make sure there are two parts concatenated together aismsg = nmeamsg[5]+nmeamsg[11] bv = binary.ais6tobitvec(aismsg) msg5 = ais_msg_5.decode(bv) print "message5 :",msg5 return msg5
Now I get a new message format:
!SAVDM,2,1,7,A, 55@0hd01sq ` pQ3W?O81L5@E : 1=0U8U@000000016000006H0004m8523k @Dp,0*2A,1410825672 !SAVDM,2,2,7,A,4hC` 2U@C `40,2*76,1410825672,1410825673
Note. the number in the last index is the time in epoch format
I tried setting my code to decode the new format. I managed to decode messages in one piece. My problem is with several types of messages.
nmeamsg = fields.split(',') if nmeamsg[0] != '!AIVDM' and nmeamsg[0] != '!SAVDM': return total = eval(nmeamsg[1]) part = eval(nmeamsg[2]) aismsg = nmeamsg[5] nmeastring = string.join(nmeamsg[0:-1],',') dbtimestring = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(nmeamsg[7]))) bv = binary.ais6tobitvec(aismsg) msgnum = int(bv[0:6])
The decoder cannot output two lines as one. Thus, decoding is not performed because message # 5 must contain two lines, not one. The error I am getting is in these lines:
if nmeastring.count('!SAVDM')==2 and len(nmeamsg)==13: aismsg = nmeamsg[5]+nmeamsg[11]
Where len(nmeamsg) always 8 (second line), and nmeastring.count('!SAVDM') always 1
Hopefully I explained this clearly, so someone can tell me what I am missing here.
UPDATE
Ok, I think I found the reason. I pass the messages from the file to the script line by line:
for line in file: i=i+1 try: doais(line)
If message No. 5 should be transmitted as two lines. Any idea on how I can do this?
UPDATE
I did this by slightly modifying the code:
for line in file: i=i+1 try: nmeamsg = line.split(',') aismsg = nmeamsg[5] bv = binary.ais6tobitvec(aismsg) msgnum = int(bv[0:6]) print msgnum if nmeamsg[0] != '!AIVDM' and nmeamsg[0] != '!SAVDM': print "wrong format" total = eval(nmeamsg[1]) if total == 1: dbtimestring = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(nmeamsg[8]))) doais(line,msgnum,dbtimestring,aismsg) if total == 2: #Multi-line messages lines= line+file.next() nmeamsg = lines.split(',') dbtimestring = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(nmeamsg[15]))) aismsg = nmeamsg[5]+nmeamsg[12] doais(lines,msgnum,dbtimestring,aismsg)