DeviceControl.py 83 KB

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