123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- # -*- 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<<n
- # [-2^{n-1}, 2^{n-1}-1]
- if is_signed:
- return (-(1 << (bit_len - 1)), (1 << (bit_len - 1)) - 1)
- else:
- return (0, (1 << bit_len) - 1)
- def _is_signal_value_missing(self, raw_value: str, signal_type: str) -> 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()
|