server.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. import os
  2. import time
  3. from typing import Optional
  4. import cv2
  5. import numpy as np
  6. from flask import Flask, request, jsonify
  7. from flask_cors import CORS
  8. from program_core import ProgramCore
  9. from program_public_tools import ProgramPublicTools
  10. class Server:
  11. def __init__(self, server_ip: str = '0.0.0.0', server_port: Optional[int] = None):
  12. self.__pubtools: ProgramPublicTools = ProgramPublicTools()
  13. self.__server_ip: str = server_ip
  14. self.__server_port: Optional[int] = server_port
  15. self.__server_ip_init()
  16. self.__core: ProgramCore = ProgramCore(self.__pubtools)
  17. self.__core.start_core()
  18. self.__app = Flask(__name__)
  19. CORS(self.__app)
  20. self.__setup_routes()
  21. self.__send_server_completed_flag()
  22. @staticmethod
  23. def __send_server_completed_flag():
  24. print("[Server] Server program is ready......")
  25. def __server_ip_init(self):
  26. if self.__server_port is None:
  27. self.__server_port = self.__pubtools.find_available_server_port(number=1, address=self.__server_ip)[0]
  28. print(f"Server is running on port [{self.__server_port}].")
  29. def start(self):
  30. self.__app.run(host=self.__server_ip, port=self.__server_port, debug=False)
  31. self.__server_debug_output()
  32. def __server_debug_output(self):
  33. _, _, url = self.__core.instrument_controller.services.digital_oscilloscope.keep_listening()
  34. print(f"[Server Debug Output]: OSC Stream Server is running on <{url}>")
  35. print(f"[Server Debug Output]: OSC Stream Server is running on <{url}>")
  36. print(f"[Server Debug Output]: OSC Stream Server is running on <{url}>")
  37. print(f"[Server Debug Output]: OSC Stream Server is running on <{url}>")
  38. print(f"[Server Debug Output]: OSC Stream Server is running on <{url}>")
  39. @staticmethod
  40. def __instrument_get_not_connect_string(not_connect_list: list[str]) -> str:
  41. response_string: str = "not_connect_list:"
  42. for not_connect_item in not_connect_list:
  43. response_string = response_string + " " + not_connect_item
  44. return response_string
  45. def __setup_routes(self):
  46. @self.__app.route("/")
  47. def home():
  48. return "Server is running."
  49. @self.__app.route("/instrument/not_connect_list", methods=['GET'])
  50. def instrument_not_connect_list():
  51. not_connect_list: list[str] = self.__core.instrument_controller.services.check()
  52. return self.__instrument_get_not_connect_string(not_connect_list)
  53. @self.__app.route("/instrument/digital_multimeter/connection_status", methods=['GET'])
  54. def instrument_digital_multimeter_connection_status():
  55. connection_status: bool = (self.__core.instrument_controller.services.digital_multimeter is not None)
  56. return f"connection_status: {connection_status}"
  57. @self.__app.route("/instrument/digital_oscilloscope/connection_status", methods=['GET'])
  58. def instrument_digital_oscilloscope_connection_status():
  59. connection_status: bool = (self.__core.instrument_controller.services.digital_oscilloscope is not None)
  60. return f"connection_status: {connection_status}"
  61. @self.__app.route("/instrument/waveform_generator/connection_status", methods=['GET'])
  62. def instrument_waveform_generator_connection_status():
  63. connection_status: bool = (self.__core.instrument_controller.services.waveform_generator is not None)
  64. return f"connection_status: {connection_status}"
  65. @self.__app.route("/instrument/analog_electronic_load/connection_status", methods=['GET'])
  66. def instrument_analog_electronic_load_connection_status():
  67. connection_status: bool = (self.__core.instrument_controller.services.analog_electronic_load is not None)
  68. return f"connection_status: {connection_status}"
  69. @self.__app.route("/instrument/digital_multimeter/keep_listening", methods=['GET'])
  70. def instrument_digital_multimeter_keep_listening():
  71. if self.__core.instrument_controller.services.digital_multimeter is not None:
  72. self.__core.instrument_controller.services.digital_multimeter.keep_listening()
  73. return f"keep_listening"
  74. else:
  75. return "None"
  76. @self.__app.route("/instrument/digital_multimeter/get_range", methods=['GET'])
  77. def instrument_digital_multimeter_get_range():
  78. if self.__core.instrument_controller.services.digital_multimeter is not None:
  79. range_list: list[str] = self.__core.instrument_controller.services.digital_multimeter.get_range()
  80. response_string: str = "get_range:"
  81. for rang_type_item in range_list:
  82. response_string = response_string + " " + rang_type_item
  83. return response_string
  84. else:
  85. return "None"
  86. @self.__app.route("/instrument/digital_multimeter/set_range", methods=['GET'])
  87. def instrument_digital_multimeter_set_range():
  88. if self.__core.instrument_controller.services.digital_multimeter is not None:
  89. range_string = request.args.get('range')
  90. range_type = self.__core.instrument_controller.services.digital_multimeter.solve_range_string(range_string)
  91. self.__core.instrument_controller.services.digital_multimeter.set_range(range_type)
  92. return f"set_range: {range_string}"
  93. else:
  94. return "None"
  95. @self.__app.route("/instrument/digital_multimeter/get_value", methods=['GET'])
  96. def instrument_digital_multimeter_get_value():
  97. if self.__core.instrument_controller.services.digital_multimeter is not None:
  98. get_value = self.__core.instrument_controller.services.digital_multimeter.get_value_latest()
  99. return f"get_value: {get_value}"
  100. else:
  101. return "None"
  102. @self.__app.route("/instrument/digital_oscilloscope/keep_listening", methods=['GET'])
  103. def instrument_digital_oscilloscope_keep_listening():
  104. if self.__core.instrument_controller.services.digital_oscilloscope is not None:
  105. _, v_port, v_url = self.__core.instrument_controller.services.digital_oscilloscope.keep_listening()
  106. return f"keep_listening: {v_port} {v_url}"
  107. else:
  108. return "None"
  109. @self.__app.route("/instrument/digital_oscilloscope/export_image", methods=['GET'])
  110. def instrument_digital_oscilloscope_export_image():
  111. if self.__core.instrument_controller.services.digital_oscilloscope is not None:
  112. get_time: str = self.__core.instrument_controller.services.digital_oscilloscope.save_img()
  113. return get_time
  114. else:
  115. return "None"
  116. @self.__app.route("/instrument/waveform_generator/output_start", methods=['GET'])
  117. def instrument_waveform_generator_output_start():
  118. if self.__core.instrument_controller.services.waveform_generator is not None:
  119. self.__core.instrument_controller.services.waveform_generator.output_start()
  120. return f"output_start"
  121. else:
  122. return "None"
  123. @self.__app.route("/instrument/waveform_generator/output_restart", methods=['GET'])
  124. def instrument_waveform_generator_output_restart():
  125. if self.__core.instrument_controller.services.waveform_generator is not None:
  126. self.__core.instrument_controller.services.waveform_generator.output_restart()
  127. return f"output_restart"
  128. else:
  129. return "None"
  130. @self.__app.route("/instrument/waveform_generator/output_pause", methods=['GET'])
  131. def instrument_waveform_generator_output_pause():
  132. if self.__core.instrument_controller.services.waveform_generator is not None:
  133. self.__core.instrument_controller.services.waveform_generator.output_pause()
  134. return f"output_pause"
  135. else:
  136. return "None"
  137. @self.__app.route("/instrument/waveform_generator/config/apply_config", methods=['GET'])
  138. def instrument_waveform_generator_config_apply_config():
  139. if self.__core.instrument_controller.services.waveform_generator is not None:
  140. self.__core.instrument_controller.services.waveform_generator.apply_config(True)
  141. return "apply_config"
  142. else:
  143. return "None"
  144. @self.__app.route("/instrument/waveform_generator/config/set_enable", methods=['GET'])
  145. def instrument_waveform_generator_config_set_enable():
  146. channel_string: str = request.args.get('channel')
  147. enable_string: str = request.args.get('enable').lower()
  148. if enable_string == "true":
  149. enable: bool = True
  150. else:
  151. enable: bool = False
  152. if self.__core.instrument_controller.services.waveform_generator is not None:
  153. channel = self.__core.instrument_controller.services.waveform_generator.set_enable(channel_string, enable)
  154. return f"set_enable: {channel} {enable}"
  155. else:
  156. return f"set_enable: None None"
  157. @self.__app.route("/instrument/waveform_generator/config/get_type", methods=['GET'])
  158. def instrument_waveform_generator_config_get_type():
  159. if self.__core.instrument_controller.services.waveform_generator is not None:
  160. res: str = self.__core.instrument_controller.services.waveform_generator.config_channel_1.get_type_string()
  161. return f"get_type: " + res
  162. else:
  163. return f"get_type: " + "None"
  164. @self.__app.route("/instrument/waveform_generator/config/set_type", methods=['GET'])
  165. def instrument_waveform_generator_config_set_type():
  166. channel_string: str = request.args.get('channel')
  167. type_string: str = request.args.get('type')
  168. if self.__core.instrument_controller.services.waveform_generator is not None:
  169. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  170. config.type = config.match_type_string(type_string)
  171. return f"set_type: {channel} {type_string}"
  172. else:
  173. return f"set_type: None None"
  174. @self.__app.route("/instrument/waveform_generator/config/set_freq", methods=['GET'])
  175. def instrument_waveform_generator_config_set_freq():
  176. channel_string: str = request.args.get('channel')
  177. freq: float = float(request.args.get('freq'))
  178. if self.__core.instrument_controller.services.waveform_generator is not None:
  179. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  180. config.freq = freq
  181. return f"set_freq: {channel} {freq}"
  182. else:
  183. return f"set_freq: None None"
  184. @self.__app.route("/instrument/waveform_generator/config/get_freq_unit", methods=['GET'])
  185. def instrument_waveform_generator_config_get_freq_unit():
  186. if self.__core.instrument_controller.services.waveform_generator is not None:
  187. _, config = self.__core.instrument_controller.services.waveform_generator.get_config("1")
  188. unit_type_string: str = config.get_freq_unit_type_string()
  189. return f"get_freq_unit: {unit_type_string}"
  190. else:
  191. return f"get_freq_unit: None"
  192. @self.__app.route("/instrument/waveform_generator/config/set_freq_unit", methods=['GET'])
  193. def instrument_waveform_generator_config_set_freq_unit():
  194. channel_string: str = request.args.get('channel')
  195. freq_unit_string: str = request.args.get('freq_unit')
  196. if self.__core.instrument_controller.services.waveform_generator is not None:
  197. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  198. config.freq_unit = config.match_freq_unit_type_string(freq_unit_string)
  199. return f"set_freq_unit: {channel} {freq_unit_string}"
  200. else:
  201. return f"set_freq_unit: None None"
  202. @self.__app.route("/instrument/waveform_generator/config/set_high_level", methods=['GET'])
  203. def instrument_waveform_generator_config_set_high_level():
  204. channel_string: str = request.args.get('channel')
  205. high_level: float = float(request.args.get('high_level'))
  206. if self.__core.instrument_controller.services.waveform_generator is not None:
  207. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  208. config.high_level = high_level
  209. return f"set_high_level: {channel} {high_level}"
  210. else:
  211. return f"set_high_level: None None"
  212. @self.__app.route("/instrument/waveform_generator/config/set_low_level", methods=['GET'])
  213. def instrument_waveform_generator_config_set_low_level():
  214. channel_string: str = request.args.get('channel')
  215. low_level: float = float(request.args.get('low_level'))
  216. if self.__core.instrument_controller.services.waveform_generator is not None:
  217. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  218. config.low_level = low_level
  219. return f"set_low_level: {channel} {low_level}"
  220. else:
  221. return f"set_low_level: None None"
  222. @self.__app.route("/instrument/waveform_generator/config/get_level_unit", methods=['GET'])
  223. def instrument_waveform_generator_config_get_level_unit():
  224. if self.__core.instrument_controller.services.waveform_generator is not None:
  225. _, config = self.__core.instrument_controller.services.waveform_generator.get_config("1")
  226. unit_type_string: str = config.get_freq_unit_type_string()
  227. return f"get_freq_unit: {unit_type_string}"
  228. else:
  229. return f"get_freq_unit: None"
  230. @self.__app.route("/instrument/waveform_generator/config/set_high_level_unit", methods=['GET'])
  231. def instrument_waveform_generator_config_set_high_level_unit():
  232. channel_string: str = request.args.get('channel')
  233. high_level_unit_string: str = request.args.get('high_level_unit')
  234. if self.__core.instrument_controller.services.waveform_generator is not None:
  235. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  236. config.high_level_unit = config.match_level_unit_type_string(high_level_unit_string)
  237. return f"set_high_level_unit: {channel} {high_level_unit_string}"
  238. else:
  239. return f"set_high_level_unit: None {high_level_unit_string}"
  240. @self.__app.route("/instrument/waveform_generator/config/set_low_level_unit", methods=['GET'])
  241. def instrument_waveform_generator_config_set_low_level_unit():
  242. channel_string: str = request.args.get('channel')
  243. low_level_unit_string: str = request.args.get('low_level_unit')
  244. if self.__core.instrument_controller.services.waveform_generator is not None:
  245. channel, config = self.__core.instrument_controller.services.waveform_generator.get_config(channel_string)
  246. config.low_level_unit = config.match_level_unit_type_string(low_level_unit_string)
  247. return f"set_low_level_unit: {channel} {low_level_unit_string}"
  248. else:
  249. return f"set_low_level_unit: None {low_level_unit_string}"
  250. @self.__app.route("/instrument/analog_electronic_load/set_resistance", methods=['GET'])
  251. def instrument_analog_electronic_load_set_resistance():
  252. if self.__core.instrument_controller.services.analog_electronic_load is not None:
  253. resistance: str = request.args.get('set_resistance')
  254. self.__core.instrument_controller.services.analog_electronic_load.set_resistance(resistance)
  255. return "True"
  256. else:
  257. return "False"
  258. @self.__app.route("/serial_device/port_list", methods=['GET'])
  259. def serial_device_port_list():
  260. port_list: list[str] = self.__core.serial_controller.get_port_list()
  261. response_string: str = "port_list:"
  262. if len(port_list) == 0:
  263. response_string = response_string + " " + "None"
  264. else:
  265. for port_name in port_list:
  266. response_string = response_string + " " + port_name
  267. return response_string
  268. @self.__app.route("/serial_device/auto_connect", methods=['GET'])
  269. def serial_device_auto_connect():
  270. matched_port_list, not_matched_port_list, cnc_matched = self.__core.serial_controller.auto_connect()
  271. response_data = {
  272. 'method': 'auto_connect',
  273. 'cnc_matched': cnc_matched,
  274. 'port_list': {
  275. 'matched': matched_port_list,
  276. 'not_matched': not_matched_port_list
  277. }
  278. }
  279. return jsonify(response_data), 200
  280. @self.__app.route("/serial_device/cnc/config_connection", methods=['GET'])
  281. def serial_device_cnc_config_connection():
  282. port_name: str = request.args.get('port_name')
  283. com_connection = self.__core.serial_controller.try_build_connection(port_name, if_add_source_to_lib=True)
  284. if_success = self.__core.serial_controller.services.cnc_attenuator.match_connection(com_connection)
  285. return f"{if_success}"
  286. @self.__app.route("/serial_device/cnc/set", methods=['GET'])
  287. def serial_device_cnc_set():
  288. set_value: str = request.args.get('value')
  289. if_success = self.__core.serial_controller.services.cnc_attenuator.set(float(set_value))
  290. return f"{if_success}"
  291. @self.__app.route("/serial_device/plc/config_connection", methods=['GET'])
  292. def serial_device_plc_connect_sender():
  293. port_name: str = request.args.get('port_name')
  294. plc_com_role: str = request.args.get('plc_com_role').lower()
  295. if_success: bool = False
  296. if (port_name is not None) and (port_name not in ["None", "", " "]):
  297. com_connection = self.__core.serial_controller.try_build_connection(port_name, if_add_source_to_lib=True)
  298. if com_connection is not None:
  299. if plc_com_role == "sender":
  300. if_success = self.__core.serial_controller.services.plc_sender.match_connection(com_connection)
  301. elif plc_com_role == "receiver":
  302. if_success = self.__core.serial_controller.services.plc_receiver.match_connection(com_connection)
  303. elif plc_com_role == "receiver2":
  304. if_success = self.__core.serial_controller.services.plc_receiver2.match_connection(com_connection)
  305. if if_success is True:
  306. self.__core.serial_controller.services.enable_multi_receiver = True
  307. else:
  308. if_success = False
  309. else:
  310. if_success: bool = True
  311. # if_success = True
  312. # ports = self.__core.serial_controller.get_port_list()
  313. # self.__core.serial_controller.services.plc_sender.match_connection()
  314. get_sender_port_name: str = "None"
  315. if self.__core.serial_controller.services.plc_sender.com is not None:
  316. get_sender_port_name = self.__core.serial_controller.services.plc_sender.com.connection_port_name
  317. get_receiver_port_name: str = "None"
  318. if self.__core.serial_controller.services.plc_receiver.com is not None:
  319. get_receiver_port_name = self.__core.serial_controller.services.plc_receiver.com.connection_port_name
  320. self.__core.serial_controller.services.com_usr_config_success = if_success
  321. response_data = {
  322. 'method': 'config_connection',
  323. 'plc_com_role': plc_com_role,
  324. 'port_name': port_name,
  325. 'if_success': if_success,
  326. 'new_config': {
  327. 'sender_port': f"{get_sender_port_name}",
  328. 'receiver_port': f"{get_receiver_port_name}",
  329. },
  330. 'received_config': {
  331. 'role': f"{plc_com_role}",
  332. 'port': f"{port_name}",
  333. }
  334. }
  335. return jsonify(response_data), 200
  336. @self.__app.route("/serial_device/plc/check_connection", methods=['GET'])
  337. def serial_device_plc_check_connection():
  338. sender_port: Optional[str] = self.__core.serial_controller.services.plc_sender.com.connection_port_name
  339. receiver_port: Optional[str] = self.__core.serial_controller.services.plc_receiver.com.connection_port_name
  340. sender_connection_flag: bool = (sender_port is not None)
  341. receiver_connection_flag: bool = (receiver_port is not None)
  342. connection_flag: bool = (sender_connection_flag is True) and (receiver_connection_flag is True)
  343. response_data = {
  344. 'method': 'check_connection',
  345. 'connection_status': connection_flag,
  346. 'config': {
  347. 'sender_port': f"{self.__core.serial_controller.services.plc_sender.com.connection_port_name}",
  348. 'receiver_port': f"{self.__core.serial_controller.services.plc_receiver.com.connection_port_name}",
  349. }
  350. }
  351. return jsonify(response_data), 200
  352. @self.__app.route("/serial_device/plc/start", methods=['GET'])
  353. def serial_device_plc_start():
  354. if self.__core.serial_controller.services.com_usr_config_success is True:
  355. package_config: Optional[str] = request.args.get('package_config')
  356. sender = self.__core.serial_controller.services.plc_sender
  357. receiver = self.__core.serial_controller.services.plc_receiver
  358. sender_port, sender_url = sender.keep_send()
  359. receiver_port, receiver_url = receiver.keep_receive()
  360. receiver2 = None
  361. if self.__core.serial_controller.services.enable_multi_receiver is True:
  362. receiver2 = self.__core.serial_controller.services.plc_receiver2
  363. receiver2.keep_receive()
  364. tester = self.__core.serial_controller.get_tester()
  365. tester.start_test_service(sender, receiver, receiver2)
  366. if package_config == "单包1kbit":
  367. tester_frame_new: bytes = tester.send_package_1kbit
  368. elif package_config == "单包16kbit":
  369. tester_frame_new: bytes = tester.send_package_16kbit
  370. else:
  371. tester_frame_new: bytes = package_config.encode()
  372. if len(tester_frame_new) % 3 == 0:
  373. tester_frame_new += b'12\n'
  374. elif len(tester_frame_new) % 3 == 1: # b'1'
  375. tester_frame_new += b'1\n'
  376. elif len(tester_frame_new) % 3 == 2: # b'12'
  377. tester_frame_new += b'\n'
  378. else:
  379. tester_frame_new = b'12\n'
  380. tester.reset_frame_std_and_restart(tester_frame_new)
  381. else:
  382. sender_port, sender_url, receiver_port, receiver_url = 0, 0, 0, 0
  383. response_data = {
  384. 'method': 'start',
  385. 'sender': {
  386. 'port': f"{sender_port}",
  387. 'url': sender_url,
  388. },
  389. 'receiver': {
  390. 'port': f"{receiver_port}",
  391. 'url': receiver_url,
  392. }
  393. }
  394. print(f"=== @self.__app.route('/serial_device/plc/start', methods=['GET']) ===")
  395. return jsonify(response_data), 200
  396. @self.__app.route("/serial_device/plc/pause", methods=['GET'])
  397. def serial_device_plc_pause():
  398. # self.__core.serial_controller.services.plc_sender.pause()
  399. # self.__core.serial_controller.services.plc_receiver.pause()
  400. tester = self.__core.serial_controller.get_tester()
  401. tester.pause_test_service()
  402. print(f"=== @self.__app.route('/serial_device/plc/pause', methods=['GET']) ===")
  403. return "pause"
  404. @self.__app.route("/serial_device/plc/clear", methods=['GET'])
  405. def serial_device_plc_clear():
  406. self.__core.serial_controller.get_tester().task_add_reset_error_rate()
  407. print(f"=== @self.__app.route('/serial_device/plc/clear', methods=['GET']) ===")
  408. return "clear"
  409. @self.__app.route("/serial_device/plc/realtime_performance", methods=['GET'])
  410. def serial_device_plc_realtime_performance():
  411. tester = self.__core.serial_controller.get_tester()
  412. error_rate_percent: float = tester.error_rate_percent
  413. error_rate_percent2: float = tester.error_rate_percent2
  414. print(f"=== @self.__app.route('/serial_device/plc/realtime_performance', methods=['GET']) ===")
  415. return f"realtime_performance: error_rate_percent={error_rate_percent} error_rate_percent2={error_rate_percent2}"
  416. @self.__app.route("/serial_device/plc/realtime_performance_speed", methods=['GET'])
  417. def serial_device_plc_realtime_performance_speed():
  418. tester = self.__core.serial_controller.get_tester()
  419. speed_kbps: float = tester.speed_kbps
  420. speed_kbps2: float = tester.speed_kbps2
  421. print(f"=== @self.__app.route('/serial_device/plc/realtime_performance_speed', methods=['GET']) ===")
  422. return f"realtime_performance_speed: speed_kbps={speed_kbps} speed_kbps2={speed_kbps2}"
  423. @self.__app.route("/files/documents/start", methods=['GET'])
  424. def files_documents_start():
  425. host, port = self.__core.local_file_service.start()
  426. return f"documents: host={host} port={port}"
  427. if __name__ == "__main__":
  428. server: Server = Server()
  429. server.start()