def test_get_bytearray(self): self.assertEqual(Calculator.get_bytearray(0), bytearray(b'\x00')) self.assertEqual(Calculator.get_bytearray(1), bytearray(b'\x01')) self.assertEqual(Calculator.get_bytearray(22), bytearray(b'\x16')) self.assertEqual(Calculator.get_bytearray(222222222), bytearray(b'\x0d\x3e\xd7\x8e')) self.assertEqual(Calculator.get_bytearray(12345), bytearray(b'\x30\x39'))
def verify_checksum(self, data: Data): data_type = '0' + str(data.msg_code) data_for_checksum = data_type + data.data_payload byte_len = int( len(data_for_checksum) / GlobalConstants.HEX_DIGITS_PER_BYTE) dec_num = Calculator.get_int(data_for_checksum) data_int = Calculator.get_bytearray(dec_num, byte_len) expected_checksum = Checksum.crc32(data_int) return data.checksum == expected_checksum
def analyse_heartbeat(self, data_payload: str): period = StrManipulator.substring( data_payload, GlobalConstants.HEARTBEAT_PERIOD_START, GlobalConstants.HEARTBEAT_PERIOD_END) period = Calculator.get_int(period) self.curr_heartbeat_period = DataStructFunctions.get_key( GlobalConstants.HEARTBEAT_PERIODS, period) id = StrManipulator.substring(data_payload, GlobalConstants.HEARTBEAT_ID_START, GlobalConstants.HEARTBEAT_ID_END) id = Calculator.get_int(id) heartbeat = DataPacketFactory.get_packet('HEARTBEAT_RESPONSE', params={'heartbeat_id': id}) return heartbeat
def get_heartbeat_request(params): heartbeat_id = params['heartbeat_id'] curr_heartbeat_period = params['heartbeat_period'] data = DataPacketFactory.init_packet() data.append( GlobalConstants.MESSAGE_CODE_DICT['HEARTBEAT_REQUEST']) # msg_code data_content = Calculator.get_bytearray(curr_heartbeat_period, 1) + Calculator.get_bytearray( heartbeat_id, 4) DataPacketFactory.append_data(data, data_content) data.append(0x81) # end_code DataPacketFactory.append_len(data) DataPacketFactory.append_checksum(data) return data
def extract_packet_length(self, data_header: str): self.packet_len = StrManipulator.substring( data_header, GlobalConstants.PACKET_LEN_START_INDEX, GlobalConstants.PACKET_LEN_END_INDEX) int_len = Calculator.get_int(self.packet_len) # number of hex digits self.len_of_hex = int_len * 2
def analyse_data_payload(self, curr_data_item): data_payload = curr_data_item.data_payload # split the data string into chunks of length 4 index_list = StrManipulator.split_string( data_payload, GlobalConstants.PAYLOAD_INDICES_LEN) if not index_list: return True index_list = StrManipulator.remove_every_other(index_list) index_list = list(map(Calculator.get_int, index_list)) # generate a sequence of numbers according to data buffer length # (number of data chunks) packet_len = Calculator.get_int(curr_data_item.packet_len) BYTES_PER_DATA_CHUNK = 2 data_payload_len = packet_len - GlobalConstants.DATA_PARAMS_LEN num_seq_len = data_payload_len / BYTES_PER_DATA_CHUNK # divide by 2 because of taking into account every other num num_seq_len /= 2 num_seq_len = int(num_seq_len) num_seq = list(range(0, num_seq_len)) if index_list != num_seq: self.add_com_error('UNORDERED DATA CONTENT') return False return True
def analyse_data(self): data = '' expected_data_len = GlobalConstants.HEX_DIGITS_PER_BYTE * GlobalConstants.MAX_PACKET_LEN + 1 data_len_hex = '' while True: if not self.serial_port: continue new_data = self.read_data_queue.get() if new_data: if self.new_data_to_read: if new_data == GlobalConstants.START_CODE: data += new_data self.new_data_to_read = False else: if len(data) < expected_data_len: data += new_data # extract if GlobalConstants.PACKET_LEN_START_INDEX <= len( data) <= GlobalConstants.PACKET_LEN_END_INDEX: data_len_hex += new_data if len(data) == GlobalConstants.DATA_COUNTER_END_INDEX: expected_data_len = Calculator.get_int( data_len_hex ) * GlobalConstants.HEX_DIGITS_PER_BYTE if len(data) == expected_data_len: data_packet = Data(data) self.analyse_data_purpose(data_packet) # clear data self.new_data_to_read = True data = '' expected_data_len = GlobalConstants.HEX_DIGITS_PER_BYTE * GlobalConstants.MAX_PACKET_LEN + 1 data_len_hex = ''
def extract_message_code(self, data_header: str): msg_code = StrManipulator.substring( data_header, GlobalConstants.MSG_CODE_START_INDEX, GlobalConstants.MSG_CODE_END_INDEX) msg_code = Calculator.get_int(msg_code) self.msg_code = msg_code self.purpose = DataStructFunctions.get_key( GlobalConstants.MESSAGE_CODE_DICT, msg_code)
def classify_data(self): data_type = self.curr_data.purpose if not data_type == 'HEARTBEAT': self.data_arr.append(self.curr_data) if data_type == 'ECC_CHECKED': self.mem_error_storage.add(self.curr_data.data_payload_value) elif data_type == 'RESET_RESPONSE': payload_int = Calculator.get_int(self.curr_data.data_payload_value) reset_purpose = GlobalConstants.RESET_PURPOSES[payload_int] reset_packet = ResetData(reset_purpose) self.reset_storage.add(reset_packet)
def get_reset_response(params): data = DataPacketFactory.init_packet() data.append( GlobalConstants.MESSAGE_CODE_DICT['RESET_RESPONSE']) #msg_code reset_reason = params['reset_reason'] reset_reason = Calculator.get_bytearray(reset_reason, 1) DataPacketFactory.append_data(data, reset_reason) data.append(0x81) DataPacketFactory.append_len(data) DataPacketFactory.append_checksum(data) return data
def get_heartbeat_response(params): heartbeat_id = params['heartbeat_id'] data = DataPacketFactory.init_packet() data.append(GlobalConstants.MESSAGE_CODE_DICT['HEARTBEAT_RESPONSE'] ) # msg_code DataPacketFactory.append_data( data, Calculator.get_bytearray(heartbeat_id, 4)) data.append(0x81) # end_code DataPacketFactory.append_len(data) DataPacketFactory.append_checksum(data) return data
def get_ecc_period_change(params=[]): period_id = params['period_id'] data = DataPacketFactory.init_packet() data.append( GlobalConstants.MESSAGE_CODE_DICT['ECC_PERIOD_CHANGE']) # msg_code DataPacketFactory.append_data( data, Calculator.get_bytearray(period_id, bytelen=1)) data.append(0x81) # end_code DataPacketFactory.append_len(data) DataPacketFactory.append_checksum(data) return data
def append_data(data: bytearray, data_content: bytearray): data_content_paired = list(DataStructFunctions.chunk(data_content, 2)) num_seq = range(0, len(data_content_paired)) num_seq = list( map(lambda x: Calculator.get_bytearray(x, bytelen=2), num_seq)) i = 0 while i < len(num_seq): cur_index = num_seq[i] cur_data = data_content_paired[i] data += cur_index data += cur_data i += 1
def send_data_packet(self, data: bytearray): if not self.com_interface.is_connected(): return False data_str = Calculator.get_hex_str(data) curr_time = Time.get_curr_time() print(str(curr_time) + ' sent data: ' + data_str) DataPacketFactory.adjust_data_cnt(data, self.sent_counter) self.com_interface.send_data(data) self.last_sent_time = Time.get_curr_time_ns() if self.sent_counter >= GlobalConstants.DATA_INDEX_MAX: self.sent_counter = 0 else: self.sent_counter += 1 return True
def get_ecc_check(params=[]): index = params['index'] err_cnt = params['err_cnt'] overflow = params['overflow'] ecc_addresses_str = params['ecc_addresses'] ecc_addresses = Calculator.get_int(ecc_addresses_str) data = DataPacketFactory.init_packet() data.append( GlobalConstants.MESSAGE_CODE_DICT['ECC_CHECKED']) # msg_code data_content = Calculator.get_bytearray(index, bytelen=2) data_content += Calculator.get_bytearray(err_cnt, bytelen=3) overflow_byte = 0 if overflow else 1 data_content += Calculator.get_bytearray(overflow_byte, bytelen=1) data_content += Calculator.get_bytearray( ecc_addresses, bytelen=int(len(ecc_addresses_str) / 2)) DataPacketFactory.append_data(data, data_content) data.append(0x81) # end_code DataPacketFactory.append_len(data) DataPacketFactory.append_checksum(data) return data
def check_heartbeat(self, curr_data_item: Data): """ if current data is HEARTBEAT_RESPONSE, extracts HEARTBEAT_ID and notifies observers :param curr_data_item: """ HEARTBEAT_RESPONSE_CODE = GlobalConstants.MESSAGE_CODE_DICT[ 'HEARTBEAT_RESPONSE'] if curr_data_item.msg_code == HEARTBEAT_RESPONSE_CODE: curr_data_item.extract_data_payload() heartbeat = curr_data_item.data_payload_value heartbeat = Calculator.get_int(heartbeat) self.heartbeat_received_id = heartbeat self.notify()
def extract_checksum(self, data_header: str): checksum = StrManipulator.substring( data_header, GlobalConstants.CHECKSUM_START_INDEX, GlobalConstants.CHECKSUM_END_INDEX) self.checksum = Calculator.get_int(checksum)
def extract_err_cnt(self): cnt = StrManipulator.substring(self.data, GlobalConstants.ERROR_CNT_START, GlobalConstants.ERROR_CNT_END) cnt = Calculator.get_int(cnt) self.error_num = cnt
def extract_data_counter(self, data_header: str): data_index = StrManipulator.substring( data_header, GlobalConstants.DATA_COUNTER_START_INDEX, GlobalConstants.DATA_COUNTER_END_INDEX) self.data_index = Calculator.get_int(data_index) self.data_index_hex = data_index