# -*- 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 from pandas import DataFrame import pandas as pd from Base.MatrixParser import MatrixParser class SignalAttrType(Enum): SIGNAL_NAME = 0 SIGNAL_TYPE = 1 SIGNAL_BIT_LEN = 2 SIGNAL_VALUE = 3 class SignalValueCheck: # is signed Type_Mapping = { 'Boolean': False, 'UInt': False, 'SInt': True, 'Composite': None, 'Bytes': None } def __init__(self, signal_attr: dict): self.signal_attr = signal_attr def _get_range_by_bit_length(self, bit_len: int, is_signed: bool = False): # [0, 2^n-1] 2^n = 1< bool: if raw_value == '' and signal_type != 'Composite': return True else: return False def _format_str_signal_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_attribute(self) -> bool: ret_status = False ret_code = 0 signal_name = self.signal_attr[SignalAttrType.SIGNAL_NAME.name] signal_type = self.signal_attr[SignalAttrType.SIGNAL_TYPE.name] signal_bit_len_str = self.signal_attr[SignalAttrType.SIGNAL_BIT_LEN.name] signal_value = self.signal_attr[SignalAttrType.SIGNAL_VALUE.name] # # 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_value_missing = self._is_signal_value_missing(signal_value, signal_type) if is_value_missing: logging.error(f'Signal {signal_name} Value missing!') ret_code = 1 else: value_number = self._format_str_signal_value(signal_value) if signal_type in SignalValueCheck.Type_Mapping.keys(): if SignalValueCheck.Type_Mapping[signal_type] == None: ret_status = True else: 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 value_number >= range_min and value_number <= range_max: ret_status = True else: logging.error(f'Signal {signal_name} value out of range!') ret_code = 2 else: logging.error(f'Unknown Signal Type! {signal_name}-{signal_type}' ) ret_code = 3 return (ret_status, ret_code) 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 = { SignalAttrType.SIGNAL_NAME: TableColumnHeaderType.Signal, SignalAttrType.SIGNAL_TYPE: TableColumnHeaderType.Type, SignalAttrType.SIGNAL_BIT_LEN: TableColumnHeaderType.Bit, SignalAttrType.SIGNAL_VALUE: TableColumnHeaderType.RawValue, } def __init__(self, project_path: str): self.project = project_path def get_signal_init_value_table(self) -> list: rx_file, tx_file = self.get_rx_tx_csv_file_name() 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) self.concat_two_csv_file(rx_file, tx_file) return rx_data def concat_two_csv_file(self, rx_csv, tx_csv): dtype = {'Signal': str, 'Type': str, 'L[bit]': str, 'App': str, 'App.Value': str, 'Raw': str, 'Raw.Value': str, 'Controller': str, 'Frame': str, 'PDU': str} rx_df = pd.read_csv(rx_csv, dtype=dtype) tx_df = pd.read_csv(tx_csv, dtype=dtype) all_df = pd.concat([rx_df, tx_df]) file_name = os.path.basename(rx_csv).split('.')[0] all_df.to_excel(f'./output/{file_name}-合并初值表.xls', index=False) 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 = os.path.join(self.project, file) if 'TX' in file_name_upper: tx_csv = os.path.join(self.project, 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 attr_name, attr_col_number in SignalInitValueTableCheck.Column_Need_Check.items(): row_data[attr_name.name] = row[attr_col_number.value] table_data.append(row_data) return table_data class MatrixSignalInitValueCheck: def _isignal_type_format(self, item): if item == 'BOOLEAN': return 'Boolean' if 'UINT' in item: return 'UInt' elif 'SINT' in item: return 'SInt' else: return None def get_signal_attr_data_by_dataframe(self, df: DataFrame): df['ISignal Type'] = df['ISignal Type'].apply(self._isignal_type_format) df.fillna('', inplace=True) table_data = [] for index, row in df.iterrows(): row_dict = dict() row_dict[SignalAttrType.SIGNAL_NAME.name] = str(row['Signal Name']) row_dict[SignalAttrType.SIGNAL_TYPE.name] = str(row['ISignal Type']) row_dict[SignalAttrType.SIGNAL_BIT_LEN.name] = str(row['ISignal Bit Length']) row_dict[SignalAttrType.SIGNAL_VALUE.name] = str(row['ISignal Init Value']) table_data.append(row_dict) return table_data if __name__ == '__main__': # matrix_path = r'D:\01_Work\02_WP\EP39_EREV\branch\src\MatrixAssistant_V2.0\EP39_EREV_SIMU+_GW' # # sc = SignalInitValueTableCheck(matrix_path) # # # data = sc.get_signal_init_value_table() # # for row in data: # # sc.check_row(row) # scb = SignalValueCheck(row) # scb.check_attribute() # mp = MatrixParser( # r'E:\Project\EP39\EP39_GW04_V1.1a_20220628_Integation\InputFiles\MA_20220607_qy1_EP39EV_simu_GWC-arxmal-V01.1.arxml') # mc = MatrixSignalInitValueCheck() df = pd.read_csv('test.csv', dtype=str) print(df.dtypes) all_data = mc.get_signal_attr_data_by_dataframe(df) for row in all_data: # print(row) scb = SignalValueCheck(row) scb.check_attribute()