|
|
@@ -5,14 +5,17 @@ import zmq
|
|
|
import asyncio
|
|
|
from PIL import Image
|
|
|
from io import BytesIO
|
|
|
-import base64,threading
|
|
|
+import base64, threading
|
|
|
import zmq, sys, time
|
|
|
from utils.SingletonType import SingletonType
|
|
|
import settings
|
|
|
import logging
|
|
|
+from databases import SqlQuery, CRUD, SysConfigs
|
|
|
from utils.common import message_queue
|
|
|
-
|
|
|
+from models import SysConfigParams
|
|
|
logger = logging.getLogger(__name__)
|
|
|
+
|
|
|
+
|
|
|
# 定义为单例模式,避免被重复实例化
|
|
|
class SmartShooter(metaclass=SingletonType):
|
|
|
SET_REQ = "tcp://127.0.0.1:54544"
|
|
|
@@ -51,6 +54,10 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
req_socket.connect(self.SET_REQ)
|
|
|
return req_socket, context
|
|
|
|
|
|
+ async def sendMessageSocket(self, message):
|
|
|
+ if self.websocket_manager and self.websocket:
|
|
|
+ await self.websocket_manager.send_personal_message(message, self.websocket)
|
|
|
+
|
|
|
def __create_listen(self) -> tuple[zmq.Socket, zmq.Context]:
|
|
|
context = zmq.Context()
|
|
|
listen_socket = context.socket(zmq.SUB)
|
|
|
@@ -64,7 +71,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
return listen_socket, context
|
|
|
|
|
|
async def GetCameraProperty(self, CameraKey=None):
|
|
|
- '''获取相机属性'''
|
|
|
+ """获取相机属性"""
|
|
|
await asyncio.sleep(0.01)
|
|
|
"""
|
|
|
实时获取相机信息,是否连接、软件是否被打开
|
|
|
@@ -92,8 +99,8 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
return False, "相机未连接"
|
|
|
# 链接的相机
|
|
|
CameraStatus = False
|
|
|
- CameraIndex =-1
|
|
|
- for cam_idx,item in enumerate(cameraInfo):
|
|
|
+ CameraIndex = -1
|
|
|
+ for cam_idx, item in enumerate(cameraInfo):
|
|
|
CameraStatus = item.get("CameraStatus") in ["Ready", "Busy"]
|
|
|
if CameraStatus == True:
|
|
|
CameraIndex = cam_idx
|
|
|
@@ -116,7 +123,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
msg_send = "相机未连接或软件未打开"
|
|
|
return False, msg_send
|
|
|
|
|
|
- async def GetCameraInfo(self, is_send=True, msg_type="",CameraKey=None):
|
|
|
+ async def GetCameraInfo(self, is_send=True, msg_type="", CameraKey=None):
|
|
|
await asyncio.sleep(0.001)
|
|
|
self.msg_type = msg_type
|
|
|
"""
|
|
|
@@ -145,9 +152,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, msg_send
|
|
|
cameraInfo = json_msg.get("CameraInfo")
|
|
|
if cameraInfo == None or len(cameraInfo) == 0:
|
|
|
@@ -161,14 +166,21 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, "相机未连接"
|
|
|
# 链接的相机
|
|
|
CameraStatus = any(
|
|
|
item.get("CameraStatus") in ["Ready", "Busy"] for item in cameraInfo
|
|
|
)
|
|
|
+ CameraLists = [
|
|
|
+ {
|
|
|
+ "CameraSelection": item.get("CameraSelection"),
|
|
|
+ "CameraKey": item.get("CameraKey"),
|
|
|
+ "CameraName": item.get("CameraName"),
|
|
|
+ "CameraStatus": item.get("CameraStatus") in ["Ready", "Busy"],
|
|
|
+ }
|
|
|
+ for item in cameraInfo
|
|
|
+ ]
|
|
|
if not CameraStatus:
|
|
|
self.connect_status = False
|
|
|
msg_send = "相机未连接"
|
|
|
@@ -180,12 +192,11 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, msg_send
|
|
|
self.connect_status = True
|
|
|
msg_send = "相机已连接"
|
|
|
+ print("CameraLists", CameraLists)
|
|
|
if is_send:
|
|
|
message = {
|
|
|
"code": 0,
|
|
|
@@ -194,10 +205,9 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": 2,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
# print("相机已连接状态信息---->", cameraInfo)
|
|
|
+ self.initConfigIsoSettings(CameraLists=CameraLists)
|
|
|
return True, "相机已连接"
|
|
|
except zmq.Again:
|
|
|
print("获取相机信息超时,继续监听...")
|
|
|
@@ -210,12 +220,10 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": 2,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, msg_send
|
|
|
except Exception as e:
|
|
|
- print("拍照异常", e)
|
|
|
+ print("相机状态获取异常", e)
|
|
|
self.connect_status = False
|
|
|
socket.close()
|
|
|
context.term()
|
|
|
@@ -228,16 +236,14 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, msg_send
|
|
|
|
|
|
- async def SetCameraFPS(self, fps=5,CameraKey=None):
|
|
|
+ async def SetCameraFPS(self, fps=5, CameraKey=None):
|
|
|
"""
|
|
|
激活相机预览
|
|
|
"""
|
|
|
- camera_states, _ = await self.GetCameraInfo(is_send=False,CameraKey=CameraKey)
|
|
|
+ camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
|
|
|
if not camera_states:
|
|
|
return False, "请先连接相机"
|
|
|
socket, context = self.__create_req()
|
|
|
@@ -293,38 +299,73 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
context.term()
|
|
|
msg_send = "相机未连接或软件未打开"
|
|
|
return False, msg_send
|
|
|
- async def getConfigIso(self):
|
|
|
+
|
|
|
+ def getConfigIso(self, CameraKey=None):
|
|
|
"""获取ISO配置信息"""
|
|
|
camera_configs = settings.getSysConfigs(
|
|
|
- "camera_configs",
|
|
|
- "iso_config",
|
|
|
- {"low": 100, "high": 6400, "mode": "un_auto"},
|
|
|
- )
|
|
|
+ "camera_configs",
|
|
|
+ "iso_config",
|
|
|
+ None,
|
|
|
+ )
|
|
|
+ for item in enumerate(camera_configs):
|
|
|
+ pass
|
|
|
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):
|
|
|
+
|
|
|
+ def initConfigIsoSettings(self, CameraLists=[]):
|
|
|
+ if not CameraLists:
|
|
|
+ return None
|
|
|
+ """获取ISO配置信息"""
|
|
|
+ camera_configs = settings.getSysConfigs(
|
|
|
+ "camera_configs",
|
|
|
+ "iso_config",
|
|
|
+ None,
|
|
|
+ )
|
|
|
+ temp_A_point = camera_configs.get("A", None)
|
|
|
+ if temp_A_point is not None:
|
|
|
+ print("已配置无需更新")
|
|
|
+ return None
|
|
|
+ points = {"A": {}, "B": {}, "C": {}}
|
|
|
+ for idx,item in enumerate(points):
|
|
|
+ if idx > len(CameraLists) -1:
|
|
|
+ break
|
|
|
+ itemSettings = CameraLists[idx]
|
|
|
+ low_iso = camera_configs.get("low", 100)
|
|
|
+ high_iso = camera_configs.get("high", 6400)
|
|
|
+ points[item] = {**itemSettings, "iso": {"low": low_iso, "high": high_iso}}
|
|
|
+ sys_iso_config = {"key": "camera_configs", "value": {"iso_config": points}}
|
|
|
+ sys_iso_config: SysConfigParams
|
|
|
+ print("首次初始化", sys_iso_config)
|
|
|
+ settings.updateSysConfigs(params=sys_iso_config)
|
|
|
+ async def EnableCameraPreview(
|
|
|
+ self, enable_status=True, msg_type="", CameraKey=None
|
|
|
+ ):
|
|
|
self.msg_type = msg_type
|
|
|
- await self.SetCameraFPS(5,CameraKey=CameraKey)
|
|
|
+ await self.SetCameraFPS(5, CameraKey=CameraKey)
|
|
|
"""
|
|
|
激活相机预览
|
|
|
"""
|
|
|
- camera_states, _ = await self.GetCameraInfo(is_send=False,CameraKey=CameraKey)
|
|
|
+ camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
|
|
|
if not camera_states:
|
|
|
return False, "请先连接相机"
|
|
|
try:
|
|
|
- low_iso,high_iso = await self.getConfigIso()
|
|
|
+ low_iso, high_iso = self.getConfigIso(CameraKey=CameraKey)
|
|
|
print("LOW_ISO", low_iso)
|
|
|
print("HIGH_ISO", high_iso)
|
|
|
# 等于auto就不设置
|
|
|
if enable_status == True:
|
|
|
if str(high_iso).lower() != "auto":
|
|
|
- await self.setCameraProperty(property="ISO", value=str(high_iso), CameraKey=CameraKey)
|
|
|
+ await self.setCameraProperty(
|
|
|
+ property="ISO", value=str(high_iso), CameraKey=CameraKey
|
|
|
+ )
|
|
|
else:
|
|
|
print("high_iso 等于auto就不设置")
|
|
|
if enable_status == False:
|
|
|
if str(low_iso).lower() != "auto":
|
|
|
- await self.setCameraProperty(property="ISO", value=str(low_iso), CameraKey=CameraKey)
|
|
|
+ await self.setCameraProperty(
|
|
|
+ property="ISO", value=str(low_iso), CameraKey=CameraKey
|
|
|
+ )
|
|
|
else:
|
|
|
print("low_iso 等于auto就不设置")
|
|
|
socket, context = self.__create_req()
|
|
|
@@ -356,7 +397,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": 2,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(message, self.websocket)
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return True, "预览启用成功" if enable_status else "预览关闭成功"
|
|
|
except zmq.Again:
|
|
|
print("启动预览超时,继续监听...")
|
|
|
@@ -372,7 +413,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(message, self.websocket)
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, "相机未连接或软件未打开"
|
|
|
|
|
|
async def CameraAutofocus(self, CameraKey=None):
|
|
|
@@ -409,18 +450,24 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
context.term()
|
|
|
return False, "相机未连接或软件未打开"
|
|
|
|
|
|
- async def CameraShooter(self, msg_type="", goods_art_no="", id=0, is_af=False,delay=0.5, CameraKey=None):
|
|
|
+ async def CameraShooter(
|
|
|
+ self, msg_type="", goods_art_no="", id=0, is_af=False, delay=0.5, CameraKey=None
|
|
|
+ ):
|
|
|
# 这里延迟一秒钟 等待前置命令完成
|
|
|
await asyncio.sleep(delay)
|
|
|
# 对焦混用
|
|
|
if is_af:
|
|
|
- await self.EnableCameraPreview(enable_status=True, msg_type=msg_type, CameraKey=CameraKey)
|
|
|
+ await self.EnableCameraPreview(
|
|
|
+ enable_status=True, msg_type=msg_type, CameraKey=CameraKey
|
|
|
+ )
|
|
|
start_time = time.time()
|
|
|
await self.CameraAutofocus(CameraKey=CameraKey)
|
|
|
end_time = time.time()
|
|
|
elapsed_time = end_time - start_time
|
|
|
logger.info(f"自动对焦耗时 {elapsed_time:.4f} 秒")
|
|
|
- await self.EnableCameraPreview(enable_status=False, msg_type=msg_type, CameraKey=CameraKey)
|
|
|
+ await self.EnableCameraPreview(
|
|
|
+ enable_status=False, msg_type=msg_type, CameraKey=CameraKey
|
|
|
+ )
|
|
|
self.msg_type = msg_type
|
|
|
print("camera_states", msg_type)
|
|
|
"""
|
|
|
@@ -432,11 +479,13 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
return False, "请先连接相机"
|
|
|
socket, context = self.__create_req()
|
|
|
try:
|
|
|
- low_iso,high_iso = await self.getConfigIso()
|
|
|
+ low_iso, high_iso = await self.getConfigIso(CameraKey=CameraKey)
|
|
|
print("LOW_ISO", low_iso)
|
|
|
print("HIGH_ISO", high_iso)
|
|
|
if str(low_iso).lower() != "auto":
|
|
|
- await self.setCameraProperty(property="ISO", value=str(low_iso), CameraKey=CameraKey)
|
|
|
+ await self.setCameraProperty(
|
|
|
+ property="ISO", value=str(low_iso), CameraKey=CameraKey
|
|
|
+ )
|
|
|
else:
|
|
|
print("low_iso 等于auto就不设置")
|
|
|
req = {}
|
|
|
@@ -464,9 +513,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, msg_send
|
|
|
msg_send = "拍照成功"
|
|
|
message = {
|
|
|
@@ -476,7 +523,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": 2,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(message, self.websocket)
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return True, "拍照成功"
|
|
|
except zmq.Again:
|
|
|
msg_send = "相机未连接或软件未打开"
|
|
|
@@ -487,7 +534,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(message, self.websocket)
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return True, "拍照失败"
|
|
|
except:
|
|
|
socket.close()
|
|
|
@@ -500,8 +547,9 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
"msg_type": self.msg_type,
|
|
|
"device_status": -1,
|
|
|
}
|
|
|
- await self.websocket_manager.send_personal_message(message, self.websocket)
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
return False, msg_send
|
|
|
+
|
|
|
async def asyncMessageListen(self):
|
|
|
if self.websocket.client_state.name != "CONNECTED":
|
|
|
print("WebSocket连接已断开,停止发送消息")
|
|
|
@@ -511,9 +559,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
if not message_queue.empty():
|
|
|
message = message_queue.get_nowait()
|
|
|
print("发送消息中。。。。。", message)
|
|
|
- await self.websocket_manager.send_personal_message(
|
|
|
- message, self.websocket
|
|
|
- )
|
|
|
+ await self.sendMessageSocket(message)
|
|
|
message_queue.task_done()
|
|
|
except Exception as e:
|
|
|
# 处理可能的异常,如队列为空等
|
|
|
@@ -538,7 +584,7 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
|
|
|
# 1. 阻塞接收 ZMQ 消息 (这是唯一的阻塞点,但在子线程,所以没问题)
|
|
|
try:
|
|
|
- raw = sub_socket.recv() # 这里会阻塞直到有消息或超时
|
|
|
+ raw = sub_socket.recv() # 这里会阻塞直到有消息或超时
|
|
|
str_msg = raw.decode("utf-8")
|
|
|
json_msg = json.loads(str_msg)
|
|
|
|
|
|
@@ -546,9 +592,11 @@ class SmartShooter(metaclass=SingletonType):
|
|
|
continue
|
|
|
|
|
|
# 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:
|
|
|
print("Error: main_loop not set in SmartShooter")
|
|
|
|