title: Building AIS Messages Decoder
body: <p>I used to decode AIS messages with theis package (Python) <a href="https://github.com/schwehr/noaadata/tree/master/ais" rel="nofollow">https://github.com/schwehr/noaadata/tree/master/ais</a>  until I started getting a new format of the messages. 
  As you may know, AIS messages come in two types mostly. one part (one message) or two parts (multi message). Message#5 is always comes in two parts. example:</p>
  
  <pre><code>!AIVDM,2,1,1,A,55?MbV02;H;s&lt;HtKR20EHE:address@hidden@Dn2222222216L961O5Gf0NSQEp6ClRp8,0*1C
  !AIVDM,2,2,1,A,88888888880,2*25
  </code></pre>
  
  <p>I used to decode this just fine using the following piece of code:</p>
  
  <pre><code>   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])
  </code></pre>
  
  <p>--</p>
  
  <pre><code>elif (total&gt;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
  </code></pre>
  
  <p>Now I'm getting a new format of the messages:</p>
  
  <pre><code>!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
  </code></pre>
  
  <p>Note. the number at the last index is the time in epoch format</p>
  
  <p>I tried to adjust my code to decode this new format. I succeed in decoding messages with one part. My problem is multi message type. </p>
  
  <pre><code>   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])
  </code></pre>
  
  <p>Decoder can't bring the two lines as one. So decoding fails because message#5 should contain two strings not one. The error i get is in these lines:</p>
  
  <pre><code>if nmeastring.count('!SAVDM')==2 and len(nmeamsg)==13: 
  aismsg = nmeamsg[5]+nmeamsg[11]
  </code></pre>
  
  <p>Where <code>len(nmeamsg)</code> is always 8 (second line) and <code>nmeastring.count('!SAVDM')</code> is always 1</p>
  
  <p>I hope I explained this clearly so someone can let me know what I'm missing here.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Okay I think I found the reason. I pass messages from file to script line by line:</p>
  
  <pre><code>for line in file:
      i=i+1
  
      try:
          doais(line)
  </code></pre>
  
  <p>Where message#5 should be passed as two lines. Any idea on how can I accomplish that? </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I did it by modifying the code a little bit:</p>
  
  <pre><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)
  </code></pre>