DeviceControl.py 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103
  1. import asyncio
  2. import datetime
  3. from cv2 import log
  4. import serial.tools.list_ports
  5. import time, json
  6. from .SerialIns import SerialIns
  7. from utils.SingletonType import SingletonType
  8. from utils.utils_func import dynamic_parameter_issuance_get
  9. from .BaseClass import BaseClass
  10. from sockets import ConnectionManager
  11. from collections import defaultdict
  12. import threading
  13. import settings
  14. from .ProgramItem import ProgramItem
  15. from .capture.module_digicam import DigiCam
  16. from databases import insert_photo_records
  17. from .McuDeviationSet import McuDeviationSet
  18. from .OtherSet import OtherSet
  19. from .DebugUart import DebugUart
  20. from .LineControl import LineControl
  21. import copy
  22. import logging
  23. from mcu.capture.smart_shooter_class import SmartShooter
  24. import logging
  25. from conifg_info import ConfigManager
  26. logger = logging.getLogger(__name__)
  27. # mcu命令
  28. class DeviceControl(BaseClass, metaclass=SingletonType):
  29. lock = threading.Lock()
  30. def __init__(
  31. self, websocket_manager: ConnectionManager, smart_shooter: SmartShooter = None
  32. ):
  33. super().__init__(
  34. websocket_manager=websocket_manager, smart_shooter=smart_shooter
  35. )
  36. self.camera_high_motor_deviation_offset = 0
  37. self.camera_height = 400
  38. self.config_manager = None
  39. self.msg_type = "mcu"
  40. self.command = {
  41. "to_device_move": 1, # 设备运动
  42. 'to_init_device': 2, # 初始化设备
  43. "to_deal_other_device": 3, # 处理其他设备
  44. 'get_all_info': 29, # 获取所有信息
  45. 'set_deviation': 40, # 设置偏移量
  46. 'get_deviation': 41, # 读取偏移量
  47. "signal_forwarding": 91, # 信号转发处理
  48. "signal_forwarding_return": 92, # 信号转发返回
  49. "get_other_info": 44, # 获取其他信息
  50. "open_rgb_led": 43, ## RGB灯的处理与通讯
  51. "set_other_info": 45, # 设置其他信息
  52. "query_remote_control_battery": 47, # 查询遥控器电量
  53. # "set_turntable_mode": 48, # 设置转盘通讯方式 1、串口、2、无线、3 混合
  54. "get_mcu_device_id": 49, # 查询MCU的设备号
  55. "mcu_power_off": 53, # 设备关机
  56. "stop_mcu": 93, # 停止运行mcu
  57. "get_steering_temperature": 108, # 查询舵机的当前的温度
  58. # "steering_forwarding": 113, # 舵机信号转发处理
  59. # "steering_forwarding_callback": 114, # 舵机信号转发返回
  60. "get_motor_value": 119, # 获取当前电机值;逻辑值
  61. "set_zero_debug": 120, # 简单的设备归零,用于调试
  62. "set_stepper_disable": 121, # 释放,或恢复使能
  63. }
  64. self.serial_ins = None
  65. self.mcu_deviation_set = McuDeviationSet(self)
  66. self.mcu_other_set = OtherSet(self)
  67. self.debug_uart = DebugUart(self)
  68. self.line_control = LineControl(websocket_manager)
  69. self.m_t = 1
  70. # 0未开始 1进行中 2已结束 99异常
  71. self.action_state = 2
  72. self._mcu_move_state = 0
  73. self.state_camera_motor = 3
  74. self.state_camera_steering = 3
  75. self.state_turntable_steering = 3
  76. self.state_overturn_steering = 3
  77. self.seed = 0
  78. self.last_camera_height = 0
  79. # 是否实时获取mcu状态信息
  80. self.is_get_mcu_state = True
  81. self.state_move_turntable_steering = 3
  82. self.last_from_mcu_move_respond_data = None
  83. self.camera_motor_speed = 0
  84. self.camera_motor_value = 0
  85. self.init_state = False
  86. self.port_name = ""
  87. self.mcu_exit = False
  88. self.t_n = 0
  89. self.connected_ports_dict = {} # 已连接的ports
  90. self.p_list = []
  91. self.temp_ports_dict = {}
  92. self.is_running = False
  93. self.is_runn_action = False
  94. self.is_stop_action = False
  95. self.connect_state = False
  96. self.is_init_while = False
  97. self.device_name_dict = {
  98. "camera_steering": 0,
  99. "camera_high_motor": 1,
  100. "turntable_steering": 2,
  101. "overturn_steering": 3,
  102. "laser_position": 4,
  103. "buzzer": 5,
  104. "split": 6,
  105. "turntable_position_motor": 7,
  106. "mp3_player": 8,
  107. "mcu": 99,
  108. "camera_zoom_motor": 10,
  109. }
  110. self.last_move_time = time.time()
  111. self.device_name_dict_mapping = {
  112. 0: "相机角度",
  113. 1: "相机高度",
  114. 2: "转盘角度",
  115. 3: "翻板角度",
  116. 4: "激光灯位置",
  117. 5: "蜂鸣器",
  118. 6: "split",
  119. 7: "转盘位置",
  120. 8: "播放音频",
  121. 99: "mcu命令",
  122. 10: "相机焦段",
  123. }
  124. # 最近的mcu基础信息,用于获取数据状态检查
  125. self.last_mcu_info_data = {
  126. "num": 0,
  127. "time": time.time(),
  128. "data": None,
  129. }
  130. # 最近的mcu的其他配置
  131. self.last_mcu_other_info_data = {
  132. "num": 0,
  133. "time": time.time(),
  134. "data": {},
  135. }
  136. # self.window = window
  137. self.last_push_time = defaultdict(float)
  138. self.is_running = False
  139. self.is_wait_connect = False # 等待链接
  140. self.send_data_queue = [] # 发送队列
  141. # self.lock = Lock()
  142. # 是否是刚进行完初始化;首次初始化,需要运动到指定第一个指定位置
  143. self.is_just_init_time = False
  144. # self.init()
  145. # ===========注册命令函数============
  146. self.deal_code_func_dict = {
  147. 29: self.get_from_mcu_base_info, # 获取基本情况
  148. 32: self.get_from_mcu_button, # 获取按键信息
  149. 42: self.get_from_mcu_deviation_info, # 获取偏移量信息
  150. 44: self.get_from_mcu_other_info, # 获取其他配置参数
  151. 90: self.get_from_mcu_connect_info, # 获取链接电脑信号
  152. 92: self.get_from_mcu_move_respond_data, # 获取MCU响应
  153. 100: self.print_mcu_error_data, # 打印下位机的错误内容
  154. 255: self.print_mcu_noraml_data, # 打印回执
  155. 124: self.read_register_data_by_usb, # 读取某个寄存器数据
  156. 125: self.write_register_data_by_usb, # 写入某个寄存器数据
  157. 126: self.get_all_registers_list_by_usb, # 获取所有寄存器
  158. 150: self.dynamic_parameter_issuance, # 动态参数下发
  159. }
  160. def set_dynamic_config(self, config):
  161. """
  162. 设置动态参数配置
  163. """
  164. print("set_dynamic_config", config)
  165. if not self.init_state:
  166. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  167. return False
  168. return self.config_manager.set_dynamic_value(config)
  169. def get_dynamic_config(self):
  170. """
  171. 获取动态参数配置
  172. """
  173. if not self.init_state:
  174. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  175. return False
  176. # 构建返回结果,过滤掉值为空的项,不修改原字典
  177. result = {}
  178. for item in self.config_manager.CONFIG_METADATA:
  179. item_value = self.config_manager.get_dynamic_value(self.config_manager.CONFIG_METADATA[item])
  180. # time.sleep(0.01)
  181. entry = dict(self.config_manager.CONFIG_METADATA[item])
  182. if not item_value:
  183. entry['value'] = None
  184. else:
  185. entry['value'] = item_value
  186. result[item] = entry
  187. # print("CONFIG_METADATA", self.config_manager.CONFIG_METADATA)
  188. # print("result", result)
  189. return result
  190. def get_dynamic_config_signle(self, name):
  191. """
  192. 获取动态参数配置-单独
  193. """
  194. data = {"addr": name}
  195. print("参数值打印", data)
  196. item_value = self.config_manager.get_dynamic_value(data)
  197. if not item_value:
  198. return None
  199. return item_value
  200. def one_key_turnoff(self, device_name, flag):
  201. # 一键关机
  202. if device_name in self.device_name_dict:
  203. device_id = self.device_name_dict[device_name]
  204. buf = [self.command["mcu_power_off"],
  205. device_id,
  206. 1 if flag else 0,
  207. ]
  208. self.add_send_data_queue(buf)
  209. def one_key_down(self):
  210. cmd = [0x55, 0x55, 0x69, 0x96, 0x00, 0x03, 0x00, 0xC8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01,
  211. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  212. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  213. 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  214. 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  215. 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
  216. 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02]
  217. # self.add_send_data_queue(cmd)
  218. buf = bytearray(b"")
  219. buf.extend(cmd)
  220. # 55 55 02 5a 01 a4
  221. if self.serial_ins.serial_handle is not None:
  222. print("one_key_down buf {}".format(self.serial_ins.change_hex_to_int(buf)))
  223. self.serial_ins.serial_handle.write(buf)
  224. def get_device_info(self):
  225. if not self.init_state:
  226. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  227. return False
  228. cmd = [124]
  229. cmd.extend([0xff & 106 >> 8, 0xff & 106])
  230. # print("get_device_info cmd",cmd)
  231. data = self.get_basic_info_mcu_without_async(data=cmd)
  232. # print("get_device_info====>",data)
  233. if not data:
  234. return False
  235. return_data = self.analysis_data(data[1:])
  236. camera_focal_data = self.config_manager.camera_focal_data()
  237. # print("return_data", return_data)
  238. # print("camera_high_motor_deviation_offset", self.camera_high_motor_deviation_offset)
  239. if return_data:
  240. camera_height = return_data.get('value', 35)
  241. self.camera_height = camera_height - self.camera_high_motor_deviation_offset
  242. else:
  243. self.camera_height = 400 - self.camera_high_motor_deviation_offset
  244. self.msg_type = 'get_device_info'
  245. self.sendSocketMessage(
  246. code=0,
  247. msg="获取其他设备信息",
  248. device_status=2,
  249. data={"camera_height": self.camera_height, "camera_focal_data": camera_focal_data}
  250. )
  251. self.msg_type = 'mcu'
  252. return self.camera_height
  253. # 获取异步数据
  254. def analysis_data(self, _data):
  255. _addr = _data[0] << 8 | _data[1]
  256. if _addr not in self.config_manager.CONFIG_METADATA_BY_ADDR:
  257. return False
  258. start = 2
  259. _value = _data[start] << 40 | _data[start + 1] << 32 | _data[start + 2] << 24 | _data[start + 3] << 16 | _data[
  260. start + 4] << 8 | _data[start + 5]
  261. start = start + 5
  262. _read_only = True if _data[start + 1] == 1 else False # 是否只读
  263. _dir = 1 if _data[start + 2] == 1 else -1
  264. _type = "int" if _data[start + 3] == 1 else "float"
  265. _precision = _data[start + 4]
  266. if _dir < 0:
  267. _value = _value * _dir
  268. if _type == "float":
  269. if _precision > 0:
  270. _round_x = _precision
  271. _precision = _precision * -1
  272. _value = _value * 10 ** _precision
  273. _value = round(_value, _round_x)
  274. else:
  275. _value = int(_value)
  276. return_data = {"addr": _addr,
  277. "key_name": self.config_manager.CONFIG_METADATA_BY_ADDR[_addr],
  278. "readonly": _read_only,
  279. "value": _value}
  280. return return_data
  281. # 跳过异步,直接查询某个数据信息
  282. def get_basic_info_mcu_without_async(self, data, fiddler_cmd=0):
  283. """
  284. fiddler_cmd :只接收指定的命令内容
  285. """
  286. try:
  287. # 清空接收数据
  288. self.serial_ins.clearn_flush()
  289. self.serial_ins.write_cmd(data)
  290. time.sleep(0.06)
  291. r_data = self.get_basic_info_mcu()
  292. print("264----------r_data:", r_data)
  293. except BaseException as e:
  294. print("302---e", e)
  295. r_data = []
  296. #
  297. # self.async_lock.release()
  298. return r_data
  299. def dynamic_parameter_issuance(self, receive_data):
  300. print("dynamic_parameter_issuance receive_data", receive_data)
  301. func_code, status_code, out_par_data_list = dynamic_parameter_issuance_get(
  302. receive_data
  303. )
  304. r_data = {
  305. "func_code": func_code,
  306. "status_code": status_code,
  307. "out_par_data_list": out_par_data_list,
  308. }
  309. print(r_data)
  310. return r_data
  311. # 读取某个寄存器数据
  312. def read_register_data_by_usb(self, receive_data):
  313. return receive_data
  314. # 写入某个寄存器数据
  315. def write_register_data_by_usb(self, receive_data):
  316. return receive_data
  317. # 获取所有寄存器
  318. def get_all_registers_list_by_usb(self, receive_data):
  319. byte_list = receive_data[1:]
  320. _r_data = []
  321. for i in range(0, len(byte_list), 2):
  322. if i + 1 < len(byte_list):
  323. first_byte = byte_list[i]
  324. second_byte = byte_list[i + 1]
  325. _addr = first_byte << 8 | second_byte
  326. _r_data.append(_addr)
  327. return _r_data
  328. async def sendCommand(self, command):
  329. await asyncio.sleep(0.01)
  330. loop = asyncio.get_event_loop()
  331. loop.create_task(self.debug_uart.set(command), name="sendCommand2")
  332. async def getMcuOtherInfo(self):
  333. await asyncio.sleep(0.01)
  334. self.get_other_info()
  335. async def setMcuOtherInfo(self, data):
  336. await asyncio.sleep(0.01)
  337. for k, v in data.items():
  338. print("k:{},v:{}".format(k, v))
  339. logger.info("k:{},v:{}".format(k, v))
  340. data[k] = self.setOtherMaxMinValue(k, v)
  341. self.set_to_mcu_other_info(data)
  342. self.msg_type = "set_other_mcu_info"
  343. self.sendSocketMessage(
  344. code=0,
  345. msg="设置mcu其他配置信息完成",
  346. device_status=2,
  347. )
  348. self.msg_type = "mcu"
  349. def setOtherMaxMinValue(self, item, value):
  350. value = int(value)
  351. parameter_limits = {
  352. "is_auto_send_base_info": (0, 10000),
  353. "is_move_retry": (0, 10000),
  354. "is_data_response": (0, 10000),
  355. "low_speed": (0, 10000), # 假设低速范围是0到1000
  356. "is_test": (0, 10000),
  357. "to_init_mode": (0, 10000),
  358. "turntable_move_to_init_mode": (0, 10000), # 假设转盘通讯方式范围是0到3
  359. "led_count": (0, 10000), # 假设LED数量范围是0到10
  360. "turntable_steering_angle_ratio": (0, 10000), # 假设角度比例范围是0到100
  361. "is_manual_check": (0, 10000),
  362. "camera_steering_angle_ratio": (0, 100000), # 假设角度比例范围是0到100
  363. "is_auto_motor_to_disable": (0, 10000),
  364. "diff_dir": (0, 10000),
  365. "is_auto_send_pos_info": (0, 10000),
  366. "is_dog": (0, 10000),
  367. "has_been_set_motor_config": (0, 10000),
  368. }
  369. # 获取参数的最小值和最大值
  370. min_value, max_value = parameter_limits.get(item, (0, 10000))
  371. value = max(min_value, min(max_value, value))
  372. return value
  373. async def initDevice(self, is_force=False):
  374. if not self.is_running:
  375. self.sendSocketMessage(
  376. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  377. )
  378. return False
  379. if self.init_state == True:
  380. print("已经初始化过,请勿重复初始化")
  381. logger.info("已经初始化过,请勿重复初始化")
  382. self.sendSocketMessage(msg="设备初始化完成", device_status=2)
  383. return False
  384. self.config_manager = ConfigManager(self)
  385. self.serial_ins.clearn_flush()
  386. self.to_init_device_origin_point(device_name="mcu", is_force=is_force)
  387. print("MCU 开始循环~")
  388. logger.info("MCU 开始循环~")
  389. while 1:
  390. await asyncio.sleep(0.05)
  391. if not self.serial_ins or not self.connect_state:
  392. break
  393. try:
  394. self.send_cmd()
  395. if not self.get_basic_info_mcu():
  396. pass
  397. except BaseException as e:
  398. print("121231298908", e)
  399. logger.info(f"121231298908{e}")
  400. break
  401. self.is_running = False
  402. self.connect_state = False
  403. print("MCU 循环退出~")
  404. logger.info("MCU 循环退出~")
  405. print("串口未连接,请检查")
  406. logger.info("串口未连接,请检查")
  407. self.sendSocketMessage(code=1, msg="MCU串口未连接,请检查", device_status=-1)
  408. message = {"_type": "show_info", "plugins_mode": "mcu", "data": "MCU 连接失败"}
  409. self.sendSocketMessage(
  410. code=1, msg="MCU 连接失败", data=message, device_status=-1
  411. )
  412. self.close_connect()
  413. async def initControlLine(self, serial_handle):
  414. """实例化有线控制设备"""
  415. self.line_control.connect_state = True
  416. self.line_control.serial_ins = serial_handle
  417. await self.line_control.run()
  418. def stop_mcu(self):
  419. buf = [self.command["stop_mcu"]]
  420. buf.extend(self.encapsulation_data(data=1, len_data=1))
  421. self.add_send_data_queue(buf)
  422. # 设置转盘通讯方式 1、串口、2、无线、3 混合
  423. def to_set_turntable_mode(self, mode=1):
  424. buf = [self.command["set_turntable_mode"]]
  425. buf.extend(self.encapsulation_data(data=mode, len_data=1))
  426. self.add_send_data_queue(buf)
  427. def query_remote_control_battery(self):
  428. """查询遥控器电量"""
  429. buf = [self.command["query_remote_control_battery"]]
  430. buf.extend(self.encapsulation_data(data=1, len_data=1))
  431. buf.extend(self.encapsulation_data(data=1, len_data=1))
  432. buf.extend(self.encapsulation_data(data=1, len_data=1))
  433. self.add_send_data_queue(buf)
  434. def encapsulation_data(self, data, len_data, data_magnification=1):
  435. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  436. data = int(data * data_magnification)
  437. if len_data == 1:
  438. return [0xFF & data]
  439. elif len_data == 2:
  440. return [0xFF & data >> 8, 0xFF & data]
  441. elif len_data == 4:
  442. return [0xFF & data >> 24, 0xFF & data >> 16, 0xFF & data >> 8, 0xFF & data]
  443. def open_rgb_led(
  444. self,
  445. color_name,
  446. led_command=1,
  447. brightness=80,
  448. enable=True,
  449. mode="loop",
  450. times=2,
  451. interval=0.1,
  452. ):
  453. color_name_value = {
  454. "红色": (156, 6, 3),
  455. "黄色": (255, 206, 25),
  456. "绿色": (0, 128, 0),
  457. "蓝色": (0, 25, 255),
  458. "白色": (255, 250, 227),
  459. }
  460. if color_name in color_name_value:
  461. buf = [self.command["open_rgb_led"]]
  462. buf.append(1 if enable else 0)
  463. buf.append(led_command)
  464. buf.extend(color_name_value[color_name])
  465. buf.extend(
  466. [
  467. brightness,
  468. 1 if mode == "loop" else 2,
  469. times,
  470. int(interval * 10),
  471. ]
  472. )
  473. self.add_send_data_queue(buf)
  474. def getDeviationInfo(self):
  475. # await asyncio.sleep(0.01)
  476. try:
  477. # 发送获取偏移量
  478. data = [self.command["get_deviation"], 1]
  479. self.add_send_data_queue(data)
  480. # if self.serial_ins:
  481. # self.serial_ins.write_cmd(data)
  482. print("发送获取偏移量")
  483. logger.info("发送获取偏移量")
  484. except Exception as e:
  485. print(e)
  486. print("getDeviationInfo", "暂未获取到self.command")
  487. logger.info("getDeviationInfo暂未获取到self.command")
  488. def set_deviation(self, device_name, _type=0, deviation=0):
  489. # turntable----0 angle_ratio 1 turntable_steering_deviation
  490. # overturn ----0 middle 1 high
  491. if device_name == "camera_high_motor":
  492. deviation = deviation / 10 # deviation 原单位为mm
  493. if device_name == "turntable_position_motor":
  494. deviation = deviation / 10 # deviation 原单位为mm
  495. if device_name == "camera_steering":
  496. pass
  497. if device_name == "turntable_steering":
  498. pass
  499. if device_name == "overturn_steering":
  500. pass
  501. device_id = self.device_name_dict[device_name]
  502. _dir = 1 if deviation >= 0 else 0
  503. deviation = int(abs(deviation * 10))
  504. data = [
  505. self.command["set_deviation"],
  506. device_id,
  507. _type,
  508. _dir,
  509. 0xFF & deviation >> 8,
  510. 0xFF & deviation,
  511. ]
  512. self.add_send_data_queue(data)
  513. # self.controlDevice(device_name, deviation)
  514. async def set_deviation_cmd(self, value, action_name, type):
  515. await asyncio.sleep(0.01)
  516. name_sets = [
  517. "相机电机", # min 0 max 400,步长1
  518. "相机舵机", # min -40 max 40,步长0.1
  519. "转盘舵机", # min -720 max 720,步长1
  520. "转盘前后电机", # min 0 max 950,步长1
  521. "翻板舵机中位", # min 0 max 180,步长0.5
  522. "翻板舵机高位", # min 0 max 180,步长0.5
  523. "翻板舵机上升速度", # min 1 max 10,步长1
  524. "翻板舵机下降速度", # min 1 max 10,步长1
  525. "相机焦段", # min 1 max 10,步长1
  526. ]
  527. if action_name not in name_sets:
  528. self.msg_type = f"{type}_deviation"
  529. self.sendSocketMessage(msg="设置参数有误,请检查", device_status=0, code=1)
  530. self.msg_type = "mcu"
  531. return
  532. # 发送获取偏移量
  533. if type == "move":
  534. self.mcu_deviation_set.change_value(value, action_name)
  535. elif type == "set":
  536. self.mcu_deviation_set.set_deviation(action_name)
  537. self.msg_type = f"{type}_deviation"
  538. self.sendSocketMessage(msg=f"{action_name} 设置成功", device_status=2, code=0)
  539. self.msg_type = "mcu"
  540. def get_other_info(self):
  541. # 发送获取偏移量
  542. data = [self.command["get_other_info"], 1]
  543. self.add_send_data_queue(data)
  544. print("发送获取其他信息")
  545. logger.info("发送获取其他信息")
  546. def add_send_data_queue(self, data):
  547. self.lock.acquire()
  548. if self.serial_ins:
  549. print("send_data_queue append :{}".format(data))
  550. logger.info("send_data_queue append %s", data)
  551. self.send_data_queue.append(data)
  552. self.lock.release()
  553. async def send_all_cmd(self):
  554. # await asyncio.sleep(0.001)
  555. while True:
  556. await asyncio.sleep(0.1)
  557. if self.send_data_queue:
  558. # self.sendSocketMessage(msg="正在发送命令", device_status=1)
  559. data = self.send_data_queue.pop(0)
  560. # print("\033[1;32;40m 正在发送命令 \033[0m",data)
  561. self.serial_ins.write_cmd(data)
  562. # self.sendSocketMessage(msg="命令发送完成", device_status=2)
  563. else:
  564. break
  565. def send_cmd(self):
  566. self.lock.acquire()
  567. if self.send_data_queue:
  568. # self.sendSocketMessage(msg="正在发送命令", device_status=1)
  569. data = self.send_data_queue.pop(0)
  570. self.serial_ins.write_cmd(data)
  571. # self.sendSocketMessage(msg="命令发送完成", device_status=2)
  572. else:
  573. # self.t_n += 1
  574. # 加大发送获取基础数据的时间间隔
  575. # 默认为0.01秒一个循环,每隔1.5秒发送数据
  576. if self.t_n == 150:
  577. # self.t_n = 0
  578. self.send_get_all_info_to_mcu()
  579. self.lock.release()
  580. def send_get_all_info_to_mcu(self):
  581. if self.is_get_mcu_state is False:
  582. return
  583. data = [self.command["get_all_info"], 1]
  584. self.serial_ins.write_cmd(data)
  585. def print_mcu_error_data(self, receive_data):
  586. # 扫码数据
  587. try:
  588. data = receive_data[1:].decode()
  589. if "设备初始化完成" in data:
  590. self.init_state = True
  591. logger.info(f"设备初始化完成:%{data}")
  592. self.sendSocketMessage(msg=data, device_status=2)
  593. else:
  594. # print("设备异常数据打印:", data)
  595. logger.info(f"115 设备异常数据打印:%{data}")
  596. current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
  597. msg_data = {
  598. "message": data,
  599. "current_time": current_time
  600. }
  601. self.msg_type = "print_mcu_error_data"
  602. self.sendSocketMessage(msg="设备信息打印", data=msg_data, device_status=2)
  603. self.msg_type = "mcu"
  604. except BaseException as e:
  605. print("117 error {}".format(e))
  606. logger.info(f"117 error %{e}")
  607. return
  608. def print_mcu_noraml_data(self, receive_data):
  609. # 扫码数据
  610. print("接收到255数据:", receive_data)
  611. try:
  612. command_mapping = {
  613. 1: "设备运动",
  614. 2: "初始化设备", # 初始化设备
  615. 3: "处理其他设备", # 处理其他设备
  616. 29: "获取所有信息", # 获取所有信息
  617. 40: "设置偏移量", # 设置偏移量
  618. 41: "读取偏移量", # 读取偏移量
  619. 91: "信号转发处理", # 信号转发处理
  620. 92: "信号转发返回", # 信号转发返回
  621. 44: "获取其他信息", # 获取其他信息
  622. 43: "RGB灯的处理与通讯", ## RGB灯的处理与通讯
  623. 45: "设置其他信息", # 设置其他信息
  624. 47: "查询遥控器电量", # 查询遥控器电量
  625. 48: "设置转盘通讯方式 1、串口、2、无线、3 混合", #
  626. 93: "停止运行mcu", # 停止运行mcu
  627. 90: "连接MCU", # 连接MCU
  628. }
  629. # command = int(receive_data[0])
  630. command = int(receive_data[1])
  631. command_text = command_mapping[command]
  632. # receive_data_temp = receive_data[2:]
  633. receive_data_temp_text = " ".join([hex(x) for x in receive_data])
  634. # print("255 command_text:", command_text)
  635. if command_text in ["设备运动", "处理其他设备"]:
  636. device_id = int(receive_data[2])
  637. device_value = int(receive_data[3])
  638. device_name_info = self.device_name_dict_mapping[device_id]
  639. message_info = {"设备名称": device_name_info, "运动值": device_value}
  640. print("【设备运动】消息回执:", message_info)
  641. logger.info(f"设备运动消息回执:{message_info}")
  642. print("接收设备消息回执:", command_text)
  643. logger.info(f"接收设备消息回执:{receive_data_temp_text}")
  644. except BaseException as e:
  645. print(f"255 error {e}")
  646. logger.info(f"255 error {e}")
  647. return
  648. def get_from_mcu_move_respond_data(self, receive_data):
  649. self.last_from_mcu_move_respond_data = receive_data
  650. def get_from_mcu_connect_info(self, receive_data):
  651. connect_flag = receive_data[1]
  652. device_id = receive_data[2]
  653. try:
  654. mcu_has_been_set = receive_data[6] # 设备是否有初始化 ,1 表示已初始化
  655. except:
  656. mcu_has_been_set = 99 # 未知状态
  657. # self.self_sign.emit({"type": "connect_sign", "data": connect_flag})
  658. message = {"type": "connect_sign", "data": connect_flag}
  659. self.sendSocketMessage(msg="接收连接信息", data=message)
  660. print("接收链接信息")
  661. logger.info("接收链接信息")
  662. return
  663. def to_init_device_origin_point(self, device_name, is_force=False):
  664. device_id = self.device_name_dict[device_name]
  665. cmd = 2
  666. data = [cmd, device_id, 0 if is_force is False else 1]
  667. self.open_rgb_led(color_name="红色")
  668. self.add_send_data_queue(data)
  669. if device_name == "mcu":
  670. # 重置初始化标记为 从未初始化
  671. self.is_just_init_time = False
  672. return
  673. def set_stepper_disable(self, device_name, flag):
  674. if device_name in self.device_name_dict:
  675. device_id = self.device_name_dict[device_name]
  676. buf = [self.command["set_stepper_disable"],
  677. device_id,
  678. 1 if flag else 0,
  679. ]
  680. self.add_send_data_queue(buf)
  681. def to_recheck_focal(self, device_name, is_force=False):
  682. # 重新校准对焦圈
  683. device_id = self.device_name_dict[device_name]
  684. cmd = 2
  685. data = [cmd, device_id, 1]
  686. self.add_send_data_queue(data)
  687. return True
  688. # 设置其他信息
  689. def set_to_mcu_other_info(self, data):
  690. is_auto_send_base_info = data["is_auto_send_base_info"]
  691. is_move_retry = data["is_move_retry"]
  692. is_data_response = data["is_data_response"]
  693. low_speed = data["low_speed"]
  694. is_test = data["is_test"]
  695. to_init_mode = data["to_init_mode"]
  696. turntable_move_to_init_mode = data["turntable_move_to_init_mode"]
  697. led_count = data["led_count"]
  698. turntable_steering_angle_ratio = data["turntable_steering_angle_ratio"]
  699. is_manual_check = data["is_manual_check"]
  700. camera_steering_angle_ratio = data["camera_steering_angle_ratio"]
  701. is_auto_motor_to_disable = data["is_auto_motor_to_disable"]
  702. diff_dir = data["diff_dir"]
  703. is_auto_send_pos_info = data["is_auto_send_pos_info"]
  704. is_dog = data["is_dog"]
  705. has_been_set_motor_config = data["has_been_set_motor_config"]
  706. buf = [self.command["set_other_info"]]
  707. buf.extend(self.encapsulation_data(data=is_auto_send_base_info, len_data=1))
  708. buf.extend(self.encapsulation_data(data=is_move_retry, len_data=1))
  709. buf.extend(self.encapsulation_data(data=is_data_response, len_data=1))
  710. buf.extend(self.encapsulation_data(data=low_speed, len_data=2))
  711. buf.extend(self.encapsulation_data(data=is_test, len_data=1))
  712. buf.extend(self.encapsulation_data(data=to_init_mode, len_data=1))
  713. buf.extend(
  714. self.encapsulation_data(data=turntable_move_to_init_mode, len_data=1)
  715. )
  716. buf.extend(self.encapsulation_data(data=led_count, len_data=2))
  717. buf.extend(
  718. self.encapsulation_data(data=turntable_steering_angle_ratio, len_data=2)
  719. )
  720. buf.extend(self.encapsulation_data(data=is_manual_check, len_data=1))
  721. buf.extend(
  722. self.encapsulation_data(data=camera_steering_angle_ratio, len_data=4)
  723. )
  724. buf.extend(self.encapsulation_data(data=is_auto_motor_to_disable, len_data=1))
  725. buf.extend(self.encapsulation_data(data=diff_dir, len_data=1))
  726. buf.extend(self.encapsulation_data(data=is_auto_send_pos_info, len_data=1))
  727. buf.extend(self.encapsulation_data(data=is_dog, len_data=1))
  728. buf.extend(self.encapsulation_data(data=has_been_set_motor_config, len_data=1))
  729. self.add_send_data_queue(buf)
  730. async def cleanAllReceiveData(self):
  731. while True:
  732. await asyncio.sleep(0.001)
  733. receive_data = self.serial_ins.read_cmd(out_time=1)
  734. if not receive_data:
  735. break
  736. def get_basic_info_mcu(self):
  737. receive_data = self.serial_ins.read_cmd(out_time=1)
  738. if receive_data is False:
  739. logger.info("get_basic_info_mcu,------------------------------------------------4657564654")
  740. self.connect_state = False
  741. return False
  742. if not receive_data:
  743. return False
  744. command = receive_data[0]
  745. logger.info(f"get_basic_info_mcu{command}")
  746. if command in self.deal_code_func_dict:
  747. _data = ' '.join([hex(x) for x in receive_data])
  748. return self.deal_code_func_dict[command](receive_data)
  749. return False
  750. def get_from_mcu_button(self, receive_data):
  751. button_name = receive_data[1]
  752. self.deal_mcu_button(button_name)
  753. def deal_mcu_button(self, button_name):
  754. # 防止重复点击
  755. s = time.time()
  756. if s - self.last_push_time[button_name] > 0.1:
  757. self.last_push_time[button_name] = s
  758. # print("button_name", button_name)
  759. else:
  760. self.last_push_time[button_name] = s
  761. return
  762. if button_name == 1:
  763. # 自动执行全部
  764. # self.sign_data.emit(
  765. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  766. # )
  767. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_1"}
  768. self.sendSocketMessage(code=0, msg="", data=message)
  769. if button_name == 2:
  770. # self.sign_data.emit(
  771. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  772. # )
  773. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_2"}
  774. self.sendSocketMessage(code=0, msg="", data=message)
  775. if button_name == 3:
  776. # self.sign_data.emit(
  777. # {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  778. # )
  779. message = {"_type": "mcu_button", "plugins_mode": "mcu", "data": "todo_3"}
  780. self.sendSocketMessage(code=0, msg="", data=message)
  781. # 获取偏移量信息
  782. def get_from_mcu_deviation_info(self, receive_data):
  783. if len(receive_data) == 18:
  784. camera_high_motor_deviation_dir = receive_data[1]
  785. camera_high_motor_deviation = receive_data[2] << 8 | receive_data[3]
  786. camera_high_motor_deviation = (
  787. camera_high_motor_deviation * -1
  788. if camera_high_motor_deviation_dir == 0
  789. else camera_high_motor_deviation
  790. )
  791. camera_steering_deviation_dir = receive_data[4]
  792. camera_steering_deviation = (receive_data[5] << 8 | receive_data[6]) * 0.1
  793. camera_steering_deviation = (
  794. camera_steering_deviation * -1
  795. if camera_steering_deviation_dir == 0
  796. else camera_steering_deviation
  797. )
  798. turntable_steering_deviation_dir = receive_data[7]
  799. turntable_steering_deviation = (
  800. receive_data[8] << 8 | receive_data[9]
  801. ) * 0.1
  802. turntable_steering_deviation = (
  803. turntable_steering_deviation * -1
  804. if turntable_steering_deviation_dir == 0
  805. else turntable_steering_deviation
  806. )
  807. overturn_steering_middle_dir = receive_data[10]
  808. overturn_steering_middle = (receive_data[11] << 8 | receive_data[12]) * 0.1
  809. overturn_steering_middle = (
  810. overturn_steering_middle * -1
  811. if overturn_steering_middle_dir == 0
  812. else overturn_steering_middle
  813. )
  814. overturn_steering_high_dir = receive_data[13]
  815. overturn_steering_high = (receive_data[14] << 8 | receive_data[15]) * 0.1
  816. overturn_steering_high = (
  817. overturn_steering_middle * -1
  818. if overturn_steering_high_dir == 0
  819. else overturn_steering_high
  820. )
  821. overturn_steering_up_speed = receive_data[16]
  822. overturn_steering_down_speed = receive_data[17]
  823. self.camera_high_motor_deviation_offset = camera_high_motor_deviation
  824. get_deviation_data = {
  825. "camera_high_motor_deviation": camera_high_motor_deviation,
  826. "camera_steering_deviation": camera_steering_deviation,
  827. "turntable_steering_deviation": turntable_steering_deviation,
  828. "turntable_front_end_deviation": 300,
  829. "overturn_steering_middle": overturn_steering_middle,
  830. "overturn_steering_high": overturn_steering_high,
  831. "overturn_steering_up_speed": overturn_steering_up_speed,
  832. "overturn_steering_down_speed": overturn_steering_down_speed,
  833. }
  834. self.initDeviationInfo(get_deviation_data)
  835. self.msg_type = "get_deviation_data"
  836. self.sendSocketMessage(msg="接收偏移量信息", data=get_deviation_data)
  837. self.msg_type = "mcu"
  838. print("接收偏移量信息", get_deviation_data)
  839. logger.info("接收偏移量信息")
  840. return
  841. def initDeviationInfo(self, get_deviation_data):
  842. # 初始化偏移量信息
  843. camera_high_motor_deviation = get_deviation_data["camera_high_motor_deviation"]
  844. camera_steering_deviation = get_deviation_data["camera_steering_deviation"]
  845. turntable_steering_deviation = get_deviation_data[
  846. "turntable_steering_deviation"
  847. ]
  848. overturn_steering_middle = get_deviation_data["overturn_steering_middle"]
  849. overturn_steering_high = get_deviation_data["overturn_steering_high"]
  850. overturn_steering_up_speed = get_deviation_data["overturn_steering_up_speed"]
  851. overturn_steering_down_speed = get_deviation_data[
  852. "overturn_steering_down_speed"
  853. ]
  854. self.mcu_deviation_set.last_value["相机电机"] = camera_high_motor_deviation
  855. self.mcu_deviation_set.last_value["相机舵机"] = camera_steering_deviation
  856. self.mcu_deviation_set.last_value["转盘舵机"] = turntable_steering_deviation
  857. self.mcu_deviation_set.last_value["翻板舵机中位"] = overturn_steering_middle
  858. self.mcu_deviation_set.last_value["翻板舵机高位"] = overturn_steering_high
  859. self.mcu_deviation_set.last_value["翻板舵机上升速度"] = (
  860. overturn_steering_up_speed
  861. )
  862. self.mcu_deviation_set.last_value["翻板舵机下降速度"] = (
  863. overturn_steering_down_speed
  864. )
  865. # 获取其他信息
  866. def get_from_mcu_other_info(self, receive_data):
  867. # TODO 已完成设置
  868. is_auto_send_base_info = self.get_data_from_receive_data(
  869. receive_data=receive_data, start=1, len_data=1
  870. )
  871. is_move_retry = self.get_data_from_receive_data(
  872. receive_data=receive_data, start=2, len_data=1
  873. )
  874. is_data_response = self.get_data_from_receive_data(
  875. receive_data=receive_data, start=3, len_data=1
  876. )
  877. low_speed = self.get_data_from_receive_data(
  878. receive_data=receive_data, start=4, len_data=2
  879. )
  880. is_test = self.get_data_from_receive_data(
  881. receive_data=receive_data, start=6, len_data=1
  882. )
  883. to_init_mode = self.get_data_from_receive_data(
  884. receive_data=receive_data, start=7, len_data=1
  885. )
  886. turntable_move_to_init_mode = self.get_data_from_receive_data(
  887. receive_data=receive_data, start=8, len_data=1
  888. )
  889. led_count = self.get_data_from_receive_data(
  890. receive_data=receive_data, start=9, len_data=2
  891. )
  892. turntable_steering_angle_ratio = self.get_data_from_receive_data(
  893. receive_data=receive_data, start=11, len_data=2
  894. )
  895. is_manual_check = self.get_data_from_receive_data(
  896. receive_data=receive_data, start=13, len_data=1
  897. )
  898. camera_steering_angle_ratio = self.get_data_from_receive_data(
  899. receive_data=receive_data, start=14, len_data=4
  900. )
  901. is_auto_motor_to_disable = self.get_data_from_receive_data(
  902. receive_data=receive_data, start=18, len_data=1
  903. )
  904. diff_dir = self.get_data_from_receive_data(
  905. receive_data=receive_data, start=19, len_data=1
  906. )
  907. is_auto_send_pos_info = self.get_data_from_receive_data(
  908. receive_data=receive_data, start=20, len_data=1
  909. )
  910. is_dog = self.get_data_from_receive_data(
  911. receive_data=receive_data, start=21, len_data=1
  912. )
  913. has_been_set_motor_config = self.get_data_from_receive_data(
  914. receive_data=receive_data, start=22, len_data=1
  915. )
  916. self.last_mcu_other_info_data["data"] = {
  917. "is_auto_send_base_info": is_auto_send_base_info,
  918. "is_move_retry": is_move_retry,
  919. "is_data_response": is_data_response,
  920. "low_speed": low_speed,
  921. "is_test": is_test,
  922. "to_init_mode": to_init_mode,
  923. "turntable_move_to_init_mode": turntable_move_to_init_mode,
  924. "led_count": led_count,
  925. "turntable_steering_angle_ratio": turntable_steering_angle_ratio,
  926. "is_manual_check": is_manual_check,
  927. "camera_steering_angle_ratio": camera_steering_angle_ratio,
  928. "is_auto_motor_to_disable": is_auto_motor_to_disable,
  929. "diff_dir": diff_dir,
  930. "is_auto_send_pos_info": is_auto_send_pos_info,
  931. "is_dog": is_dog,
  932. "has_been_set_motor_config": has_been_set_motor_config,
  933. }
  934. self.last_mcu_other_info_data["time"] = time.time()
  935. self.last_mcu_other_info_data["num"] += 1
  936. for k, v in self.last_mcu_other_info_data["data"].items():
  937. print("k:{},v:{}".format(k, v))
  938. logger.info("k:%s,v:%s", k, v)
  939. self.msg_type = "get_mcu_other_info"
  940. self.sendSocketMessage(
  941. code=0,
  942. msg="获取mcu其他配置信息",
  943. device_status=2,
  944. data=self.last_mcu_other_info_data["data"],
  945. )
  946. self.msg_type = "mcu"
  947. def get_data_from_receive_data(
  948. self, receive_data, start, len_data, data_magnification=1
  949. ):
  950. # data_magnification 数据放大倍数,或缩小倍数,默认为1
  951. try:
  952. if len_data == 1:
  953. data = receive_data[start]
  954. return data * data_magnification
  955. elif len_data == 2:
  956. data = receive_data[start] << 8 | receive_data[start + 1]
  957. return data * data_magnification
  958. elif len_data == 4:
  959. data = (
  960. receive_data[start] << 24
  961. | receive_data[start + 1] << 16
  962. | receive_data[start + 2] << 8
  963. | receive_data[start + 3]
  964. )
  965. return data * data_magnification
  966. return None
  967. except:
  968. return None
  969. def get_from_mcu_base_info(self, receive_data):
  970. # 数据缓存
  971. self.last_mcu_info_data["time"] = time.time()
  972. self.last_mcu_info_data["num"] += 1
  973. # print("last_mcu_info_data:{}".format(self.last_mcu_info_data["time"]))
  974. self.state_camera_motor = 3
  975. self.state_camera_steering = 3
  976. self.state_turntable_steering = 3
  977. self.state_overturn_steering = 3
  978. self.state_move_turntable_steering = 3
  979. if len(receive_data) == 7:
  980. self.m_t = 1
  981. laser_state = receive_data[1]
  982. self.state_camera_motor = receive_data[2]
  983. self.state_camera_steering = receive_data[3]
  984. self.state_turntable_steering = receive_data[4]
  985. self.state_overturn_steering = receive_data[5]
  986. flag = receive_data[6]
  987. message = {
  988. "_type": "show_mcu_info",
  989. "plugins_mode": "mcu",
  990. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  991. laser_state=laser_state,
  992. state_camera_motor=self.state_camera_motor,
  993. state_camera_steering=self.state_camera_steering,
  994. state_turntable_steering=self.state_turntable_steering,
  995. state_overturn_steering=self.state_overturn_steering,
  996. flag=flag,
  997. ),
  998. "data_state": {
  999. "state_camera_motor": self.state_camera_motor,
  1000. "state_camera_steering": self.state_camera_steering,
  1001. "state_turntable_steering": self.state_turntable_steering,
  1002. "state_overturn_steering": self.state_overturn_steering,
  1003. },
  1004. }
  1005. self.msg_type = "get_mcu_info"
  1006. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  1007. self.msg_type = "mcu"
  1008. # print("转盘:{},时间:{}".format(self.state_turntable_steering, time.time()))
  1009. if len(receive_data) == 8:
  1010. self.m_t = 2
  1011. laser_state = receive_data[1]
  1012. self.state_camera_motor = receive_data[2]
  1013. self.state_camera_steering = receive_data[3]
  1014. self.state_turntable_steering = receive_data[4]
  1015. self.state_overturn_steering = receive_data[5]
  1016. self.state_move_turntable_steering = receive_data[6]
  1017. flag = receive_data[7]
  1018. message = {
  1019. "_type": "show_mcu_info",
  1020. "plugins_mode": "mcu",
  1021. "data": "激光状态;{laser_state},相机高度状态:{state_camera_motor},相机角度状态:{state_camera_steering},转盘状态:{state_turntable_steering},转盘前后移动状态:{state_move_turntable_steering},翻板状态:{state_overturn_steering},flag:{flag}".format(
  1022. laser_state=laser_state,
  1023. state_camera_motor=self.state_camera_motor,
  1024. state_camera_steering=self.state_camera_steering,
  1025. state_turntable_steering=self.state_turntable_steering,
  1026. state_overturn_steering=self.state_overturn_steering,
  1027. state_move_turntable_steering=self.state_move_turntable_steering,
  1028. flag=flag,
  1029. ),
  1030. "data_state": {
  1031. "state_camera_motor": self.state_camera_motor,
  1032. "state_camera_steering": self.state_camera_steering,
  1033. "state_turntable_steering": self.state_turntable_steering,
  1034. "state_overturn_steering": self.state_overturn_steering,
  1035. "state_move_turntable_steering": self.state_move_turntable_steering,
  1036. },
  1037. }
  1038. # if self.state_camera_motor
  1039. if all(
  1040. value == 2
  1041. for value in [
  1042. self.state_camera_motor,
  1043. self.state_camera_steering,
  1044. self.state_turntable_steering,
  1045. self.state_overturn_steering,
  1046. ]
  1047. ):
  1048. self.init_state = True
  1049. self.sendSocketMessage(msg="设备初始化完成", device_status=2)
  1050. self.msg_type = "get_mcu_info"
  1051. self.sendSocketMessage(msg="获取mcu设备运行状态信息", data=message)
  1052. self.msg_type = "mcu"
  1053. # 检查是否成功初始化
  1054. if self.is_just_init_time is False:
  1055. if self.mcu_move_state == 2:
  1056. self.is_just_init_time = True
  1057. print("is_just_init_time")
  1058. logger.info("设备初始化完成")
  1059. message = {
  1060. "_type": "is_just_init_time",
  1061. "plugins_mode": "mcu",
  1062. "data": "",
  1063. }
  1064. self.sendSocketMessage(msg="检查设备初始化", data=message)
  1065. return
  1066. def scan_serial_port(self) -> dict:
  1067. # 获取所有可用串口列表
  1068. ports_dict = {}
  1069. ports = serial.tools.list_ports.comports()
  1070. # 遍历所有端口并打印信息
  1071. for port in ports:
  1072. # logger.info("扫描到的串口信息:{}".format(port.description))
  1073. if "CH34" in port.description:
  1074. ports_dict[port.name] = {
  1075. "name": port.name,
  1076. "device": port.device,
  1077. "description": port.description,
  1078. "hwid": port.hwid,
  1079. "manufacturer": port.manufacturer,
  1080. "product": port.product,
  1081. "serial_number": port.serial_number,
  1082. }
  1083. if len(ports_dict) <= 0:
  1084. return {}
  1085. return ports_dict
  1086. def remove_port(self, port_name):
  1087. """移除串口"""
  1088. print("remove", port_name)
  1089. logger.info("串口被移除")
  1090. data = {
  1091. "_type": "remove_port",
  1092. "plugins_mode": "auto_select_com",
  1093. "data": {"port_name": port_name},
  1094. }
  1095. self.sendSocketMessage(1, "串口被移除", data)
  1096. def is_serial_available(self, port):
  1097. try:
  1098. ser = serial.Serial(port)
  1099. ser.close()
  1100. return True
  1101. except serial.serialException:
  1102. return False
  1103. async def add_port_by_linkage(self, port_name):
  1104. # port_value :串口基础信息
  1105. # todo 根据prot_value 信息自动进行连接
  1106. print("add port_name", port_name)
  1107. logger.info("add port_name %s", port_name)
  1108. print("self.port_name", self.port_name)
  1109. logger.info("self.port_name %s", self.port_name)
  1110. if self.port_name == port_name:
  1111. self.port_name = ""
  1112. # 对没有连接的设备进行尝试连接
  1113. # 如果存在串口被占用则进行断开
  1114. self.is_serial_available(port_name)
  1115. return False
  1116. message_data = {
  1117. "_type": "show_info",
  1118. "plugins_mode": "auto_select_com",
  1119. "data": {"text": "开始识别接口:{}".format(port_name)},
  1120. }
  1121. self.sendSocketMessage(
  1122. msg="开始识别接口:{}".format(port_name), data=message_data, device_status=1
  1123. )
  1124. await asyncio.sleep(1)
  1125. """
  1126. 步骤:
  1127. 1、进行临时连接,并发送命令,成功后,自动连接对应设备
  1128. """
  1129. try:
  1130. # 尝试使用115200波特率链接
  1131. serial_handle = serial.Serial(port=port_name, baudrate=115200, timeout=0.5)
  1132. except Exception as e:
  1133. message_data = {
  1134. "_type": "show_info",
  1135. "plugins_mode": "auto_select_com",
  1136. "data": {"text": "串口:{} 被占用,或无法识别".format(port_name)},
  1137. }
  1138. self.sendSocketMessage(
  1139. 1,
  1140. msg="串口:{} 被占用,或无法识别".format(port_name).format(port_name),
  1141. data=message_data,
  1142. device_status=-1,
  1143. )
  1144. print("串口:{} 被占用".format(port_name))
  1145. logger.info("串口:%s 被占用", port_name)
  1146. if self.serial_ins.serial_handle is not None:
  1147. self.serial_ins.serial_handle.close()
  1148. return False
  1149. await asyncio.sleep(2)
  1150. print("开始发送命令")
  1151. logger.info("开始发送命令")
  1152. data = [90, 1]
  1153. try:
  1154. serial_handle.flushInput() # 尝试重置输入缓冲区
  1155. except serial.SerialTimeoutException:
  1156. print("超时错误:无法在规定时间内重置输入缓冲区。")
  1157. logger.info("超时错误:无法在规定时间内重置输入缓冲区。")
  1158. self.sendSocketMessage(
  1159. 1,
  1160. msg="超时错误:无法在规定时间内重置输入缓冲区。",
  1161. data=None,
  1162. )
  1163. serial_handle.close()
  1164. return False
  1165. print("尝试写入数据")
  1166. logger.info("尝试写入数据")
  1167. buf = bytearray(b"")
  1168. buf.extend([0x55, 0x55, (0xFF & len(data))])
  1169. buf.extend(data)
  1170. buf.extend([0xFF & ~sum(data)])
  1171. try:
  1172. self.receive_data = b""
  1173. serial_handle.write(buf)
  1174. except serial.SerialTimeoutException:
  1175. print("写入数据错误")
  1176. logger.info("写入数据错误")
  1177. serial_handle.close()
  1178. return False
  1179. await asyncio.sleep(0.3)
  1180. receive_data = self.read_cmd(serial_handle)
  1181. # print("尝试接收命令", receive_data)
  1182. # logger.info("尝试接收命令,%s", receive_data)
  1183. device_id = 0
  1184. if receive_data:
  1185. print("receive_data", receive_data)
  1186. logger.info("receive_data %s", receive_data)
  1187. if receive_data[0] == 90:
  1188. connect_flag = receive_data[1]
  1189. device_id = receive_data[2]
  1190. else:
  1191. logger.info("串口数据未监听到,继续等待...%s", port_name)
  1192. return False
  1193. print("关闭串口:{}".format(port_name))
  1194. logger.info("关闭串口:%s", port_name)
  1195. serial_handle.close()
  1196. loop = asyncio.get_event_loop()
  1197. print("device_id============>>>", device_id)
  1198. logger.info("device_id============>>>%s", device_id)
  1199. if device_id > 0:
  1200. if device_id == settings.MCU_CODE:
  1201. state, _ = self.to_connect_com(port_name)
  1202. if not state:
  1203. return False
  1204. message_data = {
  1205. "_type": "show_info",
  1206. "plugins_mode": "auto_select_com",
  1207. "data": {"text": "MCU开始连接"},
  1208. }
  1209. self.sendSocketMessage(
  1210. msg="MCU开始连接", data=message_data, device_status=1
  1211. )
  1212. self.connected_ports_dict[port_name] = "MCU"
  1213. message_data = {
  1214. "_type": "select_port_name",
  1215. "plugins_mode": "auto_select_com",
  1216. "data": {
  1217. "device_name": "mcu" if device_id == 1 else "remote_control",
  1218. "port_name": port_name,
  1219. },
  1220. }
  1221. return True
  1222. elif device_id == 2:
  1223. # 有线接收器
  1224. self.connected_ports_dict[port_name] = "Line_Control"
  1225. # print("device_id", device_id)
  1226. # logger.info("device_id %s", device_id)
  1227. state = await self.line_control.to_connect_com(port_name)
  1228. if not state:
  1229. return False
  1230. self.line_control.connect_state = True
  1231. return True
  1232. else:
  1233. print("串口无法识别")
  1234. logger.info("串口无法识别")
  1235. self.sendSocketMessage(
  1236. code=1,
  1237. msg="串口无法识别,请重新插拔拍照机USB",
  1238. data=message_data,
  1239. device_status=-1,
  1240. )
  1241. return False
  1242. # 走其他途径处理
  1243. def clearMyInstance(self):
  1244. SingletonType.clear_instance()
  1245. def to_connect_com(self, port_name):
  1246. # 关闭串口
  1247. print("to_connect_com", port_name)
  1248. logger.info("to_connect_com %s", port_name)
  1249. self.close_connect()
  1250. time.sleep(0.3)
  1251. self.connect_state = False
  1252. try:
  1253. self.serial_ins = SerialIns(port_name=port_name, baud=115200, timeout=0.1)
  1254. if not self.serial_ins.serial_handle:
  1255. message_data = {
  1256. "_type": "show_info",
  1257. "plugins_mode": "mcu",
  1258. "data": "MCU 打开串口失败",
  1259. }
  1260. self.sendSocketMessage(
  1261. msg="MCU 打开串口失败", data=message_data, device_status=-1
  1262. )
  1263. self.serial_ins = None
  1264. self.connect_state = False
  1265. return False, None
  1266. except:
  1267. message_data = {
  1268. "_type": "show_info",
  1269. "plugins_mode": "mcu",
  1270. "data": "MCU 打开串口失败",
  1271. }
  1272. self.sendSocketMessage(
  1273. msg="MCU 打开串口失败", data=message_data, device_status=-1
  1274. )
  1275. self.serial_ins = None
  1276. self.connect_state = False
  1277. return False, None
  1278. message_data = {
  1279. "_type": "show_info",
  1280. "plugins_mode": "mcu",
  1281. "data": "MCU 开始连接",
  1282. }
  1283. self.sendSocketMessage(msg="MCU 开始连接", data=message_data, device_status=1)
  1284. # =======================发送连接请求=================================
  1285. cmd = 90
  1286. data = [cmd, 1]
  1287. print("405 发送 连接请求 -----------------------------------------")
  1288. logger.info("405 发送 连接请求 -----------------------------------------")
  1289. print(self.serial_ins)
  1290. logger.info(self.serial_ins)
  1291. # self.serial_ins.clearn_flush()
  1292. self.serial_ins.write_cmd(data)
  1293. # 延迟接收数据
  1294. time.sleep(0.3)
  1295. receive_data = self.serial_ins.read_cmd(out_time=1)
  1296. if receive_data:
  1297. print(
  1298. "409 receive_data--90:{}".format(self.change_hex_to_int(receive_data))
  1299. )
  1300. logger.info(
  1301. "409 receive_data--90:%s", str(self.change_hex_to_int(receive_data))
  1302. )
  1303. else:
  1304. return False, None
  1305. if receive_data:
  1306. # receive_data[2]=1 表示为MCU设备编号
  1307. if receive_data[0] == 90 and receive_data[2] == settings.MCU_CODE:
  1308. connect_flag = receive_data[1]
  1309. # 是否有初始化
  1310. try:
  1311. mcu_has_been_set = receive_data[
  1312. 6
  1313. ] # 设备是否有初始化 ,1 表示已初始化
  1314. except:
  1315. mcu_has_been_set = 99 # 未知状态
  1316. print("MCU初始化信息{}".format(mcu_has_been_set))
  1317. logger.info("MCU初始化信息%s", str(mcu_has_been_set))
  1318. message_data = {
  1319. "_type": "show_info",
  1320. "plugins_mode": "mcu",
  1321. "data": "MCU 已连接",
  1322. }
  1323. self.sendSocketMessage(
  1324. msg="MCU 已连接", data=message_data, device_status=1
  1325. )
  1326. self.connect_state = True
  1327. self.is_running = True
  1328. print("MCU 已连接")
  1329. logger.info("MCU 已连接")
  1330. self.port_name = port_name
  1331. # time.sleep(2)
  1332. loop = asyncio.get_event_loop()
  1333. # # 异步处理
  1334. loop.create_task(self.initDevice(), name="initDevice")
  1335. return True, None
  1336. print("MCU 连接失败")
  1337. logger.info("MCU 连接失败")
  1338. # for port in self.p_list:
  1339. # logger.info(
  1340. # "MCU 连接失败处理list移除操作,self port name %s,p_list:%s",
  1341. # port_name,
  1342. # self.p_list,
  1343. # )
  1344. # if port == port_name:
  1345. # logger.info("MCU 连接失败处理list移除操作,移除 %s", port_name)
  1346. # self.p_list.remove(port)
  1347. # self.remove_port(port)
  1348. message_data = {
  1349. "_type": "show_info",
  1350. "plugins_mode": "mcu",
  1351. "data": "MCU 连接失败",
  1352. }
  1353. self.sendSocketMessage(msg="MCU 连接失败", data=message_data, device_status=-1)
  1354. self.close_connect()
  1355. return False, None
  1356. def close_connect(self):
  1357. self.port_name = ""
  1358. if self.serial_ins:
  1359. self.serial_ins.close_serial_port()
  1360. self.is_running = False
  1361. self.connect_state = False
  1362. self.connected_ports_dict = {} # 已连接的ports
  1363. # self.p_list = []
  1364. # self.temp_ports_dict = {}
  1365. self.init_state = False
  1366. print("关闭MCU")
  1367. logger.info("关闭MCU")
  1368. def close_lineConnect(self):
  1369. """'关闭有线遥控器连接"""
  1370. self.line_control.port_name = ""
  1371. self.line_control.close_connect()
  1372. print("关闭有线遥控器")
  1373. logger.info("关闭有线遥控器")
  1374. @property
  1375. def mcu_move_state(self):
  1376. if self.is_get_mcu_state is False:
  1377. self._mcu_move_state = 2
  1378. # self.action_state = 2
  1379. else:
  1380. if self.m_t == 1:
  1381. if (
  1382. self.state_camera_motor == 2
  1383. and self.state_camera_steering == 2
  1384. and self.state_turntable_steering == 2
  1385. and self.state_overturn_steering == 2
  1386. ):
  1387. self._mcu_move_state = 2
  1388. else:
  1389. self._mcu_move_state = 1
  1390. else:
  1391. if (
  1392. self.state_camera_motor == 2
  1393. and self.state_camera_steering == 2
  1394. and self.state_turntable_steering == 2
  1395. and self.state_overturn_steering == 2
  1396. and self.state_move_turntable_steering == 2
  1397. ):
  1398. self._mcu_move_state = 2
  1399. else:
  1400. self._mcu_move_state = 1
  1401. # self._mcu_move_state = 2
  1402. return self._mcu_move_state
  1403. def to_deal_device(self, device_name, value=1, _type=0, times=1, delay=0):
  1404. """
  1405. value 激光0关 1开
  1406. mp3_player value 表示0表示关,1表示开,_type 表示歌曲切换到指定歌曲
  1407. delay:延迟处理,单位为0.1秒,即delay=100时,表示延迟10秒
  1408. """
  1409. device_id = self.device_name_dict[device_name]
  1410. if device_name == "buzzer":
  1411. value = int(value)
  1412. cmd = 3
  1413. data = [
  1414. cmd,
  1415. device_id,
  1416. value,
  1417. _type,
  1418. times,
  1419. delay,
  1420. ]
  1421. self.add_send_data_queue(data)
  1422. # if self.serial_ins:
  1423. # self.serial_ins.write_cmd(data)
  1424. return True
  1425. def to_device_move(
  1426. self,
  1427. device_name,
  1428. value=0,
  1429. max_speed=None,
  1430. up_speed=None,
  1431. down_speed=None,
  1432. _is_debug=0,
  1433. is_relative=0,
  1434. is_deviation=1,
  1435. times=2, is_response=False
  1436. ):
  1437. """
  1438. 此处输入单位为 毫米,以及度 需要先缩小,再放大
  1439. """
  1440. self.seed += 1
  1441. if self.seed > 9000:
  1442. self.seed = 1
  1443. print("移动", time.time())
  1444. logger.info("移动,%s", time.time())
  1445. speed = settings.moveSpeed()
  1446. cmd = 1
  1447. device_id = self.device_name_dict[device_name]
  1448. # if device_id != 1:
  1449. # print("F非MCU设备,禁止处理")
  1450. # return
  1451. print("正在执行", device_name)
  1452. logger.info("正在执行 %s", device_name)
  1453. match device_name:
  1454. case "camera_high_motor":
  1455. # value 单位毫米
  1456. # max_speed = 10000 if max_speed is None else max_speed
  1457. # up_speed = 800 if up_speed is None else up_speed
  1458. # down_speed = 700 if down_speed is None else down_speed
  1459. max_speed = (
  1460. speed[device_name]["max_speed"] if max_speed is None else max_speed
  1461. )
  1462. up_speed = (
  1463. speed[device_name]["up_speed"] if up_speed is None else up_speed
  1464. )
  1465. down_speed = (
  1466. speed[device_name]["down_speed"]
  1467. if down_speed is None
  1468. else down_speed
  1469. )
  1470. value = value / 10 # value 单位毫米
  1471. max_camera_hight = self.camera_height / 10
  1472. # print("高度位置",max_camera_hight)
  1473. if value > max_camera_hight:
  1474. value = max_camera_hight
  1475. assert 0 <= value <= max_camera_hight
  1476. assert 0 <= max_speed <= 10000
  1477. case "camera_steering":
  1478. # 角度为度 未放大 精确到0.1度
  1479. max_speed = 6000 if max_speed is None else max_speed
  1480. up_speed = 500 if up_speed is None else up_speed
  1481. down_speed = 500 if down_speed is None else down_speed
  1482. assert -360 <= value <= 360
  1483. case "turntable_steering":
  1484. # 角度为度 未放大 精确到0.1度
  1485. # max_speed = 6000 if max_speed is None else max_speed
  1486. # up_speed = 500 if up_speed is None else up_speed
  1487. # down_speed = 400 if down_speed is None else down_speed
  1488. max_speed = (
  1489. speed[device_name]["max_speed"] if max_speed is None else max_speed
  1490. )
  1491. up_speed = (
  1492. speed[device_name]["up_speed"] if up_speed is None else up_speed
  1493. )
  1494. down_speed = (
  1495. speed[device_name]["down_speed"]
  1496. if down_speed is None
  1497. else down_speed
  1498. )
  1499. assert -720 <= value <= 720
  1500. case "overturn_steering":
  1501. # 角度为度 未放大 精确到0.1度
  1502. max_speed = 2 if max_speed is None else max_speed
  1503. up_speed = 1 if up_speed is None else up_speed
  1504. down_speed = 1 if down_speed is None else down_speed
  1505. assert 0 <= value <= 360
  1506. case "turntable_position_motor":
  1507. # value 单位毫米
  1508. max_speed = 11000 if max_speed is None else max_speed
  1509. up_speed = 900 if up_speed is None else up_speed
  1510. down_speed = 900 if down_speed is None else down_speed
  1511. value = value / 10 # value 单位毫米
  1512. assert 0 <= value <= 900
  1513. assert 0 <= max_speed <= 15000
  1514. case "camera_zoom_motor":
  1515. # 相机焦段设置
  1516. # 精确到0.1焦段
  1517. max_speed = 500 if max_speed is None else max_speed
  1518. up_speed = 100 if up_speed is None else up_speed
  1519. down_speed = 100 if down_speed is None else down_speed
  1520. assert 0 <= value <= 150
  1521. _dir = True if value >= 0 else False
  1522. value = int(abs(value * 10)) # 此处value赋值后,单位为mm以及0.1度
  1523. print("准备执行", device_name, value)
  1524. logger.info("准备执行,%s %s", device_name, value)
  1525. data = [
  1526. cmd,
  1527. device_id,
  1528. 1 if _dir else 0,
  1529. 0xFF & value >> 8,
  1530. 0xFF & value,
  1531. 0xFF & max_speed >> 8,
  1532. 0xFF & max_speed,
  1533. 0xFF & up_speed >> 8,
  1534. 0xFF & up_speed,
  1535. 0xFF & down_speed >> 8,
  1536. 0xFF & down_speed,
  1537. _is_debug,
  1538. is_deviation,
  1539. is_relative,
  1540. times, # 重试次数
  1541. 0xff & self.seed >> 8, # 随机种子
  1542. 0xff & self.seed, # 随机种子
  1543. 1 if is_response is True else 0, # 是否返回内容
  1544. ]
  1545. self.add_send_data_queue(data)
  1546. current_time = time.time()
  1547. self.last_move_time = current_time
  1548. def to_get_mcu_base_info(self):
  1549. if self.connect_state:
  1550. self.lock.acquire()
  1551. # print('==========================>1111')
  1552. print("-------------------to_get_mcu_base_info--------------------------")
  1553. data = [self.command["get_all_info"], 1]
  1554. f = True
  1555. try:
  1556. self.serial_ins.write_cmd(data)
  1557. except:
  1558. f = False
  1559. pass
  1560. self.lock.release()
  1561. if not f:
  1562. self.connect_state = False
  1563. return False
  1564. else:
  1565. return True
  1566. def check_before_action(self):
  1567. if self.state != 2:
  1568. print("check_before_action 设备正在运行中~")
  1569. logger.info("check_before_action 设备正在运行中~")
  1570. self.sendSocketMessage(code=1, msg="设备正在运行中", device_status=1)
  1571. return False
  1572. if self.mcu_move_state != 2:
  1573. if settings.IS_LIN_SHI_TEST:
  1574. return True
  1575. # self.show_info("mcu 非停止状态")
  1576. self.sendSocketMessage(code=1, msg="mcu 非停止状态", device_status=1)
  1577. return True
  1578. async def controlDevice(self, device_name, value):
  1579. """控制设备移动等"""
  1580. await asyncio.sleep(0.01)
  1581. if not self.is_running:
  1582. self.sendSocketMessage(
  1583. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  1584. )
  1585. return False
  1586. if not self.init_state:
  1587. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  1588. return False
  1589. _is_debug = 1 if settings.IS_DEBUG == "true" else 0
  1590. is_deviation = 0 if settings.IS_DEBUG == "true" else 1
  1591. print("控制设备==>_is_debug", _is_debug)
  1592. logger.info("控制设备==>_is_debug %s", _is_debug)
  1593. match device_name:
  1594. case "camera_high_motor":
  1595. # 相机电机
  1596. print(device_name, value)
  1597. self.to_device_move(
  1598. device_name=device_name,
  1599. value=float(value),
  1600. )
  1601. self.to_device_move(
  1602. device_name=device_name,
  1603. value=float(value),
  1604. )
  1605. case "camera_steering":
  1606. print(device_name, value)
  1607. # 相机舵机
  1608. self.to_device_move(
  1609. device_name=device_name,
  1610. value=float(value),
  1611. )
  1612. self.to_device_move(
  1613. device_name=device_name,
  1614. value=float(value),
  1615. )
  1616. case "turntable_steering":
  1617. # 转盘舵机
  1618. self.to_device_move(
  1619. device_name=device_name,
  1620. value=float(value),
  1621. )
  1622. self.to_device_move(
  1623. device_name=device_name,
  1624. value=float(value),
  1625. )
  1626. case "turntable_position_motor":
  1627. # 转盘舵机
  1628. self.to_device_move(
  1629. device_name=device_name,
  1630. value=float(value),
  1631. )
  1632. self.to_device_move(
  1633. device_name=device_name,
  1634. value=float(value),
  1635. )
  1636. case "overturn_steering":
  1637. # 翻板舵机中位
  1638. self.to_deal_device(
  1639. device_name="overturn_steering",
  1640. )
  1641. case "laser_position":
  1642. self.to_deal_device(
  1643. device_name="laser_position", value=0 if int(value) <= 0 else 1
  1644. )
  1645. case "take_picture":
  1646. # loop = asyncio.get_event_loop()
  1647. # if value>0:
  1648. # # 指定自动对焦
  1649. # loop.create_task(
  1650. # self.smart_shooter.CameraAutofocus(),
  1651. # name="CameraAutofocus",
  1652. # )
  1653. # 拍照
  1654. await self.smart_shooter.CameraShooter(msg_type="run_mcu")
  1655. case "to_deal_device":
  1656. self.to_deal_device(device_name, value=value, _type=0, times=1)
  1657. case "camera_zoom_motor":
  1658. self.to_device_move(device_name="camera_zoom_motor", value=int(value))
  1659. case "camera_focal_distance":
  1660. self.to_device_move(device_name="camera_zoom_motor", value=int(value))
  1661. case _:
  1662. pass
  1663. async def _do_camera_check(self):
  1664. """执行一次完整的状态查询检测,返回是否全部停止"""
  1665. self.send_get_all_info_to_mcu()
  1666. await asyncio.sleep(0.5)
  1667. return all(
  1668. value == 2
  1669. for value in [
  1670. self.state_camera_motor,
  1671. self.state_camera_steering,
  1672. self.state_turntable_steering,
  1673. self.state_overturn_steering,
  1674. ]
  1675. )
  1676. async def camera_check_mcu_move_is_stop(self, re_check=False):
  1677. _s = time.time()
  1678. check_times = 0
  1679. await self.cleanAllReceiveData()
  1680. while 1:
  1681. if self.action_state != 1:
  1682. return False
  1683. # 发送获取设备状态消息
  1684. if await self._do_camera_check():
  1685. # 首次检测通过,追加一次确认检测,防止读到旧状态误判
  1686. logger.info("拍照前运动检测首次通过,发起确认检测")
  1687. if await self._do_camera_check():
  1688. logger.info("拍照前运动检测状态[成功],确认通过,耗时%.1f秒", time.time() - _s)
  1689. await asyncio.sleep(0.5)
  1690. return True
  1691. else:
  1692. logger.warning("拍照前运动检测确认失败,继续等待")
  1693. check_times += 1
  1694. else:
  1695. check_times += 1
  1696. if check_times > 5:
  1697. logger.info("拍照前运动检测状态[失败],耗时%.1f秒", time.time() - _s)
  1698. return False
  1699. await asyncio.sleep(0.2)
  1700. def checkDevice(self):
  1701. print("检查设备是否运行中")
  1702. logger.info("检查设备是否运行中")
  1703. if not self.is_running:
  1704. self.sendSocketMessage(
  1705. code=1, msg="mcu设备未连接,请先连接设备", device_status=0
  1706. )
  1707. return False
  1708. if self.init_state is not True:
  1709. self.sendSocketMessage(code=1, msg="mcu设备未初始化", device_status=4)
  1710. return False
  1711. if self.action_state != 2:
  1712. self.sendSocketMessage(
  1713. code=1,
  1714. msg="当前有未完成的任务,请稍后再试",
  1715. device_status=0,
  1716. )
  1717. return False
  1718. async def run_mcu_config(
  1719. self, config_list, goods_art_no, action_info, smart_shooter
  1720. ):
  1721. if self.checkDevice() == False:
  1722. return
  1723. image_counts = 0
  1724. if config_list:
  1725. action_names = []
  1726. record_ids = []
  1727. if len(config_list) > 1:
  1728. if config_list[-1]["take_picture"] is True:
  1729. new_init_config = copy.copy(config_list[0])
  1730. new_init_config["action_name"] = "移动到初始位"
  1731. new_init_config["number_focus"] = 0
  1732. new_init_config["take_picture"] = False
  1733. new_init_config["shoe_upturn"] = False
  1734. new_init_config["pre_delay"] = 0.0
  1735. new_init_config["after_delay"] = 0.0
  1736. # new_init_config["point_name"] = "A"
  1737. new_init_config["is_move_device"] = True
  1738. new_init_config["led_switch"] = True
  1739. new_init_config["turntable_angle"] = 0.0
  1740. new_init_config["is_wait"] = False
  1741. new_init_config["is_need_confirm"] = False
  1742. config_list.append(new_init_config)
  1743. for idx, item in enumerate(config_list):
  1744. is_take_picture = item["take_picture"]
  1745. action_id = item["id"]
  1746. record_id = -1
  1747. if is_take_picture:
  1748. image_counts += 1
  1749. # 批量插入
  1750. image_deal_mode = 0 if action_info == "执行左脚程序" else 1
  1751. state, record_id = await insert_photo_records(
  1752. image_deal_mode=image_deal_mode,
  1753. goods_art_no=goods_art_no,
  1754. image_index=idx,
  1755. action_id=action_id,
  1756. )
  1757. config_list[idx]["record_id"] = record_id
  1758. total_len = len(config_list)
  1759. self.action_state = 1
  1760. self.msg_type = "image_process"
  1761. self.sendSocketMessage(
  1762. code=0,
  1763. msg="MCU 命令已发送完成",
  1764. device_status=2,
  1765. data={
  1766. "goods_art_no": goods_art_no,
  1767. "image_counts": image_counts,
  1768. "action_names": action_names,
  1769. "current_time": datetime.datetime.now(settings.TIME_ZONE).strftime(
  1770. "%Y-%m-%d %H:%M:%S"
  1771. ),
  1772. },
  1773. )
  1774. await self.controlDevice("laser_position", 0)
  1775. # await smart_shooter.EnableCameraPreview(
  1776. # enable_status=True, msg_type="smart_shooter_enable_preview"
  1777. # )
  1778. self.msg_type = "mcu"
  1779. self.is_runn_action = True
  1780. for index, action in enumerate(config_list):
  1781. # await asyncio.sleep(0.01)
  1782. if self.is_stop_action == True:
  1783. print("停止命令接收,立即终止")
  1784. logger.info("停止命令接收,立即终止")
  1785. break
  1786. # action_is_take_picture = action["take_picture"]
  1787. record_id = action["record_id"]
  1788. image_index = -1
  1789. if record_id == -1:
  1790. image_index = -1
  1791. else:
  1792. image_index = index
  1793. program_item = ProgramItem(
  1794. websocket_manager=self.websocket_manager,
  1795. action_data=action,
  1796. mcu=self,
  1797. goods_art_no=goods_art_no,
  1798. image_index=image_index,
  1799. smart_shooter=smart_shooter,
  1800. record_id=record_id,
  1801. is_get_mcu_state=True,
  1802. )
  1803. program_item.last_move_time = self.last_move_time
  1804. if self.action_state != 1:
  1805. # 异常终止
  1806. print("action异常终止")
  1807. logger.info("action异常终止")
  1808. break
  1809. self.msg_type = "photo_take"
  1810. if not await program_item.run(total_len):
  1811. self.sendSocketMessage(
  1812. code=1,
  1813. msg="{} 执行失败~".format(program_item.action_name),
  1814. data={"goods_art_no": goods_art_no, "id": action_id},
  1815. device_status=0,
  1816. )
  1817. self.to_deal_device(device_name="buzzer", times=3)
  1818. break
  1819. else:
  1820. if program_item.action_name == "移动到初始位":
  1821. self.msg_type = "mcu"
  1822. break
  1823. self.sendSocketMessage(
  1824. code=0,
  1825. msg="{} 执行完成~".format(program_item.action_name),
  1826. data={"goods_art_no": goods_art_no, "id": record_id},
  1827. device_status=2,
  1828. )
  1829. self.msg_type = "mcu"
  1830. if index == total_len - 1:
  1831. pass
  1832. if self.is_stop_action == True:
  1833. self.msg_type = "run_mcu_stop"
  1834. self.sendSocketMessage(
  1835. code=0,
  1836. msg=f"货号:{goods_art_no},执行终止",
  1837. device_status=2,
  1838. )
  1839. self.is_stop_action = False
  1840. self.action_state = 2
  1841. self.is_runn_action = False
  1842. self.msg_type = "photo_take_finish"
  1843. self.sendSocketMessage(
  1844. code=0,
  1845. msg=f"货号:{goods_art_no},执行完成",
  1846. device_status=2,
  1847. )
  1848. self.msg_type = "mcu"
  1849. await self.controlDevice("laser_position", 1)
  1850. self.action_state = 2
  1851. # await smart_shooter.EnableCameraPreview(
  1852. # enable_status=False, msg_type="smart_shooter_enable_preview"
  1853. # )
  1854. async def run_mcu_config_single(
  1855. self,
  1856. config_info,
  1857. goods_art_no,
  1858. msg_type="run_mcu_single_finish",
  1859. image_index=-1,
  1860. smart_shooter=None,
  1861. action_id=-1,
  1862. ):
  1863. """独立拍照 仅作测试用"""
  1864. await asyncio.sleep(0.01)
  1865. if self.checkDevice() == False:
  1866. return
  1867. print("检查完成", config_info)
  1868. logger.info("检查完成 %s", config_info)
  1869. if config_info:
  1870. self.action_state = 1
  1871. self.msg_type = "mcu"
  1872. program_item = ProgramItem(
  1873. websocket_manager=self.websocket_manager,
  1874. action_data=config_info,
  1875. mcu=self,
  1876. goods_art_no=goods_art_no,
  1877. image_index=image_index,
  1878. smart_shooter=smart_shooter,
  1879. record_id=action_id,
  1880. is_get_mcu_state=False,
  1881. )
  1882. program_item.last_move_time = self.last_move_time
  1883. if self.action_state != 1:
  1884. # 异常终止
  1885. print("action异常终止")
  1886. logger.info("action异常终止")
  1887. return
  1888. program_item.smart_shooter = smart_shooter
  1889. await program_item.run(3)
  1890. self.msg_type = "mcu"
  1891. logger.info(
  1892. "发送 run_mcu_signle消息,{} 执行完成~".format(program_item.action_name)
  1893. )
  1894. self.sendSocketMessage(
  1895. code=0,
  1896. msg="{} 执行完成~".format(program_item.action_name),
  1897. data={"goods_art_no": goods_art_no, "id": action_id},
  1898. device_status=2,
  1899. )
  1900. self.action_state = 2
  1901. self.msg_type = "run_mcu_single"
  1902. logger.info("发送 run_mcu_signle消息执行完成")
  1903. self.sendSocketMessage(
  1904. code=0,
  1905. msg=f"执行完成",
  1906. device_status=2,
  1907. )
  1908. self.msg_type = "mcu"
  1909. else:
  1910. self.sendSocketMessage(
  1911. code=1, msg="未查询到重拍记录得配置信息,请确认", device_status=0
  1912. )
  1913. self.action_state = 2
  1914. async def only_take_photo(self, goods_art_no, image_index, record_id):
  1915. await asyncio.sleep(0.1)
  1916. print("only_take_photo=====>", goods_art_no, image_index, record_id)
  1917. logger.info(
  1918. f"only_take_photo=====> {goods_art_no} {image_index} {record_id}"
  1919. )
  1920. if goods_art_no == "":
  1921. print("only_take_photo 数据查询异常")
  1922. logger.info("only_take_photo 数据查询异常")
  1923. return
  1924. # 关闭led
  1925. self.controlDevice("laser_position", 0)
  1926. program_item = ProgramItem(
  1927. websocket_manager=self.websocket_manager,
  1928. action_data={},
  1929. mcu=self,
  1930. goods_art_no=goods_art_no,
  1931. image_index=image_index,
  1932. record_id=record_id,
  1933. )
  1934. program_item.digicam_take_picture()
  1935. # 打开led
  1936. self.controlDevice("laser_position", 1)
  1937. async def checkMcuConnection(device_ctrl: DeviceControl):
  1938. if device_ctrl.is_running == True:
  1939. message = {
  1940. "_type": "select_port_name",
  1941. "plugins_mode": "auto_select_com",
  1942. "data": device_ctrl.temp_ports_dict,
  1943. }
  1944. device_ctrl.device_status = 2
  1945. device_ctrl.sendSocketMessage(code=0, msg="MCU连接成功", data=message)
  1946. return
  1947. if device_ctrl.is_init_while == True:
  1948. logger.info("mcu 初始化循环已创建,请勿重复创建")
  1949. device_ctrl.sendSocketMessage(
  1950. code=0, msg="mcu 初始化循环已创建,请勿重复创建", data={}
  1951. )
  1952. return
  1953. device_ctrl.is_init_while = True
  1954. """实时检测串口是否连接"""
  1955. while True:
  1956. await asyncio.sleep(1)
  1957. if device_ctrl.mcu_exit:
  1958. break
  1959. ports_dict = device_ctrl.scan_serial_port()
  1960. device_ctrl.temp_ports_dict = ports_dict
  1961. # print("device_ctrl.p_list", device_ctrl.p_list)
  1962. # logger.info("device_ctrl.p_list %s", device_ctrl.p_list)
  1963. if not ports_dict:
  1964. # 全部清空 移除所有串口
  1965. if device_ctrl.p_list:
  1966. _p = device_ctrl.p_list.pop()
  1967. device_ctrl.remove_port(_p)
  1968. continue
  1969. if ports_dict:
  1970. for index, _i in enumerate(device_ctrl.p_list):
  1971. if _i not in ports_dict:
  1972. _p = device_ctrl.p_list.pop(index)
  1973. device_ctrl.remove_port(_p)
  1974. for _port_name, _port_value in ports_dict.items():
  1975. if _port_name not in device_ctrl.p_list:
  1976. try:
  1977. flag = await device_ctrl.add_port_by_linkage(_port_name)
  1978. if not flag:
  1979. continue
  1980. device_ctrl.p_list.append(_port_name)
  1981. except BaseException as e:
  1982. print("串口不存在{} {}".format(_port_name, e))
  1983. logger.info("串口不存在{} {}".format(_port_name, e))
  1984. device_ctrl.is_init_while = False
  1985. print("MCU断开连接,已释放")
  1986. logger.info("MCU断开连接,已释放")