示例#1
0
  def testDecode(self):
    line = '$ANADS,L3 AIS ID,024829.51,V,0,I,I*39'
    message = nmea_messages.DecodeLine(line)
    self.assertEqual(
        message,
        {'alarm': '',
         'id': 'L3 AIS ID',
         'message': 'ADS',
         'pos_src': 'I',
         'talker': 'AN',
         'time_src': 'I',
         'time_sync_method': 0,
         'when': datetime.time(2, 48, 29, 510000)})

    line = '$BSADS,312670-BS,134839.00,A,3,N,N*22'
    message = nmea_messages.DecodeLine(line)
    self.assertEqual(
        message,
        {'alarm': '',
         'id': '312670-BS',
         'message': 'ADS',
         'pos_src': 'N',
         'talker': 'BS',
         'time_src': 'N',
         'time_sync_method': 3,
         'when': datetime.time(13, 48, 39)})
示例#2
0
  def testDecode(self):
    line = '$ANALR,000000.00,007,A,V,AIS: UTC Lost*75'
    message = nmea_messages.DecodeLine(line)
    self.assertEqual(
        message,
        {'ack_state': False,
         'ack_state_raw': 'V',
         'condition': True,
         'condition_raw': 'A',
         'id': '007',
         'message': 'ALR',
         'talker': 'AN',
         'text': 'AIS: UTC Lost',
         'time': datetime.time(0, 0)})

    line = '$BSALR,134239.00,002,A,V,AIS: Antenna VSWR exceeds limit*45'
    message = nmea_messages.DecodeLine(line)
    self.assertEqual(
        message,
        {'ack_state': False,
         'ack_state_raw': 'V',
         'condition': True,
         'condition_raw': 'A',
         'id': '002',
         'message': 'ALR',
         'talker': 'BS',
         'text': 'AIS: Antenna VSWR exceeds limit',
         'time': datetime.time(13, 42, 39)})

    line = '$BSALR,000000.00,006,V,V,AIS: General Failure*0D,rbs1,1206655746.11'
    message = nmea_messages.DecodeLine(line)
    self.assertEqual(
        message,
        {'ack_state': False,
         'ack_state_raw': 'V',
         'condition': False,
         'condition_raw': 'V',
         'id': '006',
         'message': 'ALR',
         'talker': 'BS',
         'text': 'AIS: General Failure',
         'time': datetime.time(0, 0)})

    line = '$BSALR,000000.00,051,V,V,AIS: IEC Comm Error*02,rbs1,1206655746.23'
    message = nmea_messages.DecodeLine(line)
    self.assertEqual(
        message,
        {'ack_state': False,
         'ack_state_raw': 'V',
         'condition': False,
         'condition_raw': 'V',
         'id': '051',
         'message': 'ALR',
         'talker': 'BS',
         'text': 'AIS: IEC Comm Error',
         'time': datetime.time(0, 0)})
示例#3
0
 def testDecode(self):
   line = '$INZDA,082015.0007,30,04,2009,,*73'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'message': 'ZDA',
        'datetime': datetime.datetime(2009, 4, 30, 8, 20, 15, 700),
        'talker': 'IN',
        'zone_hours': None,
        'zone_minutes': None})
示例#4
0
 def testDecode(self):
   line = '$AITXT,01,01,91,FREQ,2087,2088*57'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'message': 'TXT',
        'sen_num': 1,
        'sen_tot': 1,
        'seq_num': 91,
        'talker': 'AI',
        'text': 'FREQ,2087,2088'})
示例#5
0
 def testDecodeX(self):
   line = '$ARFSR,b003669708,000004,X,488,0,,,,,*5B'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'chan': 'X',
        'id': 'b003669708',
        'message': 'FSR',
        'slots_recv': 488,
        'slots_self': 0,
        'time': datetime.time(0, 0, 4)})
示例#6
0
 def testWithSingleDigitSentenceAndSequence(self):
   line = '$AITXT,1,1,007,AIS: UTC clock lost*08'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'message': 'TXT',
        'sen_num': 1,
        'sen_tot': 1,
        'seq_num': 7,
        'talker': 'AI',
        'text': 'AIS: UTC clock lost'})
示例#7
0
 def testWithCaret(self):
   # TODO(schwehr): ^2C should be replaced by a special character in decoding.
   line = '$AITXT,01,01,70,Leaving a DSC Receivable Window^2C Chan A*7E'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'message': 'TXT',
        'sen_num': 1,
        'sen_tot': 1,
        'seq_num': 70,
        'talker': 'AI',
        'text': 'Leaving a DSC Receivable Window^2C Chan A'})
示例#8
0
 def testDecode(self):
   line = '$ANABK,,A,8,4,3*15'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'ack_type': 3,
        'chan': 'A',
        'mmsi': None,
        'message_id': 8,
        'message': 'ABK',
        'seq_num': 4,
        'talker': 'AN'})
示例#9
0
 def testDecodeA(self):
   line = '$ARFSR,r17MANP1,000001,A,0005,0,0035,,,-128,*66'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'chan': 'A',
        'crc_fails': 35,
        'id': 'r17MANP1',
        'message': 'FSR',
        'noise_db': -128,
        'slots_recv': 5,
        'slots_self': 0,
        'time': datetime.time(0, 0, 1)})
示例#10
0
 def testDecode(self):
   line = '!UPBBM,1,1,2,0,8,Fv4:3s3QJr<R@GoB64vT80,4*22'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'body': 'Fv4:3s3QJr<R@GoB64vT80',
        'chan': 0,
        'fill_bits': 4,
        'message': 'BBM',
        'message_id': 8,
        'sen_num': 1,
        'sen_tot': 1,
        'seq_num': 2,
        'talker': 'UP'})
示例#11
0
 def testDecodeFull(self):
   line = '$SAFSR,D09MN-SM-GULBS1,000000,B,115,3,5,86,3,-121,124*1F'
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'chan': 'B',
        'crc_fails': 5,
        'id': 'D09MN-SM-GULBS1',
        'message': 'FSR',
        'noise_db': -121,
        'slots_above_noise': 124,
        'slots_recv': 115,
        'slots_reserved': 86,
        'slots_reserved_self': 3,
        'slots_self': 3,
        'time': datetime.time(0, 0)})
示例#12
0
 def testDecode(self):
   line = (
       '$GPGGA,174246.00,7119.6369,N,15640.8432,W,1,06,2.39,00011,M,000,M,,'
       '*7D')
   message = nmea_messages.DecodeLine(line)
   self.assertEqual(
       message,
       {'antenna_height': 11,
        'antenna_height_units': 'M',
        'geoidal_height': 0,
        'geoidal_height_units': 'M',
        'gps_quality': 1,
        'hdop': 2.39,
        'latitude': 71.32728166666666,
        'longitude': -156.68072,
        'message': 'GGA',
        'satellites': 6,
        'time': datetime.time(17, 42, 46)})
示例#13
0
    def put(self, line, line_num=None):
        """Add a line of NMEA or raw text to the queue."""

        if line_num is not None:
            self.line_num = line_num
        else:
            self.line_num += 1
            line_num = self.line_num

        line = line.rstrip()
        match = Parse(line)

        if not match:
            logger.info('No VDM match for line: %d, %s', line_num, line)
            msg = {'line_nums': [line_num], 'lines': [line]}
            decoded = nmea_messages.DecodeLine(line)
            if decoded:
                msg['decoded'] = decoded
            else:
                logger.info('No NMEA match for line: %d, %s', line_num, line)
            Queue.Queue.put(self, msg)
            return

        sentence_total = int(match['sen_tot'])
        if sentence_total == 1:
            body = match['body']
            fill_bits = int(match['fill_bits'])
            try:
                decoded = ais.decode(body, fill_bits)
            except ais.DecodeError as error:
                logger.error('Unable to decode message: %s\n  %d %s', error,
                             line_num, line)
                return
            decoded['md5'] = hashlib.md5(body.encode('utf-8')).hexdigest()
            Queue.Queue.put(
                self, {
                    'line_nums': [line_num],
                    'lines': [line],
                    'decoded': decoded,
                    'matches': [match]
                })
            return

        sentence_num = int(match['sen_num'])
        group_id = int(match['seq_id'])

        if sentence_num == 1:
            if group_id in self.groups:
                logger.error(
                    'Incomplete message overwritten by new start.  '
                    'Dropped:\n  %s', self.groups[group_id])
            self.groups[group_id] = {
                'line_nums': [line_num],
                'lines': [line],
                'matches': [match]
            }
            return

        if group_id not in self.groups:
            logger.error(
                'Do not have the prior lines in group_id %d. '
                'Dropping: \n  %s', group_id, line)
            return

        entry = self.groups[group_id]
        if len(entry['lines']) != sentence_num - 1:
            logger.error('Out of sequence message.  Dropping: %d != %d \n %s',
                         len(entry['lines']), sentence_num - 1, line)
            return

        entry['lines'].append(line)
        entry['matches'].append(match)
        entry['line_nums'].append(line_num)

        if sentence_num != sentence_total:
            # Nothing more to do in the middle of a sequence of sentences.
            return

        body = ''.join([match['body'] for match in entry['matches']])
        fill_bits = int(entry['matches'][-1]['fill_bits'])
        try:
            decoded = ais.decode(body, fill_bits)
        except ais.DecodeError as error:
            logger.error('Unable to decode message: %s\n%s', error, entry)
            return
        decoded['md5'] = hashlib.md5(body.encode('utf-8')).hexdigest()
        entry['decoded'] = decoded

        # Found the final message in a group.
        Queue.Queue.put(self, entry)
        self.groups.pop(group_id)
示例#14
0
 def testAlmostReal(self):
   line = '$AAZZZ,JUNK*73'
   message = nmea_messages.DecodeLine(line)
   self.assertIsNone(message)
示例#15
0
 def testEmpty(self):
   line = ''
   message = nmea_messages.DecodeLine(line)
   self.assertIsNone(message)
示例#16
0
 def testJunk(self):
   line = '!@#$($#&^%('
   message = nmea_messages.DecodeLine(line)
   self.assertIsNone(message)
示例#17
0
    def put(self, line, line_num=None):
        if line_num is not None:
            self.line_num = line_num
        else:
            self.line_num += 1

        line = line.rstrip()
        match = Parse(line)

        if not match:
            Queue.Queue.put(self, {
                'line_nums': [self.line_num],
                'lines': [line],
            })
            return

        time = util.MaybeToNumber(match['time'])

        if not match['group']:
            msg = {
                'line_nums': [self.line_num],
                'lines': [line],
                'matches': [match],
                'times': [time],
            }
            decoded = DecodeTagSingle(msg)
            if decoded:
                msg['decoded'] = decoded
            else:
                logger.info('Unable to decode. Passing without decoded block.')
                decoded = nmea_messages.DecodeLine(match['payload'])
                if decoded:
                    msg['decoded'] = decoded
                else:
                    logger.info('No NMEA match for line: %d, %s', line_num,
                                line)
            Queue.Queue.put(self, msg)
            return

        sentence_num = int(match['sentence_num'])
        sentence_total = int(match['sentence_tot'])
        group_id = int(match['group_id'])

        if sentence_num == 1:
            self.groups[group_id] = {
                'line_nums': [self.line_num],
                'lines': [line],
                'matches': [match],
                'times': [time],
            }
            return

        if group_id not in self.groups:
            logger.error('group_id not in groups: %d', group_id)
            return

        entry = self.groups[group_id]
        entry['line_nums'].append(self.line_num)
        entry['lines'].append(line)
        entry['matches'].append(match)
        entry['times'].append(time)

        if sentence_num != sentence_total:
            # Found the middle part of a message.
            return

        # Found the final message in a group.
        decoded = DecodeTagMultiple(entry)
        if decoded:
            entry['decoded'] = decoded
        else:
            logger.info('Unable to process: %s', entry)
        Queue.Queue.put(self, entry)
        self.groups.pop(group_id)