generate_monitor_configure.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import sys
  2. import argparse
  3. from pathlib import Path
  4. from lxml import etree
  5. node_project = {
  6. "name": "project",
  7. "attr": {
  8. "name": "测试",
  9. "version": "V1.0.0",
  10. "description": "自动化生成测试画面监控配置文件"
  11. }
  12. }
  13. node_canvas = {
  14. "name": "canvas",
  15. "attr": {
  16. "width": "1280",
  17. "height": "720",
  18. "backgroundColor": "#000000",
  19. "name": "",
  20. "version": "V1.0.0",
  21. "description": "",
  22. "lastModified": "",
  23. "lastModifiedBy": "",
  24. "default": "0"
  25. }
  26. }
  27. label = {
  28. "name": "Label",
  29. "property": {
  30. "x": 0,
  31. "y": 0,
  32. "width": 800,
  33. "height": 20,
  34. "text": "",
  35. "font": "SimSun,9,-1,5,50,0,0,0,0,0",
  36. "fontColor": "#a0a0a4",
  37. "backgroundColor": "#00000000",
  38. "borderVisiable": "true",
  39. "borderColor": "#a0a0a4",
  40. "borderWidth": 1
  41. },
  42. "parameter": {
  43. "parameterName": [
  44. ]
  45. }
  46. }
  47. number = {
  48. "name": "Number",
  49. "property": {
  50. "x": 0,
  51. "y": 0,
  52. "width": 400,
  53. "height": 20,
  54. "rangeFirst": "[0, 1)",
  55. "rangeSecond": "[1, 2)",
  56. "rangeThird": "[2, 3)",
  57. "rangeFourth": "[3, 4)",
  58. "rangeFifth": "[4, 5]",
  59. "colorFirst": "#ff0000",
  60. "colorSecond": "#ffff00",
  61. "colorThird": "#00ff00",
  62. "colorFourth": "#ffff00",
  63. "colorFifth": "#ff0000",
  64. "oorColor": "#ffffff",
  65. "currentValue": 0,
  66. "backgroundColor": "#00000000",
  67. "unit": None,
  68. "borderVisible": True,
  69. "borderWidth": 2,
  70. "font": "SimSum,10,-1,5,50,0,0,0,0,0",
  71. "decimals": 8
  72. },
  73. "parameter": {
  74. "parameterName": [
  75. ]
  76. }
  77. }
  78. binary = {
  79. "name": "Binary",
  80. "property": {
  81. "x": 0,
  82. "y": 0,
  83. "width": 400,
  84. "height": 20,
  85. "backgroundColor": "#00000000",
  86. "borderVisiable": True,
  87. "borderWidth": 1,
  88. "font": "SimSun,9,-1,5,50,0,0,0,0,0",
  89. "rangeFirst": "[0, 1)",
  90. "rangeSecond": "[1, 2]",
  91. "colorFirst": "#ff0000",
  92. "colorSecond": "#ffff00",
  93. "oorColor": "#ffffff",
  94. "currentBinary": "0b0"
  95. },
  96. "parameter": {
  97. "parameterName": [
  98. ]
  99. }
  100. }
  101. def control_dict_to_node(control_dict, parent=None):
  102. control_node = etree.Element(control_dict["name"])
  103. if parent is not None:
  104. parent.append(control_node)
  105. # property
  106. if "property" in control_dict:
  107. prop_node = etree.SubElement(control_node, "property")
  108. for k, v in control_dict["property"].items():
  109. child = etree.SubElement(prop_node, k)
  110. if v is None:
  111. continue
  112. elif isinstance(v, bool):
  113. child.text = "true" if v else "false"
  114. else:
  115. child.text = str(v)
  116. # parameter
  117. if "parameter" in control_dict:
  118. param_node = etree.SubElement(control_node, "parameter")
  119. for k, v in control_dict["parameter"].items():
  120. # 多个 parameterName
  121. if isinstance(v, list):
  122. for item in v:
  123. etree.SubElement(param_node, k).text = str(item)
  124. else:
  125. etree.SubElement(param_node, k).text = str(v)
  126. return control_node
  127. def get_parameters(filename: str) -> dict:
  128. # 读取 XML 文件
  129. tree = etree.parse(filename) # 替换为你的文件路径
  130. root = tree.getroot()
  131. # 将结果转为字典
  132. parameters = {msg.get('ParameterName'): msg.get('NormalizedDataType')
  133. for msg in root.xpath('//Message')}
  134. # 打印字典
  135. # for param, dtype in parameters.items():
  136. # print(f"{param}: {dtype}")
  137. for idx, (param, dtype) in enumerate(parameters.items(), start = 0):
  138. print(f"{idx}: param = {param}, dtype = {dtype}")
  139. return parameters
  140. def generate_monitor_xml(filename: str, output: str, cal_parameters: list):
  141. parameters = get_parameters(filename)
  142. # ========= project 根节点 =========
  143. project = etree.Element(
  144. node_project["name"],
  145. **node_project.get("attr", {})
  146. )
  147. canvas_index = 0
  148. for idx, (param, dtype) in enumerate(parameters.items(), start = 0):
  149. # 如果当前 canvas 已满 36 组,则创建新 canvas
  150. if idx % 36 == 0:
  151. node_canvas["attr"]["name"] = f"canvas-{canvas_index}"
  152. canvas = etree.SubElement(
  153. project,
  154. node_canvas["name"],
  155. **node_canvas.get("attr", {})
  156. )
  157. canvas_index += 1
  158. y_offset = (idx % 36) * 20
  159. # Label
  160. lbl_ctrl = label.copy()
  161. lbl_ctrl["property"] = label["property"].copy()
  162. lbl_ctrl["property"]["y"] = y_offset
  163. lbl_ctrl["property"]["text"] = param
  164. control_dict_to_node(lbl_ctrl, canvas)
  165. # 数据控件
  166. if dtype == "BINARY":
  167. bin_ctrl = binary.copy()
  168. bin_ctrl["property"] = binary["property"].copy()
  169. bin_ctrl["property"]["x"] = lbl_ctrl["property"]["width"] + 80
  170. bin_ctrl["property"]["y"] = y_offset
  171. bin_ctrl["parameter"]["parameterName"] = [param]
  172. control_dict_to_node(bin_ctrl, canvas)
  173. else:
  174. num_ctrl = number.copy()
  175. num_ctrl["property"] = number["property"].copy()
  176. num_ctrl["property"]["x"] = lbl_ctrl["property"]["width"] + 80
  177. num_ctrl["property"]["y"] = y_offset
  178. num_ctrl["parameter"]["parameterName"] = [param]
  179. control_dict_to_node(num_ctrl, canvas)
  180. for idx, param in enumerate(cal_parameters, start = 0):
  181. if idx % 36 == 0:
  182. node_canvas["attr"]["name"] = f"canvas-{canvas_index}"
  183. canvas = etree.SubElement(
  184. project,
  185. node_canvas["name"],
  186. **node_canvas.get("attr", {})
  187. )
  188. canvas_index += 1
  189. y_offset = (idx % 36) * 20
  190. # Label
  191. lbl_ctrl = label.copy()
  192. lbl_ctrl["property"] = label["property"].copy()
  193. lbl_ctrl["property"]["y"] = y_offset
  194. lbl_ctrl["property"]["text"] = param
  195. control_dict_to_node(lbl_ctrl, canvas)
  196. num_ctrl = number.copy()
  197. num_ctrl["property"] = number["property"].copy()
  198. num_ctrl["property"]["x"] = lbl_ctrl["property"]["width"] + 80
  199. num_ctrl["property"]["y"] = y_offset
  200. num_ctrl["parameter"]["parameterName"] = [param]
  201. control_dict_to_node(num_ctrl, canvas)
  202. # ========= 写入文件 =========
  203. tree = etree.ElementTree(project)
  204. tree.write(
  205. output,
  206. encoding="UTF-8",
  207. xml_declaration=True,
  208. pretty_print=True
  209. )
  210. print("canvas count: ", canvas_index)
  211. if __name__ == "__main__":
  212. parser = argparse.ArgumentParser(description="Auto generate test monitor configure file by data process configure file.")
  213. parser.add_argument("--dataprocess", type=str, required=True, help="data process configure file (XML file)")
  214. parser.add_argument("-o", "--output", type=str, required=True, help="output monitor configure file (XML file)")
  215. args = parser.parse_args()
  216. dataprocess_file = args.dataprocess
  217. output_file = args.output
  218. path = Path(dataprocess_file)
  219. if not path.exists():
  220. print("data process configure is not exist.")
  221. sys.exit(1)
  222. if not path.suffix.lower() == ".xml":
  223. print("the dataprocess requirement is an XML file")
  224. sys.exit(1)
  225. if not Path(output_file).suffix.lower() == ".xml":
  226. print("the output requirement is an XML file")
  227. sys.exit(1)
  228. cal_parameters = [
  229. "cal_parameter1",
  230. "cal_parameter2"
  231. ]
  232. generate_monitor_xml(dataprocess_file, output_file, cal_parameters)