DeviceControl.py 87 KB

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