SignalInitTableCheck.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # -*- coding: UTF-8 -*-
  2. """
  3. @Project :Matrix_Check
  4. @File :SignalInitTableCheck.py
  5. @Author :haojiang
  6. @Date :2022/9/28 18:15
  7. """
  8. import csv
  9. import os
  10. from enum import Enum
  11. import logging
  12. class TableColumnHeaderType(Enum):
  13. Signal = 0
  14. Type = 1
  15. Bit = 2
  16. App = 3
  17. AppValue = 4
  18. Raw = 5
  19. RawValue = 6
  20. Controller = 7
  21. Frame = 8
  22. PDU = 9
  23. class SignalInitValueTableCheck:
  24. Column_Need_Check = [TableColumnHeaderType.Signal,
  25. TableColumnHeaderType.Type,
  26. TableColumnHeaderType.Bit,
  27. TableColumnHeaderType.RawValue]
  28. # is signed
  29. Type_Mapping = {
  30. 'Boolean': False,
  31. 'UInt': False,
  32. 'SInt': True,
  33. 'Composite': None,
  34. 'Bytes': None
  35. }
  36. def __init__(self, project_path: str):
  37. self.project = project_path
  38. def _is_raw_value_missing(self, raw_value: str, signal_type: str) -> bool:
  39. if raw_value == '' and signal_type != 'Composite':
  40. return True
  41. else:
  42. return False
  43. def _format_raw_value(self, raw_value: str):
  44. ret_value = raw_value.replace('(', '').replace(')', '').upper()
  45. if ret_value in ['TRUE', 'FALSE']:
  46. ret_value = bool(ret_value)
  47. else:
  48. ret_value = self._format_str_to_number(ret_value)
  49. return ret_value
  50. def _format_str_to_number(self, str_num) -> int:
  51. try:
  52. ret = int(str_num)
  53. return ret
  54. except ValueError as e:
  55. # logging.error(f'Transform str {str_num} to number failed!')
  56. pass
  57. def check_row(self, row: dict) -> bool:
  58. ret = False
  59. # raw missing validation
  60. raw_value = row[TableColumnHeaderType.RawValue.name]
  61. # logging.error('raw_value' + raw_value)
  62. # type validation, between[Boolean Composite SInt UInt Bytes]
  63. signal_value_type = row[TableColumnHeaderType.Type.name]\
  64. is_raw_missing = self._is_raw_value_missing(raw_value, signal_value_type)
  65. if is_raw_missing:
  66. logging.error(f'Signal Raw value missing!{row.values()}')
  67. else:
  68. raw_number = self._format_raw_value(raw_value)
  69. if signal_value_type in SignalInitValueTableCheck.Type_Mapping.keys():
  70. if SignalInitValueTableCheck.Type_Mapping[signal_value_type] == None:
  71. ret = True
  72. else:
  73. signal_bit_len_str = row[TableColumnHeaderType.Bit.name]
  74. signal_bit_len = self._format_str_to_number(signal_bit_len_str)
  75. range_min, range_max = self._get_range_by_bit_length(signal_bit_len)
  76. if raw_number >= range_min and raw_number <= range_max:
  77. ret = True
  78. else:
  79. logging.error(f'Signal Raw value out of range!{row.values()}')
  80. else:
  81. logging.error(f'Unkonw Signal Type!{row.values()}')
  82. return ret
  83. def get_signal_init_value_table(self) -> list:
  84. rx_file, tx_file = self.get_rx_tx_csv_file_name()
  85. rx_file = os.path.join(self.project, rx_file)
  86. tx_file = os.path.join(self.project, tx_file)
  87. if not os.path.isfile(rx_file) \
  88. or not os.path.isfile(tx_file):
  89. logging.error(f'rx_csv {rx_file}, tx_csv {tx_file}')
  90. logging.error('Can not find rx or tx init value csv file!')
  91. return []
  92. else:
  93. rx_data = self.get_csv_data(rx_file)
  94. tx_data = self.get_csv_data(tx_file)
  95. rx_data.extend(tx_data)
  96. return rx_data
  97. def get_rx_tx_csv_file_name(self) -> tuple:
  98. files = os.listdir(self.project)
  99. rx_csv = ''
  100. tx_csv = ''
  101. for file in files:
  102. file_name_upper = file.upper()
  103. if 'RX' in file_name_upper and 'ARXML' not in file_name_upper:
  104. rx_csv = file
  105. if 'TX' in file_name_upper:
  106. tx_csv = file
  107. return (rx_csv, tx_csv)
  108. def get_csv_data(self, file_name: str) -> list:
  109. with open(file_name, 'r') as csvfile:
  110. spamreader = csv.reader(csvfile, delimiter=',')
  111. is_header_readed = False
  112. table_data = list()
  113. for row in spamreader:
  114. if not is_header_readed:
  115. is_header_readed = True
  116. continue
  117. row_data = dict()
  118. for col in SignalInitValueTableCheck.Column_Need_Check:
  119. row_data[col.name] = row[col.value]
  120. table_data.append(row_data)
  121. return table_data
  122. def _get_range_by_bit_length(self, bit_len: int, is_signed: bool = False):
  123. # [0, 2^n-1] 2^n = 1<<n
  124. # [-2^{n-1}, 2^{n-1}-1]
  125. if is_signed:
  126. return (-(1<<(bit_len-1)), (1<<(bit_len-1))-1)
  127. else:
  128. return (0, (1<<bit_len)-1)
  129. if __name__ == '__main__':
  130. matrix_path = r'E:\Project\ZP22HEV\V3.1\ZP22_HEV_V3.1a\Mat\20220606_gx2_ZP22 HEV_SecOC-GW-V01.3'
  131. sc = SignalInitValueTableCheck(matrix_path)
  132. data = sc.get_signal_init_value_table()
  133. for row in data:
  134. sc.check_row(row)