示例#1
0
 def test_empty_value_for_cog(self):
     """
     this sentence doesn't appear to have a value for course over ground
     the binary module should raise a NoBinaryData exception
     """
     testsentence = '!AIVDM,1,1,,A,3O>soN5MUNBoMdUdlh,0*64'
     nmeatracker = nmea.NMEAtracker()
     testdata = nmeatracker.process_sentence(testsentence)
     testbinarystr = binary.ais_sentence_payload_binary(testdata)
     with self.assertRaises(binary.NoBinaryData):
         binary.decode_sixbit_integer(testbinarystr[116:128]) / 10
示例#2
0
 def __init__(self, msgbinary):
     self.msgbinary = msgbinary
     self.msgtype = binary.decode_sixbit_integer(msgbinary[0:6])
     self.repeatcount = binary.decode_sixbit_integer(msgbinary[6:8])
     self.mmsi = str(
         format(binary.decode_sixbit_integer(msgbinary[8:38]), '09d'))
     try:
         self.description = MSGDESCRIPTIONS[self.msgtype]
     except KeyError:
         self.description = 'Unknown'
     self.rxtime = 'N/A'
示例#3
0
    def process_message(self, data):
        """
        determine what type of AIS message it is

        Args:
            data(str): full message payload from 1 or more NMEA sentences

        Raises:
            InvalidMMSI: if the mmsi = 000000000

        Returns:
            msgobj(messages.aismessage.AISMessage): the ais message type object
        """
        msgbinary = binary.ais_sentence_payload_binary(data)
        msgtype = binary.decode_sixbit_integer(msgbinary[0:6])
        if msgtype in (4, 11):
            msgobj = allmessages.MSGTYPES[msgtype](msgbinary)
            if msgobj.mmsi == '000000000':
                raise InvalidMMSI('Invalid MMSI - 000000000')
            if msgobj.mmsi not in self.stations:
                self.stations[msgobj.mmsi] = AISStation(msgobj.mmsi)
            if self.stations[msgobj.mmsi].stnclass == 'Unknown':
                self.stations[msgobj.mmsi].determine_station_class(msgobj)
            msgobj.rxtime = msgobj.timestamp
            self.stations[msgobj.mmsi].find_position_information(msgobj)
            self.messagesprocessed += 1
            self.messages[allmessages.MSGDESCRIPTIONS[msgtype]] += 1
示例#4
0
def decode_turn_rate(rawvalue):
    """
    decode the turn rate value to something meaningful

    Args:
        rawvalue(str): turn rate encoded as binary string

    Returns:
        turnvalue(str): actual turn rate of the vessel
    """
    decodedturnrate = binary.decode_sixbit_integer(rawvalue)
    decodedvalues = {
        0: 'not turning', 128: 'no turn rate available',
        127: ('turning right at more than 10 degrees per minute'
              ' - NO TURN INDICATOR'),
        129: ('turning left at more than -10 degrees per minute'
              ' - NO TURN INDICATOR')}
    if decodedturnrate in decodedvalues:
        turnvalue = decodedvalues[decodedturnrate]
    else:
        twos = binary.decode_twos_complement(rawvalue)
        rot = (twos / 4.733) ** 2
        if rawvalue[0] == '1':
            rot = rot * -1
            direction = 'left'
        else:
            direction = 'right'
        turnvalue = 'turning {} at {} degrees per minute'.format(
            direction, round(rot, 1))
    return turnvalue
示例#5
0
    def process_message(self, data, timestamp=None):
        """
        determine what type of AIS message it is

        Note:
            the timestamp can be given as an argument for each message to be
            processed or timings can be approximated from the last type 4/11
            base station report timestamp received. for the latter option it is
            preferred that you have a nearby base station transmitting the
            correct time on a regular interval

        Args:
            data(str): full message payload from 1 or more NMEA sentences
            timestamp(str): time this message was recieved, if provided this
                            will take precedence over timings received from AIS
                            base stations

        Raises:
            UnknownMessageType: if the message type is not in the
                                allmessages.MSGTYPES dict
            InvalidMMSI: if the mmsi = 000000000

        Returns:
            msgobj(messages.aismessage.AISMessage): the ais message type object
        """
        msgbinary = binary.ais_sentence_payload_binary(data)
        msgtype = binary.decode_sixbit_integer(msgbinary[0:6])
        if msgtype in allmessages.MSGTYPES.keys():
            msgobj = allmessages.MSGTYPES[msgtype](msgbinary)
        else:
            raise UnknownMessageType(
                'Unknown message type {} - {}'.format(msgtype, data))
        if msgobj.mmsi == '000000000':
            raise InvalidMMSI('Invalid MMSI - 000000000')
        if msgobj.mmsi not in self.stations:
            self.stations[msgobj.mmsi] = AISStation(msgobj.mmsi)
        if self.stations[msgobj.mmsi].stnclass == 'Unknown':
            self.stations[msgobj.mmsi].determine_station_class(msgobj)
        if (self.stations[msgobj.mmsi].stntype == 'Unknown' or
                self.stations[msgobj.mmsi].name == ''):
            self.stations[msgobj.mmsi].find_station_name_and_type(msgobj)
        if timestamp:
            if timestamp not in self.timings:
                self.timings.append(timestamp)
        else:
            if msgtype in (4, 11) and msgobj.mmsi in self.timingsource:
                if (msgobj.timestamp != TIMEUNAVAILABLE and
                        msgobj.timestamp not in self.timings and
                        kml.DATETIMEREGEX.match(msgobj.timestamp)):
                    self.timings.append(msgobj.timestamp + ' (estimated)')
            try:
                timestamp = self.timings[len(self.timings) - 1]
            except IndexError:
                timestamp = 'N/A'
        msgobj.rxtime = timestamp
        self.stations[msgobj.mmsi].find_position_information(msgobj)
        self.messagesprocessed += 1
        self.messages[allmessages.MSGDESCRIPTIONS[msgtype]] += 1
        return msgobj
示例#6
0
 def test_sixbit_integer_decoding(self):
     """
     tests converting from binary into integer
     """
     binstr = '000001100'
     expected = 12
     decoded = binary.decode_sixbit_integer(binstr[2:9])
     self.assertEqual(expected, decoded)
示例#7
0
    def decode_sixbit_integer(binarystr):
        """
        a wrapper for binary.decode_sixbit_intger
        adds exception handling

        Note:
            if we get a no binary data exception simply return a 0
        """
        try:
            returnval = binary.decode_sixbit_integer(binarystr)
        except binary.NoBinaryData:
            returnval = 0
        return returnval