smart_shooter_class.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. import json
  2. import datetime
  3. import random
  4. import zmq
  5. import asyncio
  6. from PIL import Image
  7. from io import BytesIO
  8. import base64, threading
  9. import zmq, sys, time
  10. from utils.SingletonType import SingletonType
  11. import settings
  12. import logging
  13. from databases import SqlQuery, CRUD, SysConfigs
  14. from utils.common import message_queue
  15. from models import SysConfigParams
  16. logger = logging.getLogger(__name__)
  17. # 定义为单例模式,避免被重复实例化
  18. class SmartShooter(metaclass=SingletonType):
  19. SET_REQ = "tcp://127.0.0.1:54544"
  20. LISTEN_REQ = "tcp://127.0.0.1:54543"
  21. def __init__(self, websocket_manager):
  22. self.msg_type = "smart_shooter"
  23. self.websocket_manager = websocket_manager
  24. # 是否停止监听
  25. self.stop_listen = False
  26. # 相机连接状态
  27. self.connect_status = False
  28. # 实时预览状态
  29. self.perview_state = False
  30. self.callback_listen = None
  31. self.listen_init = None
  32. self.websocket = None
  33. # self.main_loop = None
  34. def __send_tcp_message(self, socket, msg):
  35. # await asyncio.sleep(0.01)
  36. socket.send_string(json.dumps(msg))
  37. rep = socket.recv()
  38. str_msg = rep.decode("utf-8")
  39. json_msg = json.loads(str_msg)
  40. return json_msg
  41. def __create_req(self, time_out=5) -> tuple[zmq.Socket, zmq.Context]:
  42. context = zmq.Context()
  43. req_socket = context.socket(zmq.REQ)
  44. # 设置发送超时为 5000 毫秒(5 秒)
  45. req_socket.setsockopt(zmq.RCVTIMEO, time_out * 1000)
  46. # 设置接收超时为 5000 毫秒(5 秒)
  47. req_socket.setsockopt(zmq.SNDTIMEO, time_out * 1000)
  48. req_socket.setsockopt(zmq.LINGER, 0) # 设置为 0 表示不等待未完成的操作
  49. req_socket.connect(self.SET_REQ)
  50. return req_socket, context
  51. async def sendMessageSocket(self, message):
  52. if self.websocket_manager and self.websocket:
  53. await self.websocket_manager.send_personal_message(message, self.websocket)
  54. def __create_listen(self) -> tuple[zmq.Socket, zmq.Context]:
  55. context = zmq.Context()
  56. listen_socket = context.socket(zmq.SUB)
  57. listen_socket.setsockopt(zmq.SUBSCRIBE, b"")
  58. # 设置发送超时为 5000 毫秒(5 秒)
  59. listen_socket.setsockopt(zmq.RCVTIMEO, 5000)
  60. # 设置接收超时为 5000 毫秒(5 秒)
  61. listen_socket.setsockopt(zmq.SNDTIMEO, 5000)
  62. listen_socket.setsockopt(zmq.LINGER, 0) # 设置为 0 表示不等待未完成的操作
  63. listen_socket.connect(self.LISTEN_REQ)
  64. return listen_socket, context
  65. async def GetCameraProperty(self, CameraKey=None):
  66. """获取相机属性"""
  67. await asyncio.sleep(0.01)
  68. """
  69. 实时获取相机信息,是否连接、软件是否被打开
  70. """
  71. socket, context = self.__create_req(time_out=2)
  72. try:
  73. req = {}
  74. req["msg_type"] = "Request"
  75. req["msg_id"] = "GetCamera"
  76. req["msg_seq_num"] = 0
  77. req["CameraSelection"] = "All"
  78. if CameraKey is not None:
  79. req["CameraSelection"] = "Single"
  80. req["CameraKey"] = CameraKey
  81. json_msg = self.__send_tcp_message(socket, req)
  82. msg_result = json_msg.get("msg_result")
  83. if not msg_result:
  84. self.connect_status = False
  85. msg_send = "相机未连接或软件未打开"
  86. return False, msg_send
  87. cameraInfo = json_msg.get("CameraInfo")
  88. if cameraInfo == None or len(cameraInfo) == 0:
  89. self.connect_status = False
  90. msg_send = "相机未连接"
  91. return False, "相机未连接"
  92. # 链接的相机
  93. CameraStatus = False
  94. CameraIndex = -1
  95. for cam_idx, item in enumerate(cameraInfo):
  96. CameraStatus = item.get("CameraStatus") in ["Ready", "Busy"]
  97. if CameraStatus == True:
  98. CameraIndex = cam_idx
  99. break
  100. # CameraStatus = connect_camera.get("CameraStatus")
  101. if not CameraStatus:
  102. self.connect_status = False
  103. msg_send = "相机未连接"
  104. return False, msg_send
  105. self.connect_status = True
  106. msg_send = "相机已连接"
  107. return True, cameraInfo[CameraIndex].get("CameraPropertyInfo")
  108. except zmq.Again:
  109. msg_send = "相机未连接或软件未打开"
  110. return False, msg_send
  111. except Exception as e:
  112. self.connect_status = False
  113. socket.close()
  114. context.term()
  115. msg_send = "相机未连接或软件未打开"
  116. return False, msg_send
  117. def get_iso_range(self, camera_info):
  118. """
  119. 从相机数据中获取 ISO 的可调范围
  120. :param camera_data: 相机状态数据列表 (即你提供的那个长列表)
  121. :return: ISO 范围列表,如果未找到则返回 None
  122. """
  123. # 获取属性信息列表
  124. property_info_list = camera_info.get('CameraPropertyInfo', [])
  125. for prop in property_info_list:
  126. # 查找 CameraPropertyType 等于 'ISO' 的项
  127. if prop.get('CameraPropertyType') == 'ISO':
  128. return prop.get('CameraPropertyRange')
  129. return None
  130. async def GetCameraInfo(self, is_send=True, msg_type="", CameraKey=None):
  131. await asyncio.sleep(0.001)
  132. # self.msg_type = msg_type
  133. """
  134. 实时获取相机信息,是否连接、软件是否被打开
  135. """
  136. socket, context = self.__create_req(time_out=5)
  137. try:
  138. req = {}
  139. req["msg_type"] = "Request"
  140. req["msg_id"] = "GetCamera"
  141. req["msg_seq_num"] = 0
  142. req["CameraSelection"] = "All"
  143. if CameraKey is not None:
  144. req["CameraSelection"] = "Single"
  145. req["CameraKey"] = CameraKey
  146. json_msg = self.__send_tcp_message(socket, req)
  147. msg_result = json_msg.get("msg_result")
  148. if not msg_result:
  149. self.connect_status = False
  150. msg_send = f"请检查{CameraKey},相机是否连接" if CameraKey else f"请检查相机是否连接"
  151. if is_send:
  152. message = {
  153. "code": 1,
  154. "msg": msg_send,
  155. "data": msg_result,
  156. "CameraKey": CameraKey,
  157. "msg_type": msg_type,
  158. "device_status": -1,
  159. }
  160. await self.sendMessageSocket(message)
  161. return False, msg_send
  162. cameraInfo = json_msg.get("CameraInfo")
  163. print("相机状态msg_result", cameraInfo)
  164. if cameraInfo == None or len(cameraInfo) == 0:
  165. self.connect_status = False
  166. msg_send = (
  167. f"请检查{CameraKey},相机是否连接"
  168. if CameraKey
  169. else f"请检查相机是否连接"
  170. )
  171. if is_send:
  172. message = {
  173. "code": 1,
  174. "msg": msg_send,
  175. "data": msg_result,
  176. "msg_type": msg_type,
  177. "device_status": -1,
  178. }
  179. await self.sendMessageSocket(message)
  180. return False, "相机未连接"
  181. # 链接的相机
  182. CameraStatus = any(
  183. item.get("CameraStatus") in ["Ready", "Busy"] for item in cameraInfo
  184. )
  185. # 在这里处理
  186. CameraLists = [
  187. {
  188. "CameraSelection": item.get("CameraSelection"),
  189. "CameraKey": item.get("CameraKey"),
  190. "CameraName": item.get("CameraName"),
  191. "CameraStatus": item.get("CameraStatus") in ["Ready", "Busy"],
  192. "CameraISO": self.get_iso_range(item),
  193. }
  194. for item in cameraInfo
  195. ]
  196. if not CameraStatus:
  197. self.connect_status = False
  198. msg_send = (
  199. f"请检查{CameraKey},相机是否连接"
  200. if CameraKey
  201. else f"请检查相机是否连接"
  202. )
  203. if is_send:
  204. message = {
  205. "code": 1,
  206. "msg": msg_send,
  207. "data": msg_result,
  208. "CameraKey": CameraKey,
  209. "msg_type": msg_type,
  210. "device_status": -1,
  211. }
  212. await self.sendMessageSocket(message)
  213. return False, msg_send
  214. self.connect_status = True
  215. msg_send = f"相机{CameraKey}已连接" if CameraKey else "相机已连接"
  216. # print("CameraLists", CameraLists)
  217. if is_send:
  218. message = {
  219. "code": 0,
  220. "msg": msg_send,
  221. "data": msg_result,
  222. "CameraLists": CameraLists,
  223. "msg_type": msg_type,
  224. "device_status": 2,
  225. }
  226. await self.sendMessageSocket(message)
  227. # print("相机已连接状态信息---->", cameraInfo)
  228. self.initConfigIsoSettings(
  229. CameraLists=CameraLists, isMultCameraMode=settings.USER_CAMERAS
  230. )
  231. return True, "相机已连接"
  232. except zmq.Again as e:
  233. self.connect_status = False
  234. socket.close()
  235. context.term()
  236. print("获取相机信息超时,继续监听...", e)
  237. msg_send = f"请检查{CameraKey},相机是否连接" if CameraKey else f"请检查相机是否连接"
  238. return False, msg_send
  239. except Exception as e:
  240. print("相机状态获取异常", e)
  241. self.connect_status = False
  242. socket.close()
  243. context.term()
  244. msg_send = (
  245. f"请检查{CameraKey},相机是否连接"
  246. if CameraKey
  247. else f"请检查相机是否连接"
  248. )
  249. if is_send:
  250. message = {
  251. "code": 1,
  252. "msg": msg_send,
  253. "data": None,
  254. "msg_type": msg_type,
  255. "device_status": -1,
  256. }
  257. await self.sendMessageSocket(message)
  258. return False, msg_send
  259. async def SetCameraFPS(self, fps=5, CameraKey=None):
  260. """
  261. 激活相机预览
  262. """
  263. camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
  264. if not camera_states:
  265. return False, "请先连接相机"
  266. socket, context = self.__create_req()
  267. try:
  268. req = {}
  269. req["msg_type"] = "Request"
  270. req["msg_id"] = "LiveviewFPS"
  271. req["msg_seq_num"] = 0
  272. req["CameraSelection"] = "All"
  273. if CameraKey is not None:
  274. req["CameraSelection"] = "Single"
  275. req["CameraKey"] = CameraKey
  276. req["CameraLiveviewFPS"] = fps
  277. json_msg = self.__send_tcp_message(socket, req)
  278. msg_result = json_msg.get("msg_result")
  279. if not msg_result:
  280. self.perview_state = False
  281. return False, "设置失败"
  282. return True, "设置失败"
  283. except:
  284. self.perview_state = False
  285. socket.close()
  286. context.term()
  287. return False, "相机未连接或软件未打开"
  288. async def setCameraProperty(self, property="ISO", value=0, CameraKey=None):
  289. # SetProperty
  290. camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
  291. if not camera_states:
  292. return False, "请先连接相机"
  293. socket, context = self.__create_req()
  294. try:
  295. req = {}
  296. req["msg_type"] = "Request"
  297. req["msg_id"] = "SetProperty"
  298. req["msg_seq_num"] = 0
  299. req["CameraSelection"] = "All"
  300. if CameraKey is not None:
  301. req["CameraSelection"] = "Single"
  302. req["CameraKey"] = CameraKey
  303. req["CameraPropertyType"] = str(property)
  304. req["CameraPropertyValue"] = str(value)
  305. print("发送设置属性请求", req)
  306. json_msg = self.__send_tcp_message(socket, req)
  307. msg_result = json_msg.get("msg_result")
  308. if not msg_result:
  309. return False, f"{property}设置失败"
  310. return True, f"{property}设置成功"
  311. except zmq.Again:
  312. print(f"设置{property}超时,继续监听...")
  313. except:
  314. self.perview_state = False
  315. socket.close()
  316. context.term()
  317. msg_send = "相机未连接或软件未打开"
  318. return False, msg_send
  319. async def setCameraProperties(self, properties: dict, CameraKey=None):
  320. """
  321. 批量设置相机参数(复用同一个 socket,连续发送多条 SetProperty 消息)
  322. :param properties: 参数字典,如 {"ISO": "200", "Aperture": "8", "ShutterSpeed": "1/60"}
  323. :return: (是否全部成功, {参数名: 是否成功})
  324. """
  325. if not properties:
  326. return False, {}
  327. camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
  328. if not camera_states:
  329. return False, "请先连接相机"
  330. socket, context = self.__create_req()
  331. results = {}
  332. try:
  333. for prop, value in properties.items():
  334. req = {}
  335. req["msg_type"] = "Request"
  336. req["msg_id"] = "SetProperty"
  337. req["msg_seq_num"] = 0
  338. req["CameraSelection"] = "All"
  339. if CameraKey is not None:
  340. req["CameraSelection"] = "Single"
  341. req["CameraKey"] = CameraKey
  342. req["CameraPropertyType"] = str(prop)
  343. req["CameraPropertyValue"] = str(value)
  344. print("发送设置属性请求", req)
  345. json_msg = self.__send_tcp_message(socket, req)
  346. results[prop] = json_msg.get("msg_result")
  347. all_ok = all(results.values())
  348. return all_ok, results
  349. except zmq.Again:
  350. print(f"批量设置属性超时,继续监听...", results)
  351. return all(results.values()) if results else False, results
  352. except Exception as e:
  353. print(f"批量设置属性异常", e)
  354. return False, results
  355. finally:
  356. socket.close()
  357. context.term()
  358. def getConfigIso(self, CameraKey=None):
  359. """获取ISO配置信息"""
  360. camera_configs = settings.getSysConfigs(
  361. "camera_configs",
  362. "iso_config",
  363. None,
  364. )
  365. Itemiso = {}
  366. for idx, item in enumerate(camera_configs):
  367. itemConfig = camera_configs[item]
  368. if itemConfig == {}:
  369. continue
  370. ItemCameraKey = itemConfig.get("CameraKey")
  371. if ItemCameraKey == CameraKey:
  372. Itemiso = itemConfig.get("iso")
  373. break
  374. low_iso = Itemiso.get("low", 100)
  375. high_iso = Itemiso.get("high", 6400)
  376. return low_iso, high_iso
  377. def initConfigIsoSettings(self, CameraLists=[], isMultCameraMode=False):
  378. if not CameraLists:
  379. return None
  380. """获取ISO配置信息"""
  381. camera_configs = settings.getSysConfigs(
  382. "camera_configs",
  383. "iso_config",
  384. None,
  385. )
  386. temp_A_point = camera_configs.get("A", None)
  387. if temp_A_point is not None:
  388. print("已配置无需更新")
  389. itemSettings = CameraLists[0]
  390. OldCameraKey = temp_A_point.get("CameraKey", None)
  391. if OldCameraKey == itemSettings.get("CameraKey", None):
  392. print("相机无变动。无需自动更改配置")
  393. return None
  394. basic_iso = temp_A_point.get("iso", {"low": 100, "high": 6400})
  395. print("isMultCameraMode======>>>>", isMultCameraMode)
  396. if not isMultCameraMode:
  397. points = {"A": {}}
  398. print("相机发生变动。需要更改配置")
  399. # 如果客户是单相机版本用户,需要每次同步camera信息
  400. points["A"] = {
  401. **itemSettings,
  402. "iso": basic_iso,
  403. }
  404. sys_iso_config = {"key": "camera_configs", "value": {"iso_config": points}}
  405. sys_iso_config: SysConfigParams
  406. print("单相机用户同步相机配置", sys_iso_config)
  407. settings.updateSysConfigs(params=sys_iso_config)
  408. # 同步本地到线上
  409. settings.sync_sys_configs2Online()
  410. return None
  411. points = {"A": {}, "B": {}, "C": {}}
  412. for idx, item in enumerate(points):
  413. low_iso = camera_configs.get("low", 100)
  414. high_iso = camera_configs.get("high", 6400)
  415. if idx > len(CameraLists) - 1:
  416. points[item] = {
  417. "iso": {"low": low_iso, "high": high_iso},
  418. }
  419. continue
  420. itemSettings = CameraLists[idx]
  421. points[item] = {**itemSettings, "iso": {"low": low_iso, "high": high_iso}}
  422. sys_iso_config = {"key": "camera_configs", "value": {"iso_config": points}}
  423. sys_iso_config: SysConfigParams
  424. print("首次初始化", sys_iso_config)
  425. settings.updateSysConfigs(params=sys_iso_config)
  426. # 同步本地到线上
  427. settings.sync_sys_configs2Online()
  428. async def EnableCameraPreview(
  429. self, enable_status=True, msg_type="", CameraKey=None, isMultCameraMode=False
  430. ):
  431. print("收到得msg_type====>>>", msg_type)
  432. self.msg_type = msg_type
  433. await self.SetCameraFPS(5, CameraKey=CameraKey)
  434. """
  435. 激活相机预览
  436. """
  437. camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
  438. if not camera_states:
  439. msg_send = "预览启用失败"
  440. message = {
  441. "code": 0,
  442. "msg": msg_send,
  443. "data": None,
  444. "msg_type": msg_type,
  445. "device_status": -1,
  446. }
  447. logger.error(message)
  448. await self.sendMessageSocket(message)
  449. return False, "请先连接相机"
  450. try:
  451. low_iso, high_iso = self.getConfigIso(CameraKey=CameraKey)
  452. print("LOW_ISO", low_iso)
  453. print("HIGH_ISO", high_iso)
  454. # 等于auto就不设置
  455. if enable_status == True:
  456. if str(high_iso).lower() != "auto":
  457. set_state, set_msg = await self.setCameraProperty(
  458. property="ISO", value=str(high_iso), CameraKey=CameraKey
  459. )
  460. else:
  461. print("high_iso 等于auto就不设置")
  462. if enable_status == False:
  463. if str(low_iso).lower() != "auto":
  464. set_state, set_msg = await self.setCameraProperty(
  465. property="ISO", value=str(low_iso), CameraKey=CameraKey
  466. )
  467. else:
  468. print("low_iso 等于auto就不设置")
  469. # print("设置状态", set_state, set_msg)
  470. socket, context = self.__create_req()
  471. req = {}
  472. req["msg_type"] = "Request"
  473. req["msg_id"] = "EnableLiveview"
  474. req["msg_seq_num"] = 0
  475. req["CameraSelection"] = "All"
  476. if CameraKey is not None:
  477. req["CameraSelection"] = "Single"
  478. req["CameraKey"] = CameraKey
  479. req["Enable"] = enable_status
  480. json_msg = self.__send_tcp_message(socket, req)
  481. msg_result = json_msg.get("msg_result")
  482. if not msg_result:
  483. self.perview_state = False
  484. msg_send = "预览启用失败"
  485. message = {
  486. "code": 0,
  487. "msg": msg_send,
  488. "data": None,
  489. "msg_type": msg_type,
  490. "device_status": -1,
  491. }
  492. logger.error(message)
  493. await self.sendMessageSocket(message)
  494. return False, "预览启用失败"
  495. msg_send = "预览启用成功" if enable_status else "预览关闭成功"
  496. message = {
  497. "code": 0,
  498. "msg": msg_send,
  499. "data": None,
  500. "msg_type": msg_type,
  501. "device_status": 2,
  502. }
  503. logger.error(message)
  504. await self.sendMessageSocket(message)
  505. return True, "预览启用成功" if enable_status else "预览关闭成功"
  506. except zmq.Again:
  507. print("启动预览超时,继续监听...")
  508. except:
  509. self.perview_state = False
  510. socket.close()
  511. context.term()
  512. msg_send = "相机未连接或软件未打开"
  513. message = {
  514. "code": 1,
  515. "msg": msg_send,
  516. "data": None,
  517. "msg_type": msg_type,
  518. "device_status": -1,
  519. }
  520. logger.error(message)
  521. await self.sendMessageSocket(message)
  522. return False, "相机未连接或软件未打开"
  523. async def CameraAutofocus(self, CameraKey=None):
  524. """
  525. 相机自动对焦
  526. """
  527. camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
  528. print("CameraAutofocus 执行对焦")
  529. if not camera_states:
  530. return False, "请先连接相机"
  531. socket, context = self.__create_req()
  532. try:
  533. req = {}
  534. req["msg_type"] = "Request"
  535. req["msg_id"] = "Autofocus"
  536. req["msg_seq_num"] = 0
  537. req["CameraSelection"] = "All"
  538. if CameraKey is not None:
  539. req["CameraSelection"] = "Single"
  540. req["CameraKey"] = CameraKey
  541. start_time = time.time() # 添加对焦开始时间记录
  542. json_msg = self.__send_tcp_message(socket, req)
  543. end_time = time.time() # 添加对焦结束时间记录
  544. logger.info(f"对焦通信耗时: {end_time - start_time:.4f} 秒")
  545. print("json_msg", json_msg)
  546. msg_result = json_msg.get("msg_result")
  547. if not msg_result:
  548. return False, "对焦失败"
  549. return True, "对焦成功"
  550. except zmq.Again:
  551. print("对焦超时,继续监听...")
  552. except:
  553. socket.close()
  554. context.term()
  555. return False, "相机未连接或软件未打开"
  556. async def CameraShooter(
  557. self, msg_type="", goods_art_no="", id=0, is_af=False, delay=0.5, CameraKey=None,
  558. camera_configs=None
  559. ):
  560. # 这里延迟一秒钟 等待前置命令完成
  561. await asyncio.sleep(delay)
  562. # 对焦混用
  563. if is_af:
  564. # await self.EnableCameraPreview(
  565. # enable_status=True,
  566. # msg_type="smart_shooter_enable_preview_status",
  567. # CameraKey=CameraKey,
  568. # )
  569. # start_time = time.time()
  570. await self.CameraAutofocus(CameraKey=CameraKey)
  571. # end_time = time.time()
  572. # elapsed_time = end_time - start_time
  573. # logger.info(f"自动对焦耗时 {elapsed_time:.4f} 秒")
  574. # await self.EnableCameraPreview(
  575. # enable_status=False, msg_type="smart_shooter_enable_preview_status", CameraKey=CameraKey
  576. # )
  577. self.msg_type = msg_type
  578. print("camera_states", msg_type)
  579. """
  580. 执行拍照
  581. """
  582. camera_states, _ = await self.GetCameraInfo(is_send=True, CameraKey=CameraKey)
  583. print("camera_states CameraShooter", camera_states)
  584. if not camera_states:
  585. return False, "请先连接相机"
  586. socket, context = self.__create_req()
  587. try:
  588. if camera_configs is None:
  589. low_iso, high_iso = self.getConfigIso(CameraKey=CameraKey)
  590. print("LOW_ISO", low_iso)
  591. print("HIGH_ISO", high_iso)
  592. if str(low_iso).lower() != "auto":
  593. await self.setCameraProperty(
  594. property="ISO", value=str(low_iso), CameraKey=CameraKey
  595. )
  596. else:
  597. print("low_iso 等于auto就不设置")
  598. else:
  599. await self.setCameraProperties(camera_configs, CameraKey=CameraKey)
  600. req = {}
  601. req["msg_type"] = "Request"
  602. req["msg_id"] = "Shoot"
  603. req["msg_seq_num"] = 1
  604. req["CameraSelection"] = "All"
  605. if CameraKey is not None:
  606. req["CameraSelection"] = "Single"
  607. req["CameraKey"] = CameraKey
  608. if goods_art_no != "" and id != 0:
  609. # 此处用逗号分割,货号和id,需要在监听部分进行切割保存处理,如果使用下划线或者减号,可能货号中存在对应符号
  610. req["PhotoOrigin"] = f"{goods_art_no},{id}"
  611. else:
  612. req["PhotoOrigin"] = ""
  613. print("发送拍照请求", req)
  614. json_msg = self.__send_tcp_message(socket, req)
  615. print("CameraShooter", json_msg)
  616. msg_result = json_msg.get("msg_result")
  617. if not msg_result:
  618. msg_send = "拍照失败"
  619. message = {
  620. "code": 1,
  621. "msg": msg_send,
  622. "data": None,
  623. "msg_type": msg_type,
  624. "device_status": -1,
  625. }
  626. await self.sendMessageSocket(message)
  627. return False, msg_send
  628. msg_send = "拍照成功"
  629. message = {
  630. "code": 0,
  631. "msg": msg_send,
  632. "data": None,
  633. "msg_type": msg_type,
  634. "device_status": 2,
  635. }
  636. await self.sendMessageSocket(message)
  637. return True, "拍照成功"
  638. except zmq.Again:
  639. print("拍照超时")
  640. # msg_send = "拍照失败"
  641. # message = {
  642. # "code": 1,
  643. # "msg": msg_send,
  644. # "data": {goods_art_no: goods_art_no, "id": id},
  645. # "msg_type": msg_type,
  646. # "device_status": -1,
  647. # }
  648. # await self.sendMessageSocket(message)
  649. return True, "拍照失败"
  650. except Exception as e:
  651. print("拍照出错", e)
  652. socket.close()
  653. context.term()
  654. msg_send = "拍照失败"
  655. message = {
  656. "code": 1,
  657. "msg": msg_send,
  658. "data": None,
  659. "msg_type": msg_type,
  660. "device_status": -1,
  661. }
  662. await self.sendMessageSocket(message)
  663. return False, msg_send
  664. async def asyncMessageListen(self):
  665. if self.websocket.client_state.name != "CONNECTED":
  666. print("WebSocket连接已断开,停止发送消息")
  667. return
  668. try:
  669. # 使用非阻塞方式检查队列中是否有项目
  670. if not message_queue.empty():
  671. message = message_queue.get_nowait()
  672. print("发送消息中。。。。。", message)
  673. await self.sendMessageSocket(message)
  674. message_queue.task_done()
  675. except Exception as e:
  676. # 处理可能的异常,如队列为空等
  677. pass
  678. def connect_listen(self):
  679. print("smart shooter connect_listen START")
  680. if self.connect_status == True or self.listen_init == True:
  681. return True
  682. sub_socket, context = self.__create_listen()
  683. print("构建监听", self.connect_status)
  684. # 不再需要 self.listen_loop,我们只使用主循环
  685. try:
  686. while True:
  687. self.listen_init = True
  688. if self.stop_listen:
  689. break
  690. # 1. 阻塞接收 ZMQ 消息 (这是唯一的阻塞点,但在子线程,所以没问题)
  691. try:
  692. raw = sub_socket.recv() # 这里会阻塞直到有消息或超时
  693. str_msg = raw.decode("utf-8")
  694. json_msg = json.loads(str_msg)
  695. if json_msg.get("msg_id") == "NetworkPing":
  696. continue
  697. # 2. 将回调提交到【主事件循环】
  698. if hasattr(self, "main_loop") and self.main_loop:
  699. # 非阻塞提交,立即返回
  700. asyncio.run_coroutine_threadsafe(
  701. self.callback_listen(json_msg), self.main_loop
  702. )
  703. else:
  704. print("Error: main_loop not set in SmartShooter")
  705. except zmq.Again:
  706. # 超时,继续循环
  707. continue
  708. except Exception as e:
  709. print(f"ZMQ Error: {e}")
  710. break
  711. finally:
  712. self.listen_init = False
  713. self.connect_status = False
  714. sub_socket.close()
  715. context.term()
  716. print("smart shooter连接断开")