smart_shooter_class.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  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
  9. import zmq, sys, time
  10. from utils.SingletonType import SingletonType
  11. import settings
  12. import logging
  13. logger = logging.getLogger(__name__)
  14. # 定义为单例模式,避免被重复实例化
  15. class SmartShooter(metaclass=SingletonType):
  16. SET_REQ = "tcp://127.0.0.1:54544"
  17. LISTEN_REQ = "tcp://127.0.0.1:54543"
  18. def __init__(self, websocket_manager):
  19. self.msg_type = "smart_shooter"
  20. self.websocket_manager = websocket_manager
  21. # 是否停止监听
  22. self.stop_listen = False
  23. # 相机连接状态
  24. self.connect_status = False
  25. # 实时预览状态
  26. self.perview_state = False
  27. self.callback_listen = None
  28. self.listen_init = None
  29. self.websocket = None
  30. def __send_tcp_message(self, socket, msg):
  31. # await asyncio.sleep(0.01)
  32. socket.send_string(json.dumps(msg))
  33. rep = socket.recv()
  34. str_msg = rep.decode("utf-8")
  35. json_msg = json.loads(str_msg)
  36. return json_msg
  37. def __create_req(self, time_out=5) -> tuple[zmq.Socket, zmq.Context]:
  38. context = zmq.Context()
  39. req_socket = context.socket(zmq.REQ)
  40. # 设置发送超时为 5000 毫秒(5 秒)
  41. req_socket.setsockopt(zmq.RCVTIMEO, time_out * 1000)
  42. # 设置接收超时为 5000 毫秒(5 秒)
  43. req_socket.setsockopt(zmq.SNDTIMEO, time_out * 1000)
  44. req_socket.setsockopt(zmq.LINGER, 0) # 设置为 0 表示不等待未完成的操作
  45. req_socket.connect(self.SET_REQ)
  46. return req_socket, context
  47. def __create_listen(self) -> tuple[zmq.Socket, zmq.Context]:
  48. context = zmq.Context()
  49. listen_socket = context.socket(zmq.SUB)
  50. listen_socket.setsockopt(zmq.SUBSCRIBE, b"")
  51. # 设置发送超时为 5000 毫秒(5 秒)
  52. listen_socket.setsockopt(zmq.RCVTIMEO, 4000)
  53. # 设置接收超时为 5000 毫秒(5 秒)
  54. listen_socket.setsockopt(zmq.SNDTIMEO, 4000)
  55. listen_socket.setsockopt(zmq.LINGER, 0) # 设置为 0 表示不等待未完成的操作
  56. listen_socket.connect(self.LISTEN_REQ)
  57. return listen_socket, context
  58. async def GetCameraProperty(self):
  59. '''获取相机属性'''
  60. await asyncio.sleep(0.01)
  61. """
  62. 实时获取相机信息,是否连接、软件是否被打开
  63. """
  64. socket, context = self.__create_req(time_out=2)
  65. try:
  66. req = {}
  67. req["msg_type"] = "Request"
  68. req["msg_id"] = "GetCamera"
  69. req["msg_seq_num"] = 0
  70. req["CameraSelection"] = "All"
  71. json_msg = self.__send_tcp_message(socket, req)
  72. msg_result = json_msg.get("msg_result")
  73. if not msg_result:
  74. self.connect_status = False
  75. msg_send = "相机未连接或软件未打开"
  76. return False, msg_send
  77. cameraInfo = json_msg.get("CameraInfo")
  78. if cameraInfo == None or len(cameraInfo) == 0:
  79. self.connect_status = False
  80. msg_send = "相机未连接"
  81. return False, "相机未连接"
  82. # 链接的相机
  83. CameraStatus = False
  84. CameraIndex =-1
  85. for cam_idx,item in enumerate(cameraInfo):
  86. CameraStatus = item.get("CameraStatus") in ["Ready", "Busy"]
  87. if CameraStatus == True:
  88. CameraIndex = cam_idx
  89. break
  90. # CameraStatus = connect_camera.get("CameraStatus")
  91. if not CameraStatus:
  92. self.connect_status = False
  93. msg_send = "相机未连接"
  94. return False, msg_send
  95. self.connect_status = True
  96. msg_send = "相机已连接"
  97. return True, cameraInfo[CameraIndex].get("CameraPropertyInfo")
  98. except zmq.Again:
  99. msg_send = "相机未连接或软件未打开"
  100. return False, msg_send
  101. except Exception as e:
  102. self.connect_status = False
  103. socket.close()
  104. context.term()
  105. msg_send = "相机未连接或软件未打开"
  106. return False, msg_send
  107. async def GetCameraInfo(self, is_send=True, msg_type=""):
  108. await asyncio.sleep(0.01)
  109. self.msg_type = msg_type
  110. """
  111. 实时获取相机信息,是否连接、软件是否被打开
  112. """
  113. socket, context = self.__create_req(time_out=2)
  114. try:
  115. req = {}
  116. req["msg_type"] = "Request"
  117. req["msg_id"] = "GetCamera"
  118. req["msg_seq_num"] = 0
  119. req["CameraSelection"] = "All"
  120. json_msg = self.__send_tcp_message(socket, req)
  121. msg_result = json_msg.get("msg_result")
  122. if not msg_result:
  123. self.connect_status = False
  124. msg_send = "相机未连接或软件未打开"
  125. if is_send:
  126. message = {
  127. "code": 1,
  128. "msg": msg_send,
  129. "data": msg_result,
  130. "msg_type": self.msg_type,
  131. "device_status": -1,
  132. }
  133. await self.websocket_manager.send_personal_message(
  134. message, self.websocket
  135. )
  136. return False, msg_send
  137. cameraInfo = json_msg.get("CameraInfo")
  138. if cameraInfo == None or len(cameraInfo) == 0:
  139. self.connect_status = False
  140. msg_send = "相机未连接"
  141. if is_send:
  142. message = {
  143. "code": 1,
  144. "msg": msg_send,
  145. "data": msg_result,
  146. "msg_type": self.msg_type,
  147. "device_status": -1,
  148. }
  149. await self.websocket_manager.send_personal_message(
  150. message, self.websocket
  151. )
  152. return False, "相机未连接"
  153. # 链接的相机
  154. CameraStatus = any(
  155. item.get("CameraStatus") in ["Ready", "Busy"] for item in cameraInfo
  156. )
  157. if not CameraStatus:
  158. self.connect_status = False
  159. msg_send = "相机未连接"
  160. if is_send:
  161. message = {
  162. "code": 1,
  163. "msg": msg_send,
  164. "data": msg_result,
  165. "msg_type": self.msg_type,
  166. "device_status": -1,
  167. }
  168. await self.websocket_manager.send_personal_message(
  169. message, self.websocket
  170. )
  171. return False, msg_send
  172. self.connect_status = True
  173. msg_send = "相机已连接"
  174. if is_send:
  175. message = {
  176. "code": 0,
  177. "msg": msg_send,
  178. "data": msg_result,
  179. "msg_type": self.msg_type,
  180. "device_status": 2,
  181. }
  182. await self.websocket_manager.send_personal_message(
  183. message, self.websocket
  184. )
  185. print("相机已连接状态信息---->", cameraInfo)
  186. return True, "相机已连接"
  187. except zmq.Again:
  188. print("获取相机信息超时,继续监听...")
  189. msg_send = "相机未连接或软件未打开"
  190. if is_send:
  191. message = {
  192. "code": 1,
  193. "msg": msg_send,
  194. "data": None,
  195. "msg_type": self.msg_type,
  196. "device_status": -1,
  197. }
  198. await self.websocket_manager.send_personal_message(
  199. message, self.websocket
  200. )
  201. return False, msg_send
  202. except Exception as e:
  203. print("拍照异常", e)
  204. self.connect_status = False
  205. socket.close()
  206. context.term()
  207. msg_send = "相机未连接或软件未打开"
  208. if is_send:
  209. message = {
  210. "code": 1,
  211. "msg": msg_send,
  212. "data": None,
  213. "msg_type": self.msg_type,
  214. "device_status": -1,
  215. }
  216. await self.websocket_manager.send_personal_message(
  217. message, self.websocket
  218. )
  219. return False, msg_send
  220. async def SetCameraFPS(self, fps=5):
  221. """
  222. 激活相机预览
  223. """
  224. camera_states, _ = await self.GetCameraInfo(is_send=False)
  225. if not camera_states:
  226. return False, "请先连接相机"
  227. try:
  228. socket, context = self.__create_req()
  229. req = {}
  230. req["msg_type"] = "Request"
  231. req["msg_id"] = "LiveviewFPS"
  232. req["msg_seq_num"] = 0
  233. req["CameraSelection"] = "All"
  234. req["CameraLiveviewFPS"] = fps
  235. json_msg = self.__send_tcp_message(socket, req)
  236. msg_result = json_msg.get("msg_result")
  237. if not msg_result:
  238. self.perview_state = False
  239. return False, "设置失败"
  240. return True, "设置失败"
  241. except:
  242. self.perview_state = False
  243. socket.close()
  244. context.term()
  245. return False, "相机未连接或软件未打开"
  246. async def setCameraProperty(self, property="ISO", value=0):
  247. # SetProperty
  248. camera_states, _ = await self.GetCameraInfo(is_send=False)
  249. if not camera_states:
  250. return False, "请先连接相机"
  251. try:
  252. socket, context = self.__create_req()
  253. req = {}
  254. req["msg_type"] = "Request"
  255. req["msg_id"] = "SetProperty"
  256. req["msg_seq_num"] = 0
  257. req["CameraSelection"] = "All"
  258. req["CameraPropertyType"] = str(property)
  259. req["CameraPropertyValue"] = str(value)
  260. json_msg = self.__send_tcp_message(socket, req)
  261. msg_result = json_msg.get("msg_result")
  262. if not msg_result:
  263. return False, f"{property}设置失败"
  264. return True, f"{property}设置成功"
  265. except zmq.Again:
  266. print(f"设置{property}超时,继续监听...")
  267. except:
  268. self.perview_state = False
  269. socket.close()
  270. context.term()
  271. msg_send = "相机未连接或软件未打开"
  272. return False, msg_send
  273. async def EnableCameraPreview(self, enable_status=True, msg_type=""):
  274. self.msg_type = msg_type
  275. await self.SetCameraFPS(5)
  276. """
  277. 激活相机预览
  278. """
  279. camera_states, _ = await self.GetCameraInfo(is_send=False)
  280. if not camera_states:
  281. return False, "请先连接相机"
  282. try:
  283. camera_configs = settings.getSysConfigs(
  284. "camera_configs",
  285. "iso_config",
  286. {"low": 100, "high": 6400, "mode": "un_auto"},
  287. )
  288. low_iso = camera_configs.get("low", 100)
  289. high_iso = camera_configs.get("high", 6400)
  290. mode_iso = camera_configs.get("mode", 6400)
  291. print("LOW_ISO", low_iso)
  292. print("HIGH_ISO", high_iso)
  293. print("MODE_ISO", mode_iso)
  294. if str(mode_iso).lower() != "auto":
  295. # 等于auto就不设置
  296. if enable_status == True:
  297. await self.setCameraProperty(property="ISO", value=str(mode_iso))
  298. if enable_status == False:
  299. await self.setCameraProperty(property="ISO", value=str(mode_iso))
  300. else:
  301. print("等于auto就不设置")
  302. socket, context = self.__create_req()
  303. req = {}
  304. req["msg_type"] = "Request"
  305. req["msg_id"] = "EnableLiveview"
  306. req["msg_seq_num"] = 0
  307. req["CameraSelection"] = "All"
  308. req["Enable"] = enable_status
  309. json_msg = self.__send_tcp_message(socket, req)
  310. msg_result = json_msg.get("msg_result")
  311. if not msg_result:
  312. self.perview_state = False
  313. msg_send = "预览启用失败"
  314. self.sendSocketMessage(
  315. code=0,
  316. msg=msg_send,
  317. device_status=2,
  318. )
  319. return False, "预览启用失败"
  320. msg_send = "预览启用成功" if enable_status else "预览关闭成功"
  321. message = {
  322. "code": 0,
  323. "msg": msg_send,
  324. "data": None,
  325. "msg_type": self.msg_type,
  326. "device_status": 2,
  327. }
  328. await self.websocket_manager.send_personal_message(message, self.websocket)
  329. return True, "预览启用成功" if enable_status else "预览关闭成功"
  330. except zmq.Again:
  331. print("启动预览超时,继续监听...")
  332. except:
  333. self.perview_state = False
  334. socket.close()
  335. context.term()
  336. msg_send = "相机未连接或软件未打开"
  337. message = {
  338. "code": 1,
  339. "msg": msg_send,
  340. "data": None,
  341. "msg_type": self.msg_type,
  342. "device_status": -1,
  343. }
  344. await self.websocket_manager.send_personal_message(message, self.websocket)
  345. return False, "相机未连接或软件未打开"
  346. async def CameraAutofocus(self):
  347. """
  348. 相机自动对焦
  349. """
  350. camera_states, _ = await self.GetCameraInfo(is_send=False)
  351. print("CameraAutofocus 执行对焦")
  352. if not camera_states:
  353. return False, "请先连接相机"
  354. try:
  355. socket, context = self.__create_req()
  356. req = {}
  357. req["msg_type"] = "Request"
  358. req["msg_id"] = "Autofocus"
  359. req["msg_seq_num"] = 0
  360. req["CameraSelection"] = "All"
  361. json_msg = self.__send_tcp_message(socket, req)
  362. print("json_msg", json_msg)
  363. msg_result = json_msg.get("msg_result")
  364. if not msg_result:
  365. return False, "对焦失败"
  366. return True, "对焦成功"
  367. except zmq.Again:
  368. print("对焦超时,继续监听...")
  369. except:
  370. socket.close()
  371. context.term()
  372. return False, "相机未连接或软件未打开"
  373. async def CameraShooter(self, msg_type="", goods_art_no="", id=0, is_af=False,delay=1.5):
  374. # 这里延迟一秒钟 等待前置命令完成
  375. await asyncio.sleep(delay)
  376. # 对焦混用
  377. if is_af:
  378. await self.CameraAutofocus()
  379. self.msg_type = msg_type
  380. print("camera_states", msg_type)
  381. """
  382. 执行拍照
  383. """
  384. camera_states, _ = await self.GetCameraInfo(is_send=True)
  385. print("camera_states CameraShooter", camera_states)
  386. if not camera_states:
  387. return False, "请先连接相机"
  388. try:
  389. socket, context = self.__create_req()
  390. req = {}
  391. req["msg_type"] = "Request"
  392. req["msg_id"] = "Shoot"
  393. req["msg_seq_num"] = 1
  394. req["CameraSelection"] = "All"
  395. if goods_art_no != "" and id != 0:
  396. # 此处用逗号分割,货号和id,需要在监听部分进行切割保存处理,如果使用下划线或者减号,可能货号中存在对应符号
  397. req["PhotoOrigin"] = f"{goods_art_no},{id}"
  398. else:
  399. req["PhotoOrigin"] = ""
  400. json_msg = self.__send_tcp_message(socket, req)
  401. print("CameraShooter", json_msg)
  402. msg_result = json_msg.get("msg_result")
  403. if not msg_result:
  404. msg_send = "拍照失败"
  405. message = {
  406. "code": 1,
  407. "msg": msg_send,
  408. "data": None,
  409. "msg_type": self.msg_type,
  410. "device_status": -1,
  411. }
  412. await self.websocket_manager.send_personal_message(
  413. message, self.websocket
  414. )
  415. return False, msg_send
  416. msg_send = "拍照成功"
  417. message = {
  418. "code": 0,
  419. "msg": msg_send,
  420. "data": None,
  421. "msg_type": self.msg_type,
  422. "device_status": 2,
  423. }
  424. msg_send = "相机未连接或软件未打开"
  425. message = {
  426. "code": 1,
  427. "msg": msg_send,
  428. "data": None,
  429. "msg_type": self.msg_type,
  430. "device_status": -1,
  431. }
  432. await self.websocket_manager.send_personal_message(message, self.websocket)
  433. return True, "拍照成功"
  434. except zmq.Again:
  435. msg_send = "相机未连接或软件未打开"
  436. message = {
  437. "code": 1,
  438. "msg": msg_send,
  439. "data": {goods_art_no: goods_art_no, "id": id},
  440. "msg_type": self.msg_type,
  441. "device_status": -1,
  442. }
  443. await self.websocket_manager.send_personal_message(message, self.websocket)
  444. return True, "拍照失败"
  445. except:
  446. socket.close()
  447. context.term()
  448. msg_send = "相机未连接或软件未打开"
  449. message = {
  450. "code": 1,
  451. "msg": msg_send,
  452. "data": None,
  453. "msg_type": self.msg_type,
  454. "device_status": -1,
  455. }
  456. await self.websocket_manager.send_personal_message(message, self.websocket)
  457. return False, msg_send
  458. def connect_listen(self):
  459. print("smart shooter connect_listen", self.connect_status, self.listen_init)
  460. if self.connect_status == True or self.listen_init == True:
  461. return True
  462. # 发起监听
  463. sub_socket, context = self.__create_listen()
  464. print("构建监听", self.connect_status)
  465. logger.info("构建监听,%s", self.connect_status)
  466. while True:
  467. self.listen_init = True
  468. if self.callback_listen == None:
  469. continue
  470. # camera_states, camera_msg = await self.GetCameraInfo(is_send=False)
  471. # if not camera_states:
  472. # print("相机未连接回调打印", camera_states, camera_msg)
  473. # await asyncio.sleep(0.01) # 等待相机连接
  474. # continue
  475. if self.stop_listen:
  476. break
  477. try:
  478. self.connect_status = True
  479. raw = sub_socket.recv()
  480. str_msg = raw.decode("utf-8")
  481. json_msg = json.loads(str_msg)
  482. if json_msg["msg_id"] == "NetworkPing":
  483. continue
  484. # self.callback_listen(json_msg)
  485. asyncio.run(self.callback_listen(json_msg))
  486. except zmq.Again:
  487. print("接收超时,继续监听...")
  488. logger.info("接收超时,继续监听...")
  489. continue
  490. except Exception as e:
  491. self.connect_status = False
  492. print(f"发生错误: {e}")
  493. break
  494. self.listen_init = False
  495. self.connect_status = False
  496. self.stop_listen = False
  497. sub_socket.close()
  498. context.term()
  499. print("smart shooter连接断开")