def ais_to_nmea_0183(payload: str, ais_talker_id: str, radio_channel: str, fill_bits: int) -> AIS_SENTENCES: """ Splits the AIS payload into sentences, ASCII encodes the payload, creates and sends the relevant NMEA 0183 sentences. HINT: This method takes care of splitting large payloads (larger than 60 characters) into multiple sentences. With a total of 80 maximum chars excluding end of line per sentence, and 20 chars head + tail in the nmea 0183 carrier protocol, 60 chars remain for the actual payload. @param payload: Armored AIs payload. @param ais_talker_id: AIS talker ID (AIVDO or AIVDM) @param radio_channel: Radio channel (either A or B) @param fill_bits: The number of fill bits requires to pad the data payload to a 6 bit boundary. @return: A list of relevant AIS sentences. """ messages = [] max_len = 61 seq_id = '' frag_cnt = math.ceil(len(payload) / max_len) if len(ais_talker_id) != 5: raise ValueError( "AIS talker is must have exactly 6 characters. E.g. AIVDO") if len(radio_channel) != 1: raise ValueError("Radio channel must be a single character") for frag_num, chunk in enumerate(chunks(payload, max_len), start=1): tpl = "!{},{},{},{},{},{},{}*{:02X}" dummy_message = tpl.format(ais_talker_id, frag_cnt, frag_num, seq_id, radio_channel, chunk, fill_bits, 0) checksum = compute_checksum(dummy_message) msg = tpl.format(ais_talker_id, frag_cnt, frag_num, seq_id, radio_channel, chunk, fill_bits, checksum) messages.append(msg) return messages
def is_valid(self) -> bool: return self.checksum == compute_checksum(self.raw)