PMParameter.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. """
  2. Created on 29-03-2013
  3. @author: citan
  4. """
  5. import re
  6. from pimonitor.PMPacket import PMPacket
  7. class PMParameter(object):
  8. """
  9. classdocs
  10. """
  11. def __init__(self, pid, name, desc, byte_index, bit_index, target):
  12. """
  13. Constructor
  14. """
  15. self._id = pid
  16. self._name = name
  17. self._desc = desc
  18. self._byte_index = byte_index
  19. self._bit_index = bit_index
  20. self._target = target
  21. self._conversions = []
  22. self._dependencies = []
  23. self._parameters = []
  24. self._address = 0
  25. self._address_length = 0
  26. self._ecu_ids = {}
  27. def get_id(self):
  28. return self._id
  29. def set_address(self, address, length):
  30. self._address = address
  31. self._address_length = length
  32. def get_address(self):
  33. return self._address
  34. def get_address_length(self):
  35. return self._address_length
  36. def get_target(self):
  37. return self._target
  38. def get_name(self):
  39. return self._name
  40. def add_conversion(self, conversion):
  41. self._conversions.append(conversion)
  42. def add_dependency(self, dependency):
  43. self._dependencies.append(dependency)
  44. def get_dependencies(self):
  45. return self._dependencies
  46. def add_parameter(self, parameter):
  47. self._parameters.append(parameter)
  48. def get_parameters(self):
  49. return self._parameters
  50. def init_ecu_id(self, ecu_id):
  51. self._ecu_ids[ecu_id] = []
  52. def get_ecu_id(self, ecu_id):
  53. return self._ecu_ids[ecu_id]
  54. def get_calculated_value(self, packets, unit=None):
  55. value = ""
  56. local_vars = locals()
  57. if len(self._conversions) > 0 and unit is None:
  58. unit = self._conversions[0][0]
  59. for conversion in self._conversions:
  60. currunit = conversion[0]
  61. expr = conversion[1]
  62. value_format = conversion[2]
  63. conversion_map = {}
  64. if unit == currunit:
  65. param_pairs = re.findall(r'\[([^]]*)\]', expr)
  66. for pair in param_pairs:
  67. attributes = pair.split(":")
  68. key = attributes[0]
  69. unit = attributes[1]
  70. expr = expr.replace("[" + key + ":" + unit + "]", key)
  71. conversion_map.update({key: unit})
  72. param_no = 0
  73. for packet in packets:
  74. param = self._parameters[param_no]
  75. if param.get_id() in conversion_map:
  76. conversion_unit = conversion_map[param.get_id()]
  77. else:
  78. conversion_unit = None
  79. if param.get_dependencies():
  80. return "DEPS :("
  81. else:
  82. value = param.get_value(packet, conversion_unit)
  83. local_vars[param.get_id()] = float(value)
  84. param_no += 1
  85. try:
  86. value = eval(expr)
  87. except (SyntaxError, ZeroDivisionError):
  88. value = 0.0
  89. format_tokens = value_format.split(".")
  90. output_format = "%.0f"
  91. if len(format_tokens) > 1:
  92. output_format = "%." + str(len(format_tokens[1])) + "f"
  93. value = output_format % value
  94. return value
  95. # noinspection PyUnusedLocal
  96. def get_value(self, packet, unit=None):
  97. value = ""
  98. if len(self._conversions) > 0 and unit is None:
  99. unit = self._conversions[0][0]
  100. for conversion in self._conversions:
  101. currunit = conversion[0]
  102. expr = conversion[1]
  103. value_format = conversion[2]
  104. if unit == currunit:
  105. # ignore 0xe8
  106. index = 1
  107. x = 0
  108. value_bytes = packet.get_data()[index:index + self._address_length]
  109. if self._address_length == 1:
  110. x = value_bytes[0]
  111. if self._address_length == 2:
  112. x = (value_bytes[0] << 8) | value_bytes[1]
  113. if self._address_length == 4:
  114. x = (value_bytes[0] << 24) | (value_bytes[1] << 16) | (value_bytes[2] << 8) | value_bytes[2]
  115. try:
  116. value = eval(expr)
  117. except (SyntaxError, ZeroDivisionError):
  118. value = 0.0
  119. format_tokens = value_format.split(".")
  120. output_format = "%.0f"
  121. if len(format_tokens) > 1:
  122. output_format = "%." + str(len(format_tokens[1])) + "f"
  123. value = output_format % value
  124. return value
  125. def get_default_unit(self):
  126. if len(self._conversions) > 0:
  127. return self._conversions[0][0]
  128. return ""
  129. def switch_to_ecu_id(self, ecu_id):
  130. if ecu_id in self._ecu_ids:
  131. ecu_id_data = self._ecu_ids[ecu_id]
  132. self._address = ecu_id_data[0]
  133. self._address_length = ecu_id_data[1]
  134. def is_supported(self, data):
  135. if self._byte_index != "none" and self._bit_index != "none" and len(data) - 1 > self._byte_index:
  136. cubyte = data[1 + self._byte_index]
  137. bitmask = 1 << self._bit_index
  138. return cubyte & bitmask == bitmask
  139. elif self._ecu_ids is not None:
  140. return PMPacket.extract_rom_id(data) in self._ecu_ids
  141. else:
  142. return False
  143. def to_string(self):
  144. return "Param: id=" + self._id + ", name=" + self._name + ", desc=" + self._desc + ", byte=" + str(
  145. self._byte_index) + \
  146. ", bit=" + str(self._bit_index) + ", target=" + str(
  147. self._target) + ", conversions=" + '[%s]' % ', '.join(map(str, self._conversions)) + \
  148. ", address=" + hex(self._address) + "[" + str(self._address_length) + "]"