Преглед изворни кода

```
feat(camera): 添加相机键参数支持单个相机选择

添加 CameraKey 参数到多个相机操作方法中,包括:
- GetCameraProperty
- GetCameraInfo
- SetCameraFPS
- setCameraProperty
- EnableCameraPreview
- CameraAutofocus
- CameraShooter

当提供 CameraKey 参数时,请求将针对特定相机而不是所有相机,
通过设置 CameraSelection 为 "Single" 并传递 CameraKey 实现精确控制。

refactor(temp): 注释调试代码并优化超时设置

将临时测试文件中的调试代码注释掉,并调整
ZeroMQ 超时设置从5秒改为2秒以提高响应速度。
```

rambo пре 3 недеља
родитељ
комит
8dcb438ccb
2 измењених фајлова са 83 додато и 63 уклоњено
  1. 57 34
      python/mcu/capture/smart_shooter_class.py
  2. 26 29
      python/temp.py

+ 57 - 34
python/mcu/capture/smart_shooter_class.py

@@ -62,7 +62,8 @@ class SmartShooter(metaclass=SingletonType):
         listen_socket.setsockopt(zmq.LINGER, 0)  # 设置为 0 表示不等待未完成的操作
         listen_socket.setsockopt(zmq.LINGER, 0)  # 设置为 0 表示不等待未完成的操作
         listen_socket.connect(self.LISTEN_REQ)
         listen_socket.connect(self.LISTEN_REQ)
         return listen_socket, context
         return listen_socket, context
-    async def GetCameraProperty(self):
+
+    async def GetCameraProperty(self, CameraKey=None):
         '''获取相机属性'''
         '''获取相机属性'''
         await asyncio.sleep(0.01)
         await asyncio.sleep(0.01)
         """
         """
@@ -75,6 +76,9 @@ class SmartShooter(metaclass=SingletonType):
             req["msg_id"] = "GetCamera"
             req["msg_id"] = "GetCamera"
             req["msg_seq_num"] = 0
             req["msg_seq_num"] = 0
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             json_msg = self.__send_tcp_message(socket, req)
             json_msg = self.__send_tcp_message(socket, req)
             msg_result = json_msg.get("msg_result")
             msg_result = json_msg.get("msg_result")
             if not msg_result:
             if not msg_result:
@@ -111,7 +115,8 @@ class SmartShooter(metaclass=SingletonType):
             context.term()
             context.term()
             msg_send = "相机未连接或软件未打开"
             msg_send = "相机未连接或软件未打开"
             return False, msg_send
             return False, msg_send
-    async def GetCameraInfo(self, is_send=True, msg_type=""):
+
+    async def GetCameraInfo(self, is_send=True, msg_type="",CameraKey=None):
         await asyncio.sleep(0.001)
         await asyncio.sleep(0.001)
         self.msg_type = msg_type
         self.msg_type = msg_type
         """
         """
@@ -124,6 +129,9 @@ class SmartShooter(metaclass=SingletonType):
             req["msg_id"] = "GetCamera"
             req["msg_id"] = "GetCamera"
             req["msg_seq_num"] = 0
             req["msg_seq_num"] = 0
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             json_msg = self.__send_tcp_message(socket, req)
             json_msg = self.__send_tcp_message(socket, req)
             msg_result = json_msg.get("msg_result")
             msg_result = json_msg.get("msg_result")
             if not msg_result:
             if not msg_result:
@@ -225,11 +233,11 @@ class SmartShooter(metaclass=SingletonType):
                 )
                 )
             return False, msg_send
             return False, msg_send
 
 
-    async def SetCameraFPS(self, fps=5):
+    async def SetCameraFPS(self, fps=5,CameraKey=None):
         """
         """
         激活相机预览
         激活相机预览
         """
         """
-        camera_states, _ = await self.GetCameraInfo(is_send=False)
+        camera_states, _ = await self.GetCameraInfo(is_send=False,CameraKey=CameraKey)
         if not camera_states:
         if not camera_states:
             return False, "请先连接相机"
             return False, "请先连接相机"
         socket, context = self.__create_req()
         socket, context = self.__create_req()
@@ -239,6 +247,9 @@ class SmartShooter(metaclass=SingletonType):
             req["msg_id"] = "LiveviewFPS"
             req["msg_id"] = "LiveviewFPS"
             req["msg_seq_num"] = 0
             req["msg_seq_num"] = 0
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             req["CameraLiveviewFPS"] = fps
             req["CameraLiveviewFPS"] = fps
             json_msg = self.__send_tcp_message(socket, req)
             json_msg = self.__send_tcp_message(socket, req)
             msg_result = json_msg.get("msg_result")
             msg_result = json_msg.get("msg_result")
@@ -252,9 +263,9 @@ class SmartShooter(metaclass=SingletonType):
             context.term()
             context.term()
             return False, "相机未连接或软件未打开"
             return False, "相机未连接或软件未打开"
 
 
-    async def setCameraProperty(self, property="ISO", value=0):
+    async def setCameraProperty(self, property="ISO", value=0, CameraKey=None):
         # SetProperty
         # SetProperty
-        camera_states, _ = await self.GetCameraInfo(is_send=False)
+        camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
         if not camera_states:
         if not camera_states:
             return False, "请先连接相机"
             return False, "请先连接相机"
         socket, context = self.__create_req()
         socket, context = self.__create_req()
@@ -264,6 +275,9 @@ class SmartShooter(metaclass=SingletonType):
             req["msg_id"] = "SetProperty"
             req["msg_id"] = "SetProperty"
             req["msg_seq_num"] = 0
             req["msg_seq_num"] = 0
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             req["CameraPropertyType"] = str(property)
             req["CameraPropertyType"] = str(property)
             req["CameraPropertyValue"] = str(value)
             req["CameraPropertyValue"] = str(value)
             json_msg = self.__send_tcp_message(socket, req)
             json_msg = self.__send_tcp_message(socket, req)
@@ -280,22 +294,22 @@ class SmartShooter(metaclass=SingletonType):
             msg_send = "相机未连接或软件未打开"
             msg_send = "相机未连接或软件未打开"
             return False, msg_send
             return False, msg_send
     async def getConfigIso(self):
     async def getConfigIso(self):
-            """获取ISO配置信息"""
-            camera_configs = settings.getSysConfigs(
+        """获取ISO配置信息"""
+        camera_configs = settings.getSysConfigs(
                 "camera_configs",
                 "camera_configs",
                 "iso_config",
                 "iso_config",
                 {"low": 100, "high": 6400, "mode": "un_auto"},
                 {"low": 100, "high": 6400, "mode": "un_auto"},
             )
             )
-            low_iso = camera_configs.get("low", 100)
-            high_iso = camera_configs.get("high", 6400)
-            return low_iso, high_iso
-    async def EnableCameraPreview(self, enable_status=True, msg_type=""):
+        low_iso = camera_configs.get("low", 100)
+        high_iso = camera_configs.get("high", 6400)
+        return low_iso, high_iso
+    async def EnableCameraPreview(self, enable_status=True, msg_type="",CameraKey=None):
         self.msg_type = msg_type
         self.msg_type = msg_type
-        await self.SetCameraFPS(5)
+        await self.SetCameraFPS(5,CameraKey=CameraKey)
         """
         """
         激活相机预览
         激活相机预览
         """
         """
-        camera_states, _ = await self.GetCameraInfo(is_send=False)
+        camera_states, _ = await self.GetCameraInfo(is_send=False,CameraKey=CameraKey)
         if not camera_states:
         if not camera_states:
             return False, "请先连接相机"
             return False, "请先连接相机"
         try:
         try:
@@ -305,12 +319,12 @@ class SmartShooter(metaclass=SingletonType):
             # 等于auto就不设置
             # 等于auto就不设置
             if enable_status == True:
             if enable_status == True:
                 if str(high_iso).lower() != "auto":
                 if str(high_iso).lower() != "auto":
-                    await self.setCameraProperty(property="ISO", value=str(high_iso))
+                    await self.setCameraProperty(property="ISO", value=str(high_iso), CameraKey=CameraKey)
                 else:
                 else:
                     print("high_iso 等于auto就不设置")
                     print("high_iso 等于auto就不设置")
             if enable_status == False:
             if enable_status == False:
                 if str(low_iso).lower() != "auto":
                 if str(low_iso).lower() != "auto":
-                    await self.setCameraProperty(property="ISO", value=str(low_iso))
+                    await self.setCameraProperty(property="ISO", value=str(low_iso), CameraKey=CameraKey)
                 else:
                 else:
                     print("low_iso 等于auto就不设置")
                     print("low_iso 等于auto就不设置")
             socket, context = self.__create_req()
             socket, context = self.__create_req()
@@ -319,6 +333,9 @@ class SmartShooter(metaclass=SingletonType):
             req["msg_id"] = "EnableLiveview"
             req["msg_id"] = "EnableLiveview"
             req["msg_seq_num"] = 0
             req["msg_seq_num"] = 0
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             req["Enable"] = enable_status
             req["Enable"] = enable_status
             json_msg = self.__send_tcp_message(socket, req)
             json_msg = self.__send_tcp_message(socket, req)
             msg_result = json_msg.get("msg_result")
             msg_result = json_msg.get("msg_result")
@@ -358,11 +375,11 @@ class SmartShooter(metaclass=SingletonType):
             await self.websocket_manager.send_personal_message(message, self.websocket)
             await self.websocket_manager.send_personal_message(message, self.websocket)
             return False, "相机未连接或软件未打开"
             return False, "相机未连接或软件未打开"
 
 
-    async def CameraAutofocus(self):
+    async def CameraAutofocus(self, CameraKey=None):
         """
         """
         相机自动对焦
         相机自动对焦
         """
         """
-        camera_states, _ = await self.GetCameraInfo(is_send=False)
+        camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
         print("CameraAutofocus 执行对焦")
         print("CameraAutofocus 执行对焦")
         if not camera_states:
         if not camera_states:
             return False, "请先连接相机"
             return False, "请先连接相机"
@@ -373,6 +390,9 @@ class SmartShooter(metaclass=SingletonType):
             req["msg_id"] = "Autofocus"
             req["msg_id"] = "Autofocus"
             req["msg_seq_num"] = 0
             req["msg_seq_num"] = 0
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             start_time = time.time()  # 添加对焦开始时间记录
             start_time = time.time()  # 添加对焦开始时间记录
             json_msg = self.__send_tcp_message(socket, req)
             json_msg = self.__send_tcp_message(socket, req)
             end_time = time.time()  # 添加对焦结束时间记录
             end_time = time.time()  # 添加对焦结束时间记录
@@ -389,24 +409,24 @@ class SmartShooter(metaclass=SingletonType):
             context.term()
             context.term()
             return False, "相机未连接或软件未打开"
             return False, "相机未连接或软件未打开"
 
 
-    async def CameraShooter(self, msg_type="", goods_art_no="", id=0, is_af=False,delay=0.5):
+    async def CameraShooter(self, msg_type="", goods_art_no="", id=0, is_af=False,delay=0.5, CameraKey=None):
         # 这里延迟一秒钟 等待前置命令完成
         # 这里延迟一秒钟 等待前置命令完成
         await asyncio.sleep(delay)
         await asyncio.sleep(delay)
         # 对焦混用
         # 对焦混用
         if is_af:
         if is_af:
-            await self.EnableCameraPreview(enable_status=True, msg_type=msg_type)
+            await self.EnableCameraPreview(enable_status=True, msg_type=msg_type, CameraKey=CameraKey)
             start_time = time.time()
             start_time = time.time()
-            await self.CameraAutofocus()
+            await self.CameraAutofocus(CameraKey=CameraKey)
             end_time = time.time()
             end_time = time.time()
             elapsed_time = end_time - start_time
             elapsed_time = end_time - start_time
             logger.info(f"自动对焦耗时  {elapsed_time:.4f} 秒")
             logger.info(f"自动对焦耗时  {elapsed_time:.4f} 秒")
-            await self.EnableCameraPreview(enable_status=False, msg_type=msg_type)
+            await self.EnableCameraPreview(enable_status=False, msg_type=msg_type, CameraKey=CameraKey)
         self.msg_type = msg_type
         self.msg_type = msg_type
         print("camera_states", msg_type)
         print("camera_states", msg_type)
         """
         """
         执行拍照
         执行拍照
         """
         """
-        camera_states, _ = await self.GetCameraInfo(is_send=True)
+        camera_states, _ = await self.GetCameraInfo(is_send=True, CameraKey=CameraKey)
         print("camera_states CameraShooter", camera_states)
         print("camera_states CameraShooter", camera_states)
         if not camera_states:
         if not camera_states:
             return False, "请先连接相机"
             return False, "请先连接相机"
@@ -416,14 +436,17 @@ class SmartShooter(metaclass=SingletonType):
             print("LOW_ISO", low_iso)
             print("LOW_ISO", low_iso)
             print("HIGH_ISO", high_iso)
             print("HIGH_ISO", high_iso)
             if str(low_iso).lower() != "auto":
             if str(low_iso).lower() != "auto":
-                    await self.setCameraProperty(property="ISO", value=str(low_iso))
+                await self.setCameraProperty(property="ISO", value=str(low_iso), CameraKey=CameraKey)
             else:
             else:
-                    print("low_iso 等于auto就不设置")
+                print("low_iso 等于auto就不设置")
             req = {}
             req = {}
             req["msg_type"] = "Request"
             req["msg_type"] = "Request"
             req["msg_id"] = "Shoot"
             req["msg_id"] = "Shoot"
             req["msg_seq_num"] = 1
             req["msg_seq_num"] = 1
             req["CameraSelection"] = "All"
             req["CameraSelection"] = "All"
+            if CameraKey is not None:
+                req["CameraSelection"] = "Single"
+                req["CameraKey"] = CameraKey
             if goods_art_no != "" and id != 0:
             if goods_art_no != "" and id != 0:
                 # 此处用逗号分割,货号和id,需要在监听部分进行切割保存处理,如果使用下划线或者减号,可能货号中存在对应符号
                 # 此处用逗号分割,货号和id,需要在监听部分进行切割保存处理,如果使用下划线或者减号,可能货号中存在对应符号
                 req["PhotoOrigin"] = f"{goods_art_no},{id}"
                 req["PhotoOrigin"] = f"{goods_art_no},{id}"
@@ -500,42 +523,42 @@ class SmartShooter(metaclass=SingletonType):
         print("smart shooter connect_listen START")
         print("smart shooter connect_listen START")
         if self.connect_status == True or self.listen_init == True:
         if self.connect_status == True or self.listen_init == True:
             return True
             return True
-        
+
         sub_socket, context = self.__create_listen()
         sub_socket, context = self.__create_listen()
         print("构建监听", self.connect_status)
         print("构建监听", self.connect_status)
-        
+
         # 不再需要 self.listen_loop,我们只使用主循环
         # 不再需要 self.listen_loop,我们只使用主循环
-        
+
         try:
         try:
             while True:
             while True:
                 self.listen_init = True
                 self.listen_init = True
-                
+
                 if self.stop_listen:
                 if self.stop_listen:
                     break
                     break
-                
+
                 # 1. 阻塞接收 ZMQ 消息 (这是唯一的阻塞点,但在子线程,所以没问题)
                 # 1. 阻塞接收 ZMQ 消息 (这是唯一的阻塞点,但在子线程,所以没问题)
                 try:
                 try:
                     raw = sub_socket.recv() # 这里会阻塞直到有消息或超时
                     raw = sub_socket.recv() # 这里会阻塞直到有消息或超时
                     str_msg = raw.decode("utf-8")
                     str_msg = raw.decode("utf-8")
                     json_msg = json.loads(str_msg)
                     json_msg = json.loads(str_msg)
-                    
+
                     if json_msg.get("msg_id") == "NetworkPing":
                     if json_msg.get("msg_id") == "NetworkPing":
                         continue
                         continue
-                    
+
                     # 2. 将回调提交到【主事件循环】
                     # 2. 将回调提交到【主事件循环】
                     if hasattr(self, 'main_loop') and self.main_loop:
                     if hasattr(self, 'main_loop') and self.main_loop:
                         # 非阻塞提交,立即返回
                         # 非阻塞提交,立即返回
                         asyncio.run_coroutine_threadsafe(self.callback_listen(json_msg), self.main_loop)
                         asyncio.run_coroutine_threadsafe(self.callback_listen(json_msg), self.main_loop)
                     else:
                     else:
                         print("Error: main_loop not set in SmartShooter")
                         print("Error: main_loop not set in SmartShooter")
-                        
+
                 except zmq.Again:
                 except zmq.Again:
                     # 超时,继续循环
                     # 超时,继续循环
                     continue
                     continue
                 except Exception as e:
                 except Exception as e:
                     print(f"ZMQ Error: {e}")
                     print(f"ZMQ Error: {e}")
                     break
                     break
-                    
+
         finally:
         finally:
             self.listen_init = False
             self.listen_init = False
             self.connect_status = False
             self.connect_status = False

+ 26 - 29
python/temp.py

@@ -1,29 +1,26 @@
-import zmq,json,time
-def __send_tcp_message(socket, msg):
-    socket.send_string(json.dumps(msg, ensure_ascii=False))
-    rep = socket.recv()
-    str_msg = rep.decode("utf-8")
-    json_msg = json.loads(str_msg)
-    return json_msg
-LISTEN_REQ = "tcp://127.0.0.1:54543"
-SET_REQ = "tcp://127.0.0.1:54544"
-time_out = 5
-context = zmq.Context()
-req_socket = context.socket(zmq.REQ)
-# 设置发送超时为 5000 毫秒(5 秒)
-req_socket.setsockopt(zmq.RCVTIMEO, time_out * 1000)
-# 设置接收超时为 5000 毫秒(5 秒)
-req_socket.setsockopt(zmq.SNDTIMEO, time_out * 1000)
-req_socket.setsockopt(zmq.LINGER, 0)  # 设置为 0 表示不等待未完成的操作
-req_socket.connect(SET_REQ)
-req = {}
-req["msg_type"] = "Request"
-req["msg_id"] = "Autofocus"
-req["msg_seq_num"] = 0
-req["CameraSelection"] = "All"
-start_time = time.time()  # 添加对焦开始时间记录
-json_msg = __send_tcp_message(req_socket, req)
-end_time = time.time()  # 添加对焦结束时间记录
-print(f"对焦通信耗时: {end_time - start_time:.4f} 秒")
-msg_result = json_msg.get("msg_result")
-print("json_msg", json_msg)
+import zmq,json
+# def __send_tcp_message(socket, msg):
+#     socket.send_string(json.dumps(msg, ensure_ascii=False))
+#     rep = socket.recv()
+#     str_msg = rep.decode("utf-8")
+#     json_msg = json.loads(str_msg)
+#     return json_msg
+# LISTEN_REQ = "tcp://127.0.0.1:54543"
+# SET_REQ = "tcp://127.0.0.1:54544"
+# context = zmq.Context()
+# req_socket = context.socket(zmq.REQ)
+# # 设置发送超时为 5000 毫秒(5 秒)
+# req_socket.setsockopt(zmq.RCVTIMEO, 2 * 1000)
+# # 设置接收超时为 5000 毫秒(5 秒)
+# req_socket.setsockopt(zmq.SNDTIMEO, 2 * 1000)
+# req_socket.setsockopt(zmq.LINGER, 0)  # 设置为 0 表示不等待未完成的操作
+# req_socket.connect(SET_REQ)
+# req = {}
+# req["msg_type"] = "Request"
+# req["msg_id"] = "GetCamera"
+# req["msg_seq_num"] = 0
+# req["CameraSelection"] = "Single"
+# req["CameraKey"] = "Canon Inc.|Canon EOS 650D|12"
+# json_msg = __send_tcp_message(req_socket,req)
+# cameraInfo = json_msg.get("CameraInfo")
+# print("cameraInfo",json_msg)