# -*- coding: UTF-8 -*- """ @Project :Matrix_Check @File :SignalInitTableCheck.py @Author :haojiang @Date :2022/9/28 18:15 """ import csv import os from enum import Enum import logging class TableColumnHeaderType(Enum): Signal = 0 Type = 1 Bit = 2 App = 3 AppValue = 4 Raw = 5 RawValue = 6 Controller = 7 Frame = 8 PDU = 9 class SignalInitValueTableCheck: Column_Need_Check = [TableColumnHeaderType.Signal, TableColumnHeaderType.Type, TableColumnHeaderType.Bit, TableColumnHeaderType.RawValue] # is signed Type_Mapping = { 'Boolean': False, 'UInt': False, 'SInt': True, 'Composite': None, 'Bytes': None } def __init__(self, project_path: str): self.project = project_path def _is_raw_value_missing(self, raw_value: str, signal_type: str) -> bool: if raw_value == '' and signal_type != 'Composite': return True else: return False def _format_raw_value(self, raw_value: str): ret_value = raw_value.replace('(', '').replace(')', '').upper() if ret_value in ['TRUE', 'FALSE']: ret_value = bool(ret_value) else: ret_value = self._format_str_to_number(ret_value) return ret_value def _format_str_to_number(self, str_num) -> int: try: ret = int(str_num) return ret except ValueError as e: # logging.error(f'Transform str {str_num} to number failed!') pass def check_row(self, row: dict) -> bool: ret = False # raw missing validation raw_value = row[TableColumnHeaderType.RawValue.name] # logging.error('raw_value' + raw_value) # type validation, between[Boolean Composite SInt UInt Bytes] signal_value_type = row[TableColumnHeaderType.Type.name]\ is_raw_missing = self._is_raw_value_missing(raw_value, signal_value_type) if is_raw_missing: logging.error(f'Signal Raw value missing!{row.values()}') else: raw_number = self._format_raw_value(raw_value) if signal_value_type in SignalInitValueTableCheck.Type_Mapping.keys(): if SignalInitValueTableCheck.Type_Mapping[signal_value_type] == None: ret = True else: signal_bit_len_str = row[TableColumnHeaderType.Bit.name] signal_bit_len = self._format_str_to_number(signal_bit_len_str) range_min, range_max = self._get_range_by_bit_length(signal_bit_len) if raw_number >= range_min and raw_number <= range_max: ret = True else: logging.error(f'Signal Raw value out of range!{row.values()}') else: logging.error(f'Unkonw Signal Type!{row.values()}') return ret def get_signal_init_value_table(self) -> list: rx_file, tx_file = self.get_rx_tx_csv_file_name() rx_file = os.path.join(self.project, rx_file) tx_file = os.path.join(self.project, tx_file) if not os.path.isfile(rx_file) \ or not os.path.isfile(tx_file): logging.error(f'rx_csv {rx_file}, tx_csv {tx_file}') logging.error('Can not find rx or tx init value csv file!') return [] else: rx_data = self.get_csv_data(rx_file) tx_data = self.get_csv_data(tx_file) rx_data.extend(tx_data) return rx_data def get_rx_tx_csv_file_name(self) -> tuple: files = os.listdir(self.project) rx_csv = '' tx_csv = '' for file in files: file_name_upper = file.upper() if 'RX' in file_name_upper and 'ARXML' not in file_name_upper: rx_csv = file if 'TX' in file_name_upper: tx_csv = file return (rx_csv, tx_csv) def get_csv_data(self, file_name: str) -> list: with open(file_name, 'r') as csvfile: spamreader = csv.reader(csvfile, delimiter=',') is_header_readed = False table_data = list() for row in spamreader: if not is_header_readed: is_header_readed = True continue row_data = dict() for col in SignalInitValueTableCheck.Column_Need_Check: row_data[col.name] = row[col.value] table_data.append(row_data) return table_data def _get_range_by_bit_length(self, bit_len: int, is_signed: bool = False): # [0, 2^n-1] 2^n = 1<