Bläddra i källkod

Merge branch 'smart-shooter-merge' into smart-shooter-master

rambo 4 månader sedan
förälder
incheckning
1a4a9d4ed8

+ 12 - 17
python/api.py

@@ -626,12 +626,6 @@ def get_photo_records(page: int = 1, size: int = 5):
         }
         }
     ]
     ]
     for item in result:
     for item in result:
-        print(item)
-        # list_item = photos.read_all(
-        #     session,
-        #     conditions={"goods_art_no": item.goods_art_no},
-        #     join_conditions=join_conditions,
-        # )
         query = (
         query = (
             select(PhotoRecord, DeviceConfig.action_name)
             select(PhotoRecord, DeviceConfig.action_name)
             .where(PhotoRecord.goods_art_no == item.goods_art_no)
             .where(PhotoRecord.goods_art_no == item.goods_art_no)
@@ -731,10 +725,21 @@ def update_left_right_config(params: LeftRightParams):
     save_device_config = sysConfig.updateConditions(
     save_device_config = sysConfig.updateConditions(
         session, conditions={"key": "action_configs"}, **kwargs
         session, conditions={"key": "action_configs"}, **kwargs
     )
     )
-    # return {"code": 0, "msg": "操作成功", "data": save_device_config}
     return {"code": 0, "msg": "操作成功", "data": None}
     return {"code": 0, "msg": "操作成功", "data": None}
 
 
 
 
+@app.post("/update_record", description="更新拍照记录")
+def update_record(params: RecordUpdate):
+    session = SqlQuery()
+    photoRecord = CRUD(PhotoRecord)
+    model = photoRecord.read(session, conditions={"id": params.id})
+    if model == None:
+        return {"code": 1, "msg": "记录不存在", "data": None}
+    kwargs = params.__dict__
+    save_device_config = photoRecord.update(session, obj_id=params.id, **kwargs)
+    return {"code": 0, "msg": "操作成功", "data": save_device_config}
+
+
 @app.post("/update_sys_configs", description="创建或修改系统配置")
 @app.post("/update_sys_configs", description="创建或修改系统配置")
 def save_sys_configs(params: SysConfigParams):
 def save_sys_configs(params: SysConfigParams):
     session = SqlQuery()
     session = SqlQuery()
@@ -754,16 +759,6 @@ def save_sys_configs(params: SysConfigParams):
 def create_main_image(params: MaineImageTest):
 def create_main_image(params: MaineImageTest):
     file_path = params.file_path
     file_path = params.file_path
     onePic = OnePicTest(pic_path=file_path)
     onePic = OnePicTest(pic_path=file_path)
-    # session = SqlQuery()
-    # sysConfig = CRUD(SysConfigs)
-    # model = sysConfig.read(session, conditions={"key": params.key})
-    # if model == None:
-    #     return {"code": 1, "msg": "配置不存在", "data": None}
-    # # 走编辑逻辑
-    # kwargs = params.__dict__
-    # save_device_config = sysConfig.updateConditions(
-    #     session, conditions={"key": params.key}, **kwargs
-    # )
     main_out_path = onePic.HandlerMainImage()
     main_out_path = onePic.HandlerMainImage()
     return {"code": 0, "msg": "操作成功", "data": {"main_out_path": main_out_path}}
     return {"code": 0, "msg": "操作成功", "data": {"main_out_path": main_out_path}}
 
 

+ 4 - 3
python/databases.py

@@ -79,8 +79,9 @@ def insert_photo_records(
     device_config = PhotoRecord(**data)
     device_config = PhotoRecord(**data)
     session.add(device_config)
     session.add(device_config)
     session.commit()
     session.commit()
+    record_id = device_config.id
     session.close()
     session.close()
-    return True
+    return True, record_id
 
 
 
 
 # 创建一个通用的 CRUD 类
 # 创建一个通用的 CRUD 类
@@ -93,8 +94,8 @@ class CRUD:
         db_obj = self.model(**obj_in_data)
         db_obj = self.model(**obj_in_data)
         session.add(db_obj)
         session.add(db_obj)
         session.commit()
         session.commit()
-        session.refresh(db_obj)
-        session.close()
+        # session.refresh(db_obj)
+        # session.close()
         return db_obj
         return db_obj
 
 
     def read(
     def read(

+ 106 - 0
python/docs/socket命令.md

@@ -553,4 +553,110 @@ _(该命令用于单独自定义配置中某一项的单独调整测试,不进
     "msg_type": "stop_action"
     "msg_type": "stop_action"
 }
 }
 ```
 ```
+
+
+
+#### 使用smart shooter进行相机控制
+<mark>以下操作需要连接连接相机并拉起smartshooter5软件<mark>
+##### 获取相机是否连接
+* data:{}
+* type:
+    * 当该字段为smart_shooter_getinfo时,代表获取相机连接信息,是否连接成功
+##### 请求示例
+```python
+{
+    "data":{},
+    "type": "smart_shooter_getinfo"
+}
+```
+##### 响应示例-连接成功
+###### 发送后指令转换
+```python
+{
+    "code": 0,
+    "msg": "相机已连接",
+    "status": 2,
+    "data": null,
+    "msg_type": "smart_shooter_getinfo"
+}
+```
+##### 响应示例-连接失败
+###### 发送后指令转换
+```python
+{
+    "code": 0,
+    "msg": "相机未连接",
+    "status": -1,
+    "data": null,
+    "msg_type": "smart_shooter_getinfo"
+}
+```
+
+##### 启动/关闭预览
+* data:
+    * value:为true时代表打开预览,为false时代表关闭预览
+* type:
+    * 当该字段为smart_shooter_enable_preview时,代表操作预览启动关闭操作
+##### 请求示例
+```python
+{
+    "data":{"value":false},
+    "type": "smart_shooter_enable_preview"
+}
+```
+##### 响应示例-启动预览
+```python
+{
+    "code": 0,
+    "msg": "预览启用成功",
+    "status": 2,
+    "data": null,
+    "msg_type": ""
+}
+```
+##### 响应示例-关闭预览
+```python
+{
+    "code": 0,
+    "msg": "预览关闭成功",
+    "status": 2,
+    "data": null,
+    "msg_type": ""
+}
+```
+
+
+##### 拍照
+* data:{}
+* type:
+    * 当该字段为smart_shooter_photo_take时,代表操作拍照动作
+##### 请求示例
+```python
+{
+    "data":{},
+    "type": "smart_shooter_photo_take"
+}
+```
+##### 响应示例-拍照成功
+```python
+{
+    "code": 0,
+    "msg": "拍照成功",
+    "status": 2,
+    "data": null,
+    "msg_type": ""
+}
+```
+##### 响应示例-照片获取成功
+```python
+{
+    "code": 1,
+    "msg": "照片获取成功",
+    "data": {
+        "photo_file_name": "C:\\Users\\15001\\Pictures\\Smart Shooter 5\\SSP_45.JPG"
+    },
+    "msg_type": "smart_shooter_photo_take"
+}
+```
+
 ##### 未完待续.....
 ##### 未完待续.....

+ 6 - 2
python/mcu/BaseClass.py

@@ -1,11 +1,15 @@
 import asyncio
 import asyncio
 from sockets import ConnectionManager
 from sockets import ConnectionManager
 from utils.common import message_queue
 from utils.common import message_queue
+from mcu.capture.smart_shooter_class import SmartShooter
 
 
 class BaseClass:
 class BaseClass:
 
 
-    def __init__(self, websocket_manager: ConnectionManager):
+    def __init__(
+        self, websocket_manager: ConnectionManager, smart_shooter: SmartShooter = None
+    ):
         self.websocket_manager = websocket_manager
         self.websocket_manager = websocket_manager
+        self.smart_shooter = smart_shooter
         self.msg_type = ""
         self.msg_type = ""
         # -1连接失败  0未连接 1连接中  2连接成功  3端口占用
         # -1连接失败  0未连接 1连接中  2连接成功  3端口占用
         # self.device_status = 2
         # self.device_status = 2
@@ -94,4 +98,4 @@ class BaseClass:
             except:
             except:
                 serial_handle = None
                 serial_handle = None
                 _recv_data = b""
                 _recv_data = b""
-                return False
+                return False

+ 26 - 29
python/mcu/BlueToothMode.py

@@ -9,13 +9,17 @@ from utils.SingletonType import SingletonType
 from .RemoteControlV2 import RemoteControlV2
 from .RemoteControlV2 import RemoteControlV2
 from .BaseClass import BaseClass
 from .BaseClass import BaseClass
 from sockets.connect_manager import ConnectionManager
 from sockets.connect_manager import ConnectionManager
+from mcu.capture.smart_shooter_class import SmartShooter
 
 
-class BlueToothMode(BaseClass,metaclass=SingletonType):
+
+class BlueToothMode(BaseClass, metaclass=SingletonType):
     instance = None
     instance = None
     init_flag = None
     init_flag = None
 
 
-    def __init__(self, websocket_manager: ConnectionManager):
-        super().__init__(websocket_manager)
+    def __init__(
+        self, websocket_manager: ConnectionManager, smart_shooter: SmartShooter = None
+    ):
+        super().__init__(websocket_manager, smart_shooter)
         """此处设计为,如果已经存在实例时,不再执行初始化"""
         """此处设计为,如果已经存在实例时,不再执行初始化"""
         if self.init_flag:
         if self.init_flag:
             return
             return
@@ -149,8 +153,8 @@ class BlueToothMode(BaseClass,metaclass=SingletonType):
                     self.print_error("Failed to connect to the device.")
                     self.print_error("Failed to connect to the device.")
                     self.devices[address]["connect_state"] = False
                     self.devices[address]["connect_state"] = False
                     self.disconnect_device(
                     self.disconnect_device(
-                            address=address, name=self.devices[address]["name"]
-                        )
+                        address=address, name=self.devices[address]["name"]
+                    )
                     continue
                     continue
                 if len(self.devices) == 0:
                 if len(self.devices) == 0:
                     break
                     break
@@ -162,32 +166,28 @@ class BlueToothMode(BaseClass,metaclass=SingletonType):
                     for char in service.characteristics:
                     for char in service.characteristics:
                         if "notify" in char.properties:
                         if "notify" in char.properties:
                             self.print_error(
                             self.print_error(
-                                    f"Subscribing to characteristic: {char.uuid}"
-                                )
+                                f"Subscribing to characteristic: {char.uuid}"
+                            )
                             await client.start_notify(
                             await client.start_notify(
-                                    char,
-                                    lambda char, data: asyncio.create_task(
-                                        self.notification_handler(address, char, data)
-                                    ),
-                                )
+                                char,
+                                lambda char, data: asyncio.create_task(
+                                    self.notification_handler(address, char, data)
+                                ),
+                            )
 
 
                 # 进入一个简单的循环,保持连接
                 # 进入一个简单的循环,保持连接
                 self.print_error(
                 self.print_error(
-                        "进入一个简单的循环  保持连接", self.devices[address]["name"]
-                    )
-                self.connect_device(
-                        address=address, name=self.devices[address]["name"]
-                    )
+                    "进入一个简单的循环  保持连接", self.devices[address]["name"]
+                )
+                self.connect_device(address=address, name=self.devices[address]["name"])
                 self.retry_num += 1
                 self.retry_num += 1
                 while True:
                 while True:
                     if not client.is_connected:
                     if not client.is_connected:
-                        self.print_error(
-                                f"Device {address} disconnected unexpectedly."
-                            )
+                        self.print_error(f"Device {address} disconnected unexpectedly.")
                         with self._lock:
                         with self._lock:
                             self.disconnect_device(
                             self.disconnect_device(
-                                    address=address, name=self.devices[address]["name"]
-                                )
+                                address=address, name=self.devices[address]["name"]
+                            )
                             if len(self.devices) == 0:
                             if len(self.devices) == 0:
                                 break
                                 break
                             self.devices[address]["connect_state"] = False
                             self.devices[address]["connect_state"] = False
@@ -196,13 +196,9 @@ class BlueToothMode(BaseClass,metaclass=SingletonType):
                         break
                         break
                     if self.devices[address]["send_queue"]:
                     if self.devices[address]["send_queue"]:
                         with self._lock:
                         with self._lock:
-                            send_data = self.devices[address][
-                                    "send_queue"
-                                ].popleft()
+                            send_data = self.devices[address]["send_queue"].popleft()
                             # print("-----------> send_data:", self.change_hex_to_10_int(send_data))
                             # print("-----------> send_data:", self.change_hex_to_10_int(send_data))
-                        await self.write_characteristic(
-                                client, char.uuid, send_data
-                            )
+                        await self.write_characteristic(client, char.uuid, send_data)
                         await asyncio.sleep(0.01)
                         await asyncio.sleep(0.01)
 
 
                     await asyncio.sleep(0.02)
                     await asyncio.sleep(0.02)
@@ -229,7 +225,7 @@ class BlueToothMode(BaseClass,metaclass=SingletonType):
         # self.devices_name[_name] = address
         # self.devices_name[_name] = address
         # asyncio.create_task(self.connect_and_listen(address))
         # asyncio.create_task(self.connect_and_listen(address))
         if self.connect_state == True:
         if self.connect_state == True:
-            print('蓝牙已连接,不可重新连接')
+            print("蓝牙已连接,不可重新连接")
             message = {
             message = {
                 "_type": "show_info",
                 "_type": "show_info",
                 "plugins_mode": "remote_control",
                 "plugins_mode": "remote_control",
@@ -251,6 +247,7 @@ class BlueToothMode(BaseClass,metaclass=SingletonType):
                 await asyncio.sleep(3)
                 await asyncio.sleep(3)
             await self.scan_for_esp32()
             await self.scan_for_esp32()
         print("蓝牙断开连接,已释放")
         print("蓝牙断开连接,已释放")
+
     def run(self):
     def run(self):
         self.print_error("开启蓝牙扫描")
         self.print_error("开启蓝牙扫描")
         asyncio.run(self.main_func())
         asyncio.run(self.main_func())

+ 72 - 69
python/mcu/DeviceControl.py

@@ -16,13 +16,15 @@ from .McuDeviationSet import McuDeviationSet
 from .OtherSet import OtherSet
 from .OtherSet import OtherSet
 from .DebugUart import DebugUart
 from .DebugUart import DebugUart
 import copy
 import copy
-
+from mcu.capture.smart_shooter_class import SmartShooter
 # mcu命令
 # mcu命令
 class DeviceControl(BaseClass, metaclass=SingletonType):
 class DeviceControl(BaseClass, metaclass=SingletonType):
     lock = threading.Lock()
     lock = threading.Lock()
 
 
-    def __init__(self, websocket_manager: ConnectionManager):
-        super().__init__(websocket_manager)
+    def __init__(
+        self, websocket_manager: ConnectionManager, smart_shooter: SmartShooter = None
+    ):
+        super().__init__(websocket_manager=websocket_manager,smart_shooter=smart_shooter)
         self.msg_type = "mcu"
         self.msg_type = "mcu"
         self.mcu_deviation_set = McuDeviationSet(self)
         self.mcu_deviation_set = McuDeviationSet(self)
         self.mcu_other_set = OtherSet(self)
         self.mcu_other_set = OtherSet(self)
@@ -114,6 +116,7 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             92: self.get_from_mcu_move_respond_data,  # 获取MCU响应
             92: self.get_from_mcu_move_respond_data,  # 获取MCU响应
             100: self.print_mcu_error_data,  # 打印下位机的错误内容
             100: self.print_mcu_error_data,  # 打印下位机的错误内容
         }
         }
+
     async def sendCommand(self,command):
     async def sendCommand(self,command):
         await asyncio.sleep(0.01)
         await asyncio.sleep(0.01)
         loop = asyncio.get_event_loop()
         loop = asyncio.get_event_loop()
@@ -261,12 +264,16 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
 
 
     async def getDeviationInfo(self):
     async def getDeviationInfo(self):
         await asyncio.sleep(0.01)
         await asyncio.sleep(0.01)
-        # 发送获取偏移量
-        data = [self.command["get_deviation"], 1]
-        self.add_send_data_queue(data)
-        # if self.serial_ins:
-        #     self.serial_ins.write_cmd(data)
-        print("发送获取偏移量")
+        try:
+            # 发送获取偏移量
+            data = [self.command["get_deviation"], 1]
+            self.add_send_data_queue(data)
+            # if self.serial_ins:
+            #     self.serial_ins.write_cmd(data)
+            print("发送获取偏移量")
+        except Exception as e:
+            print(e)
+            print("getDeviationInfo", "暂未获取到self.command")
 
 
     def set_deviation(self, device_name, _type=0, deviation=0):
     def set_deviation(self, device_name, _type=0, deviation=0):
         # turntable----0 angle_ratio   1 turntable_steering_deviation
         # turntable----0 angle_ratio   1 turntable_steering_deviation
@@ -333,7 +340,8 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             print("send_data_queue  append  :{}".format(data))
             print("send_data_queue  append  :{}".format(data))
             self.send_data_queue.append(data)
             self.send_data_queue.append(data)
         self.lock.release()
         self.lock.release()
-    def send_all_cmd(self):
+    async def send_all_cmd(self):
+        await asyncio.sleep(0.001)
         while True:
         while True:
             if self.send_data_queue:
             if self.send_data_queue:
                 self.sendSocketMessage(msg="正在发送命令", device_status=1)
                 self.sendSocketMessage(msg="正在发送命令", device_status=1)
@@ -446,8 +454,9 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
         buf.extend(self.encapsulation_data(data=has_been_set_motor_config, len_data=1))
         buf.extend(self.encapsulation_data(data=has_been_set_motor_config, len_data=1))
         self.add_send_data_queue(buf)
         self.add_send_data_queue(buf)
 
 
-    def cleanAllReceiveData(self):
+    async def cleanAllReceiveData(self):
         while True:
         while True:
+            await asyncio.sleep(0.001)
             receive_data = self.serial_ins.read_cmd(out_time=1)
             receive_data = self.serial_ins.read_cmd(out_time=1)
             if not receive_data:
             if not receive_data:
                 break
                 break
@@ -1265,8 +1274,9 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             self.sendSocketMessage(code=1, msg="mcu 非停止状态", device_status=1)
             self.sendSocketMessage(code=1, msg="mcu 非停止状态", device_status=1)
         return True
         return True
 
 
-    def controlDevice(self, device_name, value):
+    async def controlDevice(self, device_name, value):
         '''控制设备移动等'''
         '''控制设备移动等'''
+        await asyncio.sleep(0.01)
         if not self.is_running:
         if not self.is_running:
             self.sendSocketMessage(
             self.sendSocketMessage(
                 code=1, msg="mcu设备未连接,请先连接设备", device_status=0
                 code=1, msg="mcu设备未连接,请先连接设备", device_status=0
@@ -1331,18 +1341,15 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                     device_name="laser_position", value=0 if int(value) <= 0 else 1
                     device_name="laser_position", value=0 if int(value) <= 0 else 1
                 )
                 )
             case "take_picture":
             case "take_picture":
-                capture_one = DigiCam()
-                try:
-                    # camera_is_connect = capture_one.checkCameraConnect()
-                    # if camera_is_connect is not True:
-                    #     self.sendSocketMessage(1,"相机未连接,请检查",device_status=-1)
-                    #     return
-                    capture_one.getCaptureFolderPath()
-                    if value > 0:
-                        capture_one.auto_focus()
-                    capture_one.run_capture_action("Capture")
-                except:
-                    self.sendSocketMessage(1,"digicam未初始化,请检查",device_status=-1)
+                # loop = asyncio.get_event_loop()
+                # if value>0:
+                #     # 指定自动对焦
+                #     loop.create_task(
+                #         self.smart_shooter.CameraAutofocus(),
+                #         name="CameraAutofocus",
+                #     )
+                # 拍照
+                await self.smart_shooter.CameraShooter(msg_type="run_mcu")
             case "to_deal_device":
             case "to_deal_device":
                 self.to_deal_device(device_name, value=value, _type=0, times=1)
                 self.to_deal_device(device_name, value=value, _type=0, times=1)
             case _:
             case _:
@@ -1350,6 +1357,7 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             # case "photograph":
             # case "photograph":
             #     self.photograph(goods_art_no=None)
             #     self.photograph(goods_art_no=None)
     def checkDevice(self):
     def checkDevice(self):
+        print("检查设备是否运行中")
         if not self.is_running:
         if not self.is_running:
             self.sendSocketMessage(
             self.sendSocketMessage(
                 code=1, msg="mcu设备未连接,请先连接设备", device_status=0
                 code=1, msg="mcu设备未连接,请先连接设备", device_status=0
@@ -1366,12 +1374,15 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             )
             )
             return False
             return False
 
 
-    async def run_mcu_config(self, config_list, goods_art_no, action_info):
+    async def run_mcu_config(
+        self, config_list, goods_art_no, action_info, smart_shooter
+    ):
         if self.checkDevice() == False:
         if self.checkDevice() == False:
             return
             return
         image_counts = 0
         image_counts = 0
         if config_list:
         if config_list:
             action_names = []
             action_names = []
+            record_ids = []
             if len(config_list) > 1:
             if len(config_list) > 1:
                 if config_list[-1]["take_picture"] is True:
                 if config_list[-1]["take_picture"] is True:
                     new_init_config = copy.copy(config_list[0])
                     new_init_config = copy.copy(config_list[0])
@@ -1389,17 +1400,18 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             for idx, item in enumerate(config_list):
             for idx, item in enumerate(config_list):
                 is_take_picture = item["take_picture"]
                 is_take_picture = item["take_picture"]
                 action_id = item["id"]
                 action_id = item["id"]
+                record_id = -1
                 if is_take_picture:
                 if is_take_picture:
-                    action_names.append(item["action_name"])
                     image_counts += 1
                     image_counts += 1
                     # 批量插入
                     # 批量插入
                     image_deal_mode = 0 if action_info == "执行左脚程序" else 1
                     image_deal_mode = 0 if action_info == "执行左脚程序" else 1
-                    insert_photo_records(
+                    state,record_id = insert_photo_records(
                         image_deal_mode=image_deal_mode,
                         image_deal_mode=image_deal_mode,
                         goods_art_no=goods_art_no,
                         goods_art_no=goods_art_no,
                         image_index=idx,
                         image_index=idx,
                         action_id=action_id,
                         action_id=action_id,
                     )
                     )
+                config_list[idx]["record_id"] = record_id
             total_len = len(config_list)
             total_len = len(config_list)
             self.action_state = 1
             self.action_state = 1
             self.msg_type = "image_process"
             self.msg_type = "image_process"
@@ -1416,17 +1428,20 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                     ),
                     ),
                 },
                 },
             )
             )
-            self.controlDevice("laser_position", 0)
+            await self.controlDevice("laser_position", 0)
             self.msg_type = "mcu"
             self.msg_type = "mcu"
             self.is_runn_action = True
             self.is_runn_action = True
             for index, action in enumerate(config_list):
             for index, action in enumerate(config_list):
-                await asyncio.sleep(0.1)
+                # await asyncio.sleep(0.01)
                 if self.is_stop_action == True:
                 if self.is_stop_action == True:
                     self.is_stop_action = False
                     self.is_stop_action = False
                     break
                     break
-                action_is_take_picture = action["take_picture"]
+                # action_is_take_picture = action["take_picture"]
+                record_id = action["record_id"]
                 image_index = -1
                 image_index = -1
-                if action_is_take_picture:
+                if record_id == -1:
+                    image_index = -1
+                else:
                     image_index = index
                     image_index = index
                 program_item = ProgramItem(
                 program_item = ProgramItem(
                     websocket_manager=self.websocket_manager,
                     websocket_manager=self.websocket_manager,
@@ -1434,44 +1449,35 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                     mcu=self,
                     mcu=self,
                     goods_art_no=goods_art_no,
                     goods_art_no=goods_art_no,
                     image_index=image_index,
                     image_index=image_index,
+                    smart_shooter=smart_shooter,
+                    record_id=record_id,
                 )
                 )
-                print("self.action_state===>", self.action_state)
                 if self.action_state != 1:
                 if self.action_state != 1:
                     # 异常终止
                     # 异常终止
                     print("action异常终止")
                     print("action异常终止")
                     break
                     break
                 self.msg_type = "photo_take"
                 self.msg_type = "photo_take"
-                if not program_item.run(total_len):
+                if not await program_item.run(total_len):
                     self.sendSocketMessage(
                     self.sendSocketMessage(
                         code=1,
                         code=1,
                         msg="{} 执行失败~".format(program_item.action_name),
                         msg="{} 执行失败~".format(program_item.action_name),
+                        data={"goods_art_no": goods_art_no, "id": action_id},
                         device_status=0,
                         device_status=0,
                     )
                     )
                     self.to_deal_device(device_name="buzzer", times=3)
                     self.to_deal_device(device_name="buzzer", times=3)
                     break
                     break
                 else:
                 else:
-                    # self.show_info("{}执行完成~".format(action.action_name))
+                    if program_item.action_name == "移动到初始位":
+                        self.msg_type = "mcu"
+                        break
                     self.sendSocketMessage(
                     self.sendSocketMessage(
                         code=0,
                         code=0,
                         msg="{} 执行完成~".format(program_item.action_name),
                         msg="{} 执行完成~".format(program_item.action_name),
-                        data={"goods_art_no": goods_art_no},
+                        data={"goods_art_no": goods_art_no, "id": record_id},
                         device_status=2,
                         device_status=2,
                     )
                     )
                 self.msg_type = "mcu"
                 self.msg_type = "mcu"
                 # 在第三张图时检查是否有对应图片生成
                 # 在第三张图时检查是否有对应图片生成
-                # if index == 3:
-                #     # if not self.image_process_data.check_photo_is_get():
-                #     self.sendSocketMessage(
-                #             code=1,
-                #             msg="未获取到图片数据",
-                #             device_status=0,
-                #         )
-                #     self.action_state = 2
-                #     return
-                if index == total_len - 1:
-                    #  最后一个初始化处理
-                    pass
-                # self.action_state = 2
             self.action_state = 2
             self.action_state = 2
             self.is_runn_action = False
             self.is_runn_action = False
             self.msg_type = "photo_take_finish"
             self.msg_type = "photo_take_finish"
@@ -1481,46 +1487,39 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                 device_status=2,
                 device_status=2,
             )
             )
             self.msg_type = "mcu"
             self.msg_type = "mcu"
-            self.controlDevice("laser_position", 1)
+            await self.controlDevice("laser_position", 1)
 
 
-    async def run_mcu_config_single(self, config_info, goods_art_no,msg_type="run_mcu_single_finish",image_index=-1):
+    async def run_mcu_config_single(self, config_info, goods_art_no,msg_type="run_mcu_single_finish",image_index=-1,smart_shooter=None,action_id=-1):
         '''独立拍照  仅作测试用'''
         '''独立拍照  仅作测试用'''
+        await asyncio.sleep(0.01)
         if self.checkDevice() == False:
         if self.checkDevice() == False:
             return
             return
+        print("检查完成", config_info)
         if config_info:
         if config_info:
             self.action_state = 1
             self.action_state = 1
             self.msg_type = "mcu"
             self.msg_type = "mcu"
-            await asyncio.sleep(0.1)
             program_item = ProgramItem(
             program_item = ProgramItem(
                     websocket_manager=self.websocket_manager,
                     websocket_manager=self.websocket_manager,
                     action_data=config_info,
                     action_data=config_info,
                     mcu=self,
                     mcu=self,
                     goods_art_no=goods_art_no,
                     goods_art_no=goods_art_no,
                     image_index=image_index,
                     image_index=image_index,
+                    smart_shooter=smart_shooter,
+                    record_id=action_id,
                 )
                 )
-            print("self.action_state===>", self.action_state)
             if self.action_state != 1:
             if self.action_state != 1:
                 # 异常终止
                 # 异常终止
                 print("action异常终止")
                 print("action异常终止")
                 return
                 return
             self.msg_type = "photo_take"
             self.msg_type = "photo_take"
-            # if not program_item.run_only_mcu(1):
-            #     self.sendSocketMessage(
-            #             code=1,
-            #             msg="{} 执行失败~".format(program_item.action_name),
-            #             device_status=0,
-            #         )
-            #     self.to_deal_device(device_name="buzzer", times=3)
-            #     return
-            # else:
-            program_item.run(3)
-            # self.show_info("{}执行完成~".format(action.action_name))
+            program_item.smart_shooter = smart_shooter
+            await program_item.run(3)
             self.sendSocketMessage(
             self.sendSocketMessage(
-                        code=0,
-                        msg="{} 执行完成~".format(program_item.action_name),
-                        data={"goods_art_no": goods_art_no},
-                        device_status=2,
-                    )
+                code=0,
+                msg="{} 执行完成~".format(program_item.action_name),
+                data={"goods_art_no": goods_art_no, "id": action_id},
+                device_status=2,
+            )
             self.msg_type = "mcu"
             self.msg_type = "mcu"
             self.action_state = 2
             self.action_state = 2
             self.msg_type = msg_type
             self.msg_type = msg_type
@@ -1530,6 +1529,10 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                     device_status=2,
                     device_status=2,
                 )
                 )
             self.msg_type = "mcu"
             self.msg_type = "mcu"
+        else:
+            self.sendSocketMessage(
+                code=1, msg="未查询到重拍记录得配置信息,请确认", device_status=0
+            )
 
 
 
 
 async def checkMcuConnection(device_ctrl: DeviceControl):
 async def checkMcuConnection(device_ctrl: DeviceControl):
@@ -1544,7 +1547,7 @@ async def checkMcuConnection(device_ctrl: DeviceControl):
         return
         return
     """实时检测串口是否连接"""
     """实时检测串口是否连接"""
     while True:
     while True:
-        await asyncio.sleep(0.5)
+        await asyncio.sleep(0.01)
         if device_ctrl.mcu_exit:
         if device_ctrl.mcu_exit:
             break
             break
         ports_dict = device_ctrl.scan_serial_port()
         ports_dict = device_ctrl.scan_serial_port()

+ 8 - 4
python/mcu/McuDeviationSet.py

@@ -21,8 +21,8 @@ class McuDeviationSet:
         self.last_value = defaultdict(float)
         self.last_value = defaultdict(float)
         is_debug = True if settings.IS_DEBUG == "true" else False
         is_debug = True if settings.IS_DEBUG == "true" else False
         self.mcu_debug = McuDebug(mcu, is_debug=is_debug, is_deviation=False)
         self.mcu_debug = McuDebug(mcu, is_debug=is_debug, is_deviation=False)
-        loop = asyncio.get_event_loop()
-        loop.create_task(self.get_mcu_deviation(), name="get_mcu_deviation")
+        # loop = asyncio.get_event_loop()
+        self.get_mcu_deviation()
         # # 运动到设定位
         # # 运动到设定位
         # QTimer.singleShot(2500, self.init_pos)
         # QTimer.singleShot(2500, self.init_pos)
 
 
@@ -235,8 +235,12 @@ class McuDeviationSet:
     def _to_init_all(self, *args):
     def _to_init_all(self, *args):
         self.mcu.to_init_device_origin_point(device_name="mcu", is_force=True)
         self.mcu.to_init_device_origin_point(device_name="mcu", is_force=True)
 
 
-    async def get_mcu_deviation(self):
-        await self.mcu.getDeviationInfo()
+    def get_mcu_deviation(self):
+        # await asyncio.sleep(0.01)
+        # await self.mcu.getDeviationInfo()
+        # loop = asyncio.get_event_loop()
+        # loop.create_task(self.mcu.getDeviationInfo(), name="get_mcu_deviation")
+        asyncio.run(self.mcu.getDeviationInfo())
 
 
     def get_mcu_deviation_info(self, data):
     def get_mcu_deviation_info(self, data):
         if "_type" not in data:
         if "_type" not in data:

+ 76 - 32
python/mcu/ProgramItem.py

@@ -1,3 +1,4 @@
+import asyncio
 import json
 import json
 import os
 import os
 
 
@@ -7,24 +8,39 @@ import time
 from .capture.module_digicam import DigiCam
 from .capture.module_digicam import DigiCam
 from .capture.module_watch_dog import FileEventHandler
 from .capture.module_watch_dog import FileEventHandler
 
 
+
 class ProgramItem(BaseClass):
 class ProgramItem(BaseClass):
     # program_sign = Signal(dict)
     # program_sign = Signal(dict)
     # program_refresh_photo_list_sign = Signal()
     # program_refresh_photo_list_sign = Signal()
 
 
-    def __init__(self,websocket_manager, action_data:any, mcu, goods_art_no:str=None,image_index:int=-1):
+    def __init__(
+        self,
+        websocket_manager,
+        action_data: any,
+        mcu,
+        goods_art_no: str = None,
+        image_index: int = -1,
+        record_id: int = -1,
+        smart_shooter=None,
+    ):
         super().__init__(BaseClass)
         super().__init__(BaseClass)
         # 1 表示等待中,2表示没有等待
         # 1 表示等待中,2表示没有等待
         self.wait_state = 2
         self.wait_state = 2
         self.msg_type = "mcu"
         self.msg_type = "mcu"
         print("action_data====>", action_data)
         print("action_data====>", action_data)
         self.data = action_data
         self.data = action_data
-        self.capture_one = DigiCam()
-        captrure_folder_path = self.capture_one.getCaptureFolderPath()
-        self.watch_dog = FileEventHandler()
-        self.watch_dog.goods_art_no = goods_art_no
-        self.watch_dog.image_index = image_index
-        self.watch_dog.mcu = mcu
-        self.watch_dog.start_observer(captrure_folder_path)
+        print("ProgramItem smart_shooter", smart_shooter)
+        self.smart_shooter = smart_shooter
+        if smart_shooter == None:
+            self.capture_one = DigiCam()
+            captrure_folder_path = self.capture_one.getCaptureFolderPath()
+            self.watch_dog = FileEventHandler()
+            self.watch_dog.goods_art_no = goods_art_no
+            self.watch_dog.image_index = image_index
+            self.watch_dog.mcu = mcu
+            self.watch_dog.start_observer(captrure_folder_path)
+        else:
+            print("使用smart_shooter")
         print("21 =========ProgramItem=======action_data=====")
         print("21 =========ProgramItem=======action_data=====")
         print(action_data)
         print(action_data)
         self.action_id = self.get_value(action_data, "id")
         self.action_id = self.get_value(action_data, "id")
@@ -51,6 +67,7 @@ class ProgramItem(BaseClass):
 
 
         self.last_photograph_time = None  # 最近一次拍照时间
         self.last_photograph_time = None  # 最近一次拍照时间
         self.goods_art_no = goods_art_no  # 货号
         self.goods_art_no = goods_art_no  # 货号
+        self.record_id = record_id  # 货号
 
 
         self.set_other()
         self.set_other()
         self.error_info_text = ""  # 错误提示信息
         self.error_info_text = ""  # 错误提示信息
@@ -93,7 +110,7 @@ class ProgramItem(BaseClass):
         }
         }
         if self.is_wait:
         if self.is_wait:
             msg = "{}--等待".format(self.action_name)
             msg = "{}--等待".format(self.action_name)
-            self.sendSocketMessage(msg=msg,device_status=0)
+            self.sendSocketMessage(msg=msg, device_status=0)
         else:
         else:
             msg = "{}".format(self.action_name)
             msg = "{}".format(self.action_name)
             self.sendSocketMessage(msg=msg, device_status=2)
             self.sendSocketMessage(msg=msg, device_status=2)
@@ -125,24 +142,24 @@ class ProgramItem(BaseClass):
         #     self.ui_retry.setEnabled(True)
         #     self.ui_retry.setEnabled(True)
         #     self.ui_action_name.setToolTip(self.error_info_text)
         #     self.ui_action_name.setToolTip(self.error_info_text)
 
 
-    def check_mcu_move_is_stop(self, re_check=False):
+    async def check_mcu_move_is_stop(self, re_check=False):
         self.error_info_text = ""
         self.error_info_text = ""
         # 发送基础数据信息
         # 发送基础数据信息
         # self.mcu.to_get_mcu_base_info()
         # self.mcu.to_get_mcu_base_info()
         _s = time.time()
         _s = time.time()
         last_num_1 = self.mcu.last_mcu_info_data["num"]
         last_num_1 = self.mcu.last_mcu_info_data["num"]
-        self.mcu.cleanAllReceiveData()
+        await self.mcu.cleanAllReceiveData()
         while 1:
         while 1:
             if self.mcu.action_state != 1:
             if self.mcu.action_state != 1:
                 # 外部终止,停止运行
                 # 外部终止,停止运行
                 return False
                 return False
             cr_time = time.time()
             cr_time = time.time()
-            print(cr_time - _s, cr_time,_s)
+            print(cr_time - _s, cr_time, _s)
             if cr_time - _s > 8:
             if cr_time - _s > 8:
                 self.error_info_text = "MCU检测运动未停止,自动退出"
                 self.error_info_text = "MCU检测运动未停止,自动退出"
                 self.set_state(state_value=99)  # 标记异常
                 self.set_state(state_value=99)  # 标记异常
                 print("MCU检测运动未停止,自动退出")
                 print("MCU检测运动未停止,自动退出")
-                self.sendSocketMessage(msg=self.error_info_text,device_status=-1)
+                self.sendSocketMessage(msg=self.error_info_text, device_status=-1)
                 return False
                 return False
                 # return True
                 # return True
             # 存在时间间隙,导致误认为所有设备已完成运动
             # 存在时间间隙,导致误认为所有设备已完成运动
@@ -150,15 +167,15 @@ class ProgramItem(BaseClass):
                 return True
                 return True
             else:
             else:
                 self.mcu.to_get_mcu_base_info()
                 self.mcu.to_get_mcu_base_info()
-                self.mcu.send_all_cmd()
-                time.sleep(0.5)
+                await self.mcu.send_all_cmd()
+                await asyncio.sleep(0.5)
                 self.mcu.get_basic_info_mcu()
                 self.mcu.get_basic_info_mcu()
                 # return True
                 # return True
 
 
-            time.sleep(0.1)
+            await asyncio.sleep(0.1)
             # self.mcu.to_get_mcu_base_info()
             # self.mcu.to_get_mcu_base_info()
 
 
-    def run(self, total_len=5, *args):
+    async def run(self, total_len=5, *args):
         if total_len == 1:
         if total_len == 1:
             self.mode_type = "其他配置"
             self.mode_type = "其他配置"
             self.set_other()
             self.set_other()
@@ -166,12 +183,11 @@ class ProgramItem(BaseClass):
         print("1{}  - is run".format(self.action_name))
         print("1{}  - is run".format(self.action_name))
         self.set_state(state_value=1)
         self.set_state(state_value=1)
         if settings.IS_TEST:
         if settings.IS_TEST:
-            self.do_run()
+            await self.do_run()
         else:
         else:
             try:
             try:
-                self.do_run()
+                await self.do_run()
             except BaseException as e:
             except BaseException as e:
-                # print("p_item 错误:{}".format(e))
                 self.sendSocketMessage(
                 self.sendSocketMessage(
                     msg="p_item 错误:{}".format(e), device_status=-1
                     msg="p_item 错误:{}".format(e), device_status=-1
                 )
                 )
@@ -209,16 +225,21 @@ class ProgramItem(BaseClass):
                 time.sleep(0.1)
                 time.sleep(0.1)
             self.mcu.send_all_cmd()
             self.mcu.send_all_cmd()
 
 
-    def do_run(self, *args):
+    async def do_run(self, *args):
+        await asyncio.sleep(0.001)
         # if not self.goods_art_no:  # and self.action_name != "初始化位置"
         # if not self.goods_art_no:  # and self.action_name != "初始化位置"
         #     return False
         #     return False
         start_time = time.time()
         start_time = time.time()
         # ============连接MCU 处理步进电机与舵机等
         # ============连接MCU 处理步进电机与舵机等
         if settings.IS_MCU:
         if settings.IS_MCU:
-            if self.mode_type != "其他配置" and self.check_mcu_move_is_stop() is False:
+            if self.mode_type != "其他配置" and await self.check_mcu_move_is_stop() is False:
                 # MCU运动是否有停止检查,设定超时时间
                 # MCU运动是否有停止检查,设定超时时间
                 return
                 return
-            print("{} 检查停止时间1:{}".format(self.action_name, time.time() - start_time))
+            print(
+                "{} 检查停止时间1:{}".format(
+                    self.action_name, time.time() - start_time
+                )
+            )
             if self.is_led:
             if self.is_led:
                 self.mcu.to_deal_device(device_name="laser_position", value=1)
                 self.mcu.to_deal_device(device_name="laser_position", value=1)
             else:
             else:
@@ -252,34 +273,57 @@ class ProgramItem(BaseClass):
                 # time.sleep(0.1)
                 # time.sleep(0.1)
 
 
             # MCU运动是否有停止检查,设定超时时间
             # MCU运动是否有停止检查,设定超时时间
-            self.mcu.send_all_cmd()
+            await self.mcu.send_all_cmd()
             if self.mode_type != "其他配置":
             if self.mode_type != "其他配置":
-                time.sleep(1.2)
+                await asyncio.sleep(1.2)
                 print("二次检查")
                 print("二次检查")
-                if self.check_mcu_move_is_stop(re_check=True) is False:
+                if await self.check_mcu_move_is_stop(re_check=True) is False:
                     print("MCU检测运动未停止,自动退出,   提前退出")
                     print("MCU检测运动未停止,自动退出,   提前退出")
                     return
                     return
 
 
         if self.delay_time:
         if self.delay_time:
-            # print("拍照前延时:{}".format(self.delay_time))
-            time.sleep(self.delay_time)
-
+            await asyncio.sleep(self.delay_time)
         if self.is_photograph:
         if self.is_photograph:
-            print("拍照==>", time.time())
             # print("photograph==================")
             # print("photograph==================")
             self.mcu.to_deal_device(device_name="buzzer", times=1)
             self.mcu.to_deal_device(device_name="buzzer", times=1)
             # 用于临时拍照计数
             # 用于临时拍照计数
             is_af = True if self.af_times > 0 else False
             is_af = True if self.af_times > 0 else False
-            self.capture_one.photograph(is_af=is_af)
+            if self.smart_shooter != None:
+                # 拍照
+                print("smart shooter 拍照")
+                record_id = self.record_id
+                goods_art_no = self.goods_art_no
+                if record_id == -1:
+                    goods_art_no = ""
+                print("smart shooter CameraShooter")
+                await self.smart_shooter.CameraShooter(
+                    msg_type="run_mcu",
+                    goods_art_no=goods_art_no,
+                    id=record_id,
+                    is_af=is_af,
+                )
+                print("smart shooter CameraShooter end")
+            else:
+                # 指定自动对焦
+                self.capture_one.photograph(is_af=is_af)
             self.last_photograph_time = time.time()  # 记录最近一次拍照时间
             self.last_photograph_time = time.time()  # 记录最近一次拍照时间
         # print("{} 拍照时间:{}".format(self.action_name, time.time() - start_time))
         # print("{} 拍照时间:{}".format(self.action_name, time.time() - start_time))
         print("{}-{}已完成".format(self.mode_type, self.action_name))
         print("{}-{}已完成".format(self.mode_type, self.action_name))
 
 
         if self.after_delay_time:
         if self.after_delay_time:
             print("拍照后延时:{}".format(self.after_delay_time))
             print("拍照后延时:{}".format(self.after_delay_time))
-            time.sleep(self.after_delay_time)
+            await asyncio.sleep(self.after_delay_time)
         return True
         return True
 
 
+    async def RunSmartShooter(self, goods_art_no,record_id):
+        await asyncio.gather(
+            self.smart_shooter.CameraShooter(
+                msg_type="run_mcu",
+                goods_art_no=goods_art_no,
+                id=record_id,
+            ),
+        )
+
     def rephotograph_one_pic(self, *args):
     def rephotograph_one_pic(self, *args):
         """
         """
         1、获取最近一张照片
         1、获取最近一张照片

+ 53 - 23
python/mcu/RemoteControlV2.py

@@ -3,11 +3,12 @@
 
 
 import json
 import json
 import time, asyncio
 import time, asyncio
+from model import DeviceConfig
 import settings
 import settings
 from .SerialIns import SerialIns
 from .SerialIns import SerialIns
 from .BaseClass import BaseClass
 from .BaseClass import BaseClass
 from sockets.connect_manager import ConnectionManager
 from sockets.connect_manager import ConnectionManager
-from databases import SqlQuery, PhotoRecord, CRUD, insert_photo_records
+from databases import SqlQuery, PhotoRecord,DeviceConfig, CRUD, insert_photo_records
 from .capture.module_digicam import DigiCam
 from .capture.module_digicam import DigiCam
 from .capture.module_watch_dog import FileEventHandler
 from .capture.module_watch_dog import FileEventHandler
 
 
@@ -234,7 +235,7 @@ class RemoteControlV2(BaseClass):
         self.msg_type = "blue_tooth"
         self.msg_type = "blue_tooth"
         self.photo_take_state = 2
         self.photo_take_state = 2
 
 
-    async def handlerTakePhoto(self):
+    async def handlerTakePhoto(self, smart_shooter=None):
         """处理单独拍照"""
         """处理单独拍照"""
         await asyncio.sleep(0.1)
         await asyncio.sleep(0.1)
         print("开始单拍0")
         print("开始单拍0")
@@ -262,30 +263,61 @@ class RemoteControlV2(BaseClass):
                 )
                 )
                 self.msg_type = "blue_tooth"
                 self.msg_type = "blue_tooth"
                 return
                 return
+            deviceConfig = CRUD(DeviceConfig)
+            deviceConfigData = deviceConfig.read(session=session, conditions={"id": record.action_id})
+            select_tab_id = deviceConfigData.tab_id
+            AllTabConfig = deviceConfig.read_all(session=session, conditions={"tab_id": select_tab_id})
+            action_id = 0
+            if AllTabConfig[len(AllTabConfig) - 1].take_picture == True:
+                action_id = AllTabConfig[0].id
+            else:
+                action_id = AllTabConfig[len(AllTabConfig) - 1].id
+            image_index = record.image_index + 1
+            self.photo_take_state = 1
+            deviceConfig = CRUD(DeviceConfig)
+            deviceConfigData = deviceConfig.read(
+                session=session, conditions={"id": record.action_id}
+            )
+            select_tab_id = deviceConfigData.tab_id
+            AllTabConfig = deviceConfig.read_all(
+                session=session, conditions={"tab_id": select_tab_id}
+            )
+            action_id = 0
+            if AllTabConfig[len(AllTabConfig) - 1].take_picture == True:
+                action_id = AllTabConfig[0].id
+            else:
+                action_id = AllTabConfig[len(AllTabConfig) - 1].id
             image_index = record.image_index + 1
             image_index = record.image_index + 1
             self.photo_take_state = 1
             self.photo_take_state = 1
-            insert_photo_records(
+            state, record_id = insert_photo_records(
                 record.image_deal_mode,
                 record.image_deal_mode,
                 record.goods_art_no,
                 record.goods_art_no,
                 image_index,
                 image_index,
-                record.action_id,
+                action_id,
             )
             )
             print("开始单拍1-插入数据")
             print("开始单拍1-插入数据")
-            capture_one = DigiCam()
             try:
             try:
-                watch_dog = FileEventHandler()
-                if watch_dog.observer is None:
-                    captrure_folder_path = capture_one.getCaptureFolderPath()
-                    watch_dog.start_observer(captrure_folder_path)
-                watch_dog.goods_art_no = record.goods_art_no
-                watch_dog.image_index = image_index
-                print("开始单拍1-检查相机")
-                # camera_is_connect = capture_one.checkCameraConnect()
-                # if camera_is_connect is not True:
-                #     self.sendSocketMessage(1, "相机未连接,请检查", device_status=-1)
-                #     return
-                capture_one.run_capture_action("Capture")
-                print("开始单拍1-完成拍照")
+                if smart_shooter == None:
+                    capture_one = DigiCam()
+                    watch_dog = FileEventHandler()
+                    if watch_dog.observer is None:
+                        captrure_folder_path = capture_one.getCaptureFolderPath()
+                        watch_dog.start_observer(captrure_folder_path)
+                    watch_dog.goods_art_no = record.goods_art_no
+                    watch_dog.image_index = image_index
+                    print("开始单拍1-检查相机")
+                    capture_one.run_capture_action("Capture")
+                    print("开始单拍1-完成拍照")
+                else:
+                    loop = asyncio.get_event_loop()
+                    loop.create_task(
+                        smart_shooter.CameraShooter(
+                            msg_type="handler_take_picture",
+                            goods_art_no=record.goods_art_no,
+                            id=record_id,
+                        ),
+                        name="CameraShooter",
+                    )
                 time.sleep(1)
                 time.sleep(1)
                 self.msg_type = "photo_take"
                 self.msg_type = "photo_take"
                 self.sendSocketMessage(
                 self.sendSocketMessage(
@@ -295,12 +327,13 @@ class RemoteControlV2(BaseClass):
                         if record.image_deal_mode == 1
                         if record.image_deal_mode == 1
                         else "执行左脚程序"
                         else "执行左脚程序"
                     ),
                     ),
-                    data={"goods_art_no": record.goods_art_no},
+                    data={"goods_art_no": record.goods_art_no, "id": record_id},
                     device_status=2,
                     device_status=2,
                 )
                 )
                 self.msg_type = "blue_tooth"
                 self.msg_type = "blue_tooth"
             except Exception as e:
             except Exception as e:
-                self.sendSocketMessage(1, "digicam未初始化,请检查", device_status=-1)
+                print(f"错误:{e}")
+                self.sendSocketMessage(1, "处理失败,请重试", device_status=-1)
         self.photo_take_state = 0
         self.photo_take_state = 0
 
 
     async def analysis_received_data(self):
     async def analysis_received_data(self):
@@ -311,11 +344,8 @@ class RemoteControlV2(BaseClass):
             receive_data = self.bluetooth_ins.read_cmd_one(
             receive_data = self.bluetooth_ins.read_cmd_one(
                 address=self.bluetooth_address
                 address=self.bluetooth_address
             )
             )
-            # print("received data", 1)
         else:
         else:
             receive_data = self.serial_ins.read_cmd(out_time=1, check=None)
             receive_data = self.serial_ins.read_cmd(out_time=1, check=None)
-        # print("received data", 2)
-        # print("self.bluetooth_ins", receive_data)
         if receive_data is False:
         if receive_data is False:
             self.connect_state = False
             self.connect_state = False
             return False
             return False

+ 16 - 4
python/mcu/capture/module_watch_dog.py

@@ -10,7 +10,7 @@ from databases import CRUD, SqlQuery, PhotoRecord
 import asyncio
 import asyncio
 
 
 
 
-def updateImageRaw(time_str, image_path, goods_art_no, image_index):
+def updateImageRaw(time_str, image_path, goods_art_no, record_id):
     session = SqlQuery()
     session = SqlQuery()
     crud = CRUD(PhotoRecord)
     crud = CRUD(PhotoRecord)
     res = crud.read(
     res = crud.read(
@@ -18,7 +18,15 @@ def updateImageRaw(time_str, image_path, goods_art_no, image_index):
         conditions={
         conditions={
             "image_path": None,
             "image_path": None,
             "goods_art_no": goods_art_no,
             "goods_art_no": goods_art_no,
-            "image_index": image_index,
+            "id": record_id,
+        },
+    )
+    print(
+        "更新图片数据库======>",
+        {
+            "image_path": image_path,
+            "goods_art_no": goods_art_no,
+            "id": record_id,
         },
         },
     )
     )
     if res:
     if res:
@@ -29,7 +37,7 @@ def updateImageRaw(time_str, image_path, goods_art_no, image_index):
         }
         }
         crud.update(
         crud.update(
             session,
             session,
-            res.id,
+            record_id,
             **update,
             **update,
         )
         )
 
 
@@ -45,6 +53,7 @@ class FileEventHandler(FileSystemEventHandler, metaclass=SingletonType):
         #     self.init_flag = True
         #     self.init_flag = True
         self.goods_art_no = None
         self.goods_art_no = None
         self.image_index = -1
         self.image_index = -1
+        self.record_id = -1
         self.mcu = None
         self.mcu = None
         super().__init__()
         super().__init__()
         # self.window = window
         # self.window = window
@@ -176,7 +185,10 @@ class FileEventHandler(FileSystemEventHandler, metaclass=SingletonType):
                 )
                 )
                 loop.close()
                 loop.close()
                 updateImageRaw(
                 updateImageRaw(
-                    create_time, file_path, self.goods_art_no, self.image_index
+                    create_time,
+                    file_path,
+                    self.goods_art_no,
+                    self.record_id,
                 )
                 )
             except BaseException as e:
             except BaseException as e:
                 print("获取文件create_time失败", e)
                 print("获取文件create_time失败", e)

+ 385 - 0
python/mcu/capture/smart_shooter_class.py

@@ -0,0 +1,385 @@
+import json
+import datetime
+import random
+import zmq
+import asyncio
+from PIL import Image
+from io import BytesIO
+import base64
+import zmq, sys
+from utils.SingletonType import SingletonType
+
+
+# 定义为单例模式,避免被重复实例化
+class SmartShooter(metaclass=SingletonType):
+    SET_REQ = "tcp://127.0.0.1:54544"
+    LISTEN_REQ = "tcp://127.0.0.1:54543"
+
+    def __init__(self, websocket_manager):
+        self.msg_type = "smart_shooter"
+        self.websocket_manager = websocket_manager
+        # 是否停止监听
+        self.stop_listen = False
+        # 相机连接状态
+        self.connect_status = False
+        # 实时预览状态
+        self.perview_state = False
+        self.callback_listen = None
+        self.listen_init = False
+        self.websocket = None
+        # loop = asyncio.get_event_loop()
+        # loop.create_task(
+        #         self.connect_listen(),
+        #         name="connect_listen",
+        #     )
+
+    def __send_tcp_message(self, socket, msg):
+        # await asyncio.sleep(0.01)
+        socket.send_string(json.dumps(msg))
+        rep = socket.recv()
+        str_msg = rep.decode("utf-8")
+        json_msg = json.loads(str_msg)
+        return json_msg
+
+    def __create_req(self, time_out=5) -> tuple[zmq.Socket, zmq.Context]:
+        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(self.SET_REQ)
+        return req_socket, context
+
+    def __create_listen(self) -> tuple[zmq.Socket, zmq.Context]:
+        context = zmq.Context()
+        listen_socket = context.socket(zmq.SUB)
+        listen_socket.setsockopt(zmq.SUBSCRIBE, b"")
+        # 设置发送超时为 5000 毫秒(5 秒)
+        listen_socket.setsockopt(zmq.RCVTIMEO, 4000)
+        # 设置接收超时为 5000 毫秒(5 秒)
+        listen_socket.setsockopt(zmq.SNDTIMEO, 4000)
+        listen_socket.setsockopt(zmq.LINGER, 0)  # 设置为 0 表示不等待未完成的操作
+        listen_socket.connect(self.LISTEN_REQ)
+        return listen_socket, context
+
+    async def GetCameraInfo(self, is_send=True, msg_type=""):
+        await asyncio.sleep(0.01)
+        self.msg_type = msg_type
+        """
+            实时获取相机信息,是否连接、软件是否被打开
+            """
+        socket, context = self.__create_req(time_out=2)
+        try:
+            req = {}
+            req["msg_type"] = "Request"
+            req["msg_id"] = "GetCamera"
+            req["msg_seq_num"] = 0
+            req["CameraSelection"] = "All"
+            json_msg = self.__send_tcp_message(socket, req)
+            msg_result = json_msg.get("msg_result")
+            if not msg_result:
+                self.connect_status = False
+                msg_send = "相机未连接或软件未打开"
+                if is_send:
+                    message = {
+                        "code": 1,
+                        "msg": msg_send,
+                        "data": msg_result,
+                        "msg_type": self.msg_type,
+                        "device_status": -1,
+                    }
+                    await self.websocket_manager.send_personal_message(
+                        message, self.websocket
+                    )
+                return False, msg_send
+            cameraInfo = json_msg.get("CameraInfo")
+            if cameraInfo == None or len(cameraInfo) == 0:
+                self.connect_status = False
+                msg_send = "相机未连接"
+                if is_send:
+                    message = {
+                        "code": 1,
+                        "msg": msg_send,
+                        "data": msg_result,
+                        "msg_type": self.msg_type,
+                        "device_status": -1,
+                    }
+                    await self.websocket_manager.send_personal_message(
+                        message, self.websocket
+                    )
+                return False, "相机未连接"
+            # 链接的相机
+            # connect_camera = cameraInfo
+            CameraStatus = any(
+                item.get("CameraStatus") in ["Ready", "Busy"] for item in cameraInfo
+            )
+            # CameraStatus = connect_camera.get("CameraStatus")
+            if not CameraStatus:
+                self.connect_status = False
+                msg_send = "相机未连接"
+                if is_send:
+                    message = {
+                        "code": 1,
+                        "msg": msg_send,
+                        "data": msg_result,
+                        "msg_type": self.msg_type,
+                        "device_status": -1,
+                    }
+                    await self.websocket_manager.send_personal_message(
+                        message, self.websocket
+                    )
+                return False, msg_send
+            self.connect_status = True
+            msg_send = "相机已连接"
+            if is_send:
+                message = {
+                    "code": 0,
+                    "msg": msg_send,
+                    "data": msg_result,
+                    "msg_type": self.msg_type,
+                    "device_status": 2,
+                }
+                await self.websocket_manager.send_personal_message(
+                    message, self.websocket
+                )
+            return True, "相机已连接"
+        except zmq.Again:
+            print("获取相机信息超时,继续监听...")
+            msg_send = "相机未连接或软件未打开"
+            if is_send:
+                message = {
+                    "code": 1,
+                    "msg": msg_send,
+                    "data": None,
+                    "msg_type": self.msg_type,
+                    "device_status": -1,
+                }
+                await self.websocket_manager.send_personal_message(
+                    message, self.websocket
+                )
+            return False, msg_send
+        except Exception as e:
+            print("拍照异常", e)
+            self.connect_status = False
+            socket.close()
+            context.term()
+            msg_send = "相机未连接或软件未打开"
+            if is_send:
+                message = {
+                    "code": 1,
+                    "msg": msg_send,
+                    "data": None,
+                    "msg_type": self.msg_type,
+                    "device_status": -1,
+                }
+                await self.websocket_manager.send_personal_message(
+                    message, self.websocket
+                )
+            return False, msg_send
+
+    async def EnableCameraPreview(self, enable_status=True, msg_type=""):
+        self.msg_type = msg_type
+        """
+        激活相机预览
+        """
+        camera_states, _ = await self.GetCameraInfo(is_send=False)
+        if not camera_states:
+            return False, "请先连接相机"
+        try:
+            socket, context = self.__create_req()
+            req = {}
+            req["msg_type"] = "Request"
+            req["msg_id"] = "EnableLiveview"
+            req["msg_seq_num"] = 0
+            req["CameraSelection"] = "All"
+            req["Enable"] = enable_status
+            json_msg = self.__send_tcp_message(socket, req)
+            msg_result = json_msg.get("msg_result")
+            if not msg_result:
+                self.perview_state = False
+                msg_send = "预览启用失败"
+                self.sendSocketMessage(
+                    code=0,
+                    msg=msg_send,
+                    device_status=2,
+                )
+                return False, "预览启用失败"
+            msg_send = "预览启用成功" if enable_status else "预览关闭成功"
+            message = {
+                "code": 0,
+                "msg": msg_send,
+                "data": None,
+                "msg_type": self.msg_type,
+                "device_status": 2,
+            }
+            await self.websocket_manager.send_personal_message(message, self.websocket)
+            return True, "预览启用成功" if enable_status else "预览关闭成功"
+        except zmq.Again:
+            print("启动预览超时,继续监听...")
+        except:
+            self.perview_state = False
+            socket.close()
+            context.term()
+            msg_send = "相机未连接或软件未打开"
+            message = {
+                "code": 1,
+                "msg": msg_send,
+                "data": None,
+                "msg_type": self.msg_type,
+                "device_status": -1,
+            }
+            await self.websocket_manager.send_personal_message(message, self.websocket)
+            return False, "相机未连接或软件未打开"
+
+    async def CameraAutofocus(self):
+        """
+        相机自动对焦
+        """
+        camera_states, _ = await self.GetCameraInfo(is_send=False)
+        print("CameraAutofocus 执行对焦")
+        if not camera_states:
+            return False, "请先连接相机"
+        try:
+            socket, context = self.__create_req()
+            req = {}
+            req["msg_type"] = "Request"
+            req["msg_id"] = "Autofocus"
+            req["msg_seq_num"] = 0
+            req["CameraSelection"] = "All"
+            json_msg = self.__send_tcp_message(socket, req)
+            print("json_msg", json_msg)
+            msg_result = json_msg.get("msg_result")
+            if not msg_result:
+                return False, "对焦失败"
+            return True, "对焦成功"
+        except zmq.Again:
+            print("对焦超时,继续监听...")
+        except:
+            socket.close()
+            context.term()
+            return False, "相机未连接或软件未打开"
+
+    async def CameraShooter(self, msg_type="", goods_art_no="", id=0, is_af=False):
+        # 对焦混用
+        if is_af:
+            await self.CameraAutofocus()
+        self.msg_type = msg_type
+        print("camera_states", msg_type)
+        """
+        执行拍照
+        """
+        camera_states, _ = await self.GetCameraInfo(is_send=True)
+        print("camera_states CameraShooter", camera_states)
+        if not camera_states:
+            return False, "请先连接相机"
+        try:
+            socket, context = self.__create_req()
+            req = {}
+            req["msg_type"] = "Request"
+            req["msg_id"] = "Shoot"
+            req["msg_seq_num"] = 1
+            req["CameraSelection"] = "All"
+            if goods_art_no != "" and id != 0:
+                # 此处用逗号分割,货号和id,需要在监听部分进行切割保存处理,如果使用下划线或者减号,可能货号中存在对应符号
+                req["PhotoOrigin"] = f"{goods_art_no},{id}"
+            else:
+                req["PhotoOrigin"] = ""
+            json_msg = self.__send_tcp_message(socket, req)
+            print("CameraShooter", json_msg)
+            msg_result = json_msg.get("msg_result")
+            if not msg_result:
+                msg_send = "拍照失败"
+                message = {
+                    "code": 1,
+                    "msg": msg_send,
+                    "data": None,
+                    "msg_type": self.msg_type,
+                    "device_status": -1,
+                }
+                await self.websocket_manager.send_personal_message(
+                    message, self.websocket
+                )
+                return False, msg_send
+            msg_send = "拍照成功"
+            message = {
+                "code": 0,
+                "msg": msg_send,
+                "data": None,
+                "msg_type": self.msg_type,
+                "device_status": 2,
+            }
+            msg_send = "相机未连接或软件未打开"
+            message = {
+                "code": 1,
+                "msg": msg_send,
+                "data": None,
+                "msg_type": self.msg_type,
+                "device_status": -1,
+            }
+            await self.websocket_manager.send_personal_message(message, self.websocket)
+            return True, "拍照成功"
+        except zmq.Again:
+            msg_send = "相机未连接或软件未打开"
+            message = {
+                "code": 1,
+                "msg": msg_send,
+                "data": {goods_art_no: goods_art_no, "id": id},
+                "msg_type": self.msg_type,
+                "device_status": -1,
+            }
+            await self.websocket_manager.send_personal_message(message, self.websocket)
+            return True, "拍照失败"
+        except:
+            socket.close()
+            context.term()
+            msg_send = "相机未连接或软件未打开"
+            message = {
+                "code": 1,
+                "msg": msg_send,
+                "data": None,
+                "msg_type": self.msg_type,
+                "device_status": -1,
+            }
+            await self.websocket_manager.send_personal_message(message, self.websocket)
+            return False, msg_send
+
+    async def connect_listen(self):
+        print("smart shooter connect_listen", self.connect_status, self.listen_init)
+        if self.connect_status == True or self.listen_init == True:
+            return True
+        # 发起监听
+        sub_socket, context = self.__create_listen()
+        print("构建监听", self.connect_status)
+        while True:
+            self.listen_init = True
+            await asyncio.sleep(0.01)
+            if self.callback_listen == None:
+                continue
+            camera_states, camera_msg = await self.GetCameraInfo(is_send=False)
+            if not camera_states:
+                print("相机未连接")
+                await asyncio.sleep(0.01)  # 等待相机连接
+                continue
+            if self.stop_listen:
+                break
+            try:
+                self.connect_status = True
+                raw = sub_socket.recv()
+                str_msg = raw.decode("utf-8")
+                json_msg = json.loads(str_msg)
+                if json_msg["msg_id"] == "NetworkPing":
+                    continue
+                await self.callback_listen(json_msg)
+            except zmq.Again:
+                print("接收超时,继续监听...")
+                continue
+            except Exception as e:
+                self.connect_status = False
+                print(f"发生错误: {e}")
+                break
+        self.listen_init = False
+        sub_socket.close()
+        context.term()
+        print("smart shooter连接断开")

+ 7 - 0
python/models.py

@@ -110,3 +110,10 @@ class LogoParamsupdate(BaseModel):
 class DeviceConfigTabsReq(BaseModel):
 class DeviceConfigTabsReq(BaseModel):
     id: int = Field(default=None, primary_key=True)
     id: int = Field(default=None, primary_key=True)
     mode_name: str = Field(default="", description="Tab名称")
     mode_name: str = Field(default="", description="Tab名称")
+
+
+class RecordUpdate(BaseModel):
+    """系统配置"""
+
+    id: int = Field(default=0, description="记录id")
+    image_path: str = Field(default=None, description="图片地址")

+ 13 - 10
python/service/OnePicTest.py

@@ -46,10 +46,13 @@ class OnePicTest():
         check_path("temp")
         check_path("temp")
         check_path("temp\pic_test")
         check_path("temp\pic_test")
         root = r"{}\temp\pic_test".format(os.getcwd())
         root = r"{}\temp\pic_test".format(os.getcwd())
-        for file_name in os.listdir(root):
-            path = "{}\{}".format(root, file_name)
-            if os.path.isfile(path):
-                os.remove(path)
+        try:
+            for file_name in os.listdir(root):
+                path = "{}\{}".format(root, file_name)
+                if os.path.isfile(path):
+                    os.remove(path)
+        except Exception as e:
+            print("deal_image", e)
 
 
         # ==============抠图处理=====================
         # ==============抠图处理=====================
         remove_pic_ins = RemoveBgALi()
         remove_pic_ins = RemoveBgALi()
@@ -66,8 +69,8 @@ class OnePicTest():
         print("image_path", image_path)
         print("image_path", image_path)
         print("cut_image_path", cut_image_path)
         print("cut_image_path", cut_image_path)
         print("main_out_path", main_out_path)
         print("main_out_path", main_out_path)
-        try:
-            GeneratePic().run(
+        # try:
+        GeneratePic().run(
                     image_path=image_path,
                     image_path=image_path,
                     cut_image_path=cut_image_path,
                     cut_image_path=cut_image_path,
                     out_path=main_out_path,
                     out_path=main_out_path,
@@ -76,9 +79,9 @@ class OnePicTest():
                     out_pic_size=1024,
                     out_pic_size=1024,
                     is_logo=False,
                     is_logo=False,
             )
             )
-        except Exception as e:
-            print(e)
-            raise UnicornException("处理失败,请重试")
+        # except Exception as e:
+        #     print(e)
+        #     raise UnicornException("处理失败,请重试")
 
 
         # return_data["code"] = 0
         # return_data["code"] = 0
         # return_data["data"]["image_path"] = image_path
         # return_data["data"]["image_path"] = image_path
@@ -91,7 +94,7 @@ class OnePicTest():
         if not os.path.exists(self.pic_path):
         if not os.path.exists(self.pic_path):
             raise UnicornException("图片不存在")
             raise UnicornException("图片不存在")
         image_pth = Image.open(self.pic_path)
         image_pth = Image.open(self.pic_path)
-        if image_pth.mode != "RGB":
+        if image_pth.mode == "RGBA":
             raise UnicornException("抠图图片不能是PNG")
             raise UnicornException("抠图图片不能是PNG")
         return_data = self.deal_image(self.pic_path)
         return_data = self.deal_image(self.pic_path)
         # if return_data["message"]:
         # if return_data["message"]:

+ 7 - 4
python/service/generate_main_image/grenerate_main_image_test.py

@@ -402,11 +402,14 @@ class GeneratePic(object):
         print("242  need_time_1:{}".format(time.time() - _s))
         print("242  need_time_1:{}".format(time.time() - _s))
 
 
         orign_x, orign_y = orign_im.size
         orign_x, orign_y = orign_im.size
-        time.sleep(1)
+        time.sleep(3)
         cut_image = Image.open(cut_image_path)  # 原始图的已扣图
         cut_image = Image.open(cut_image_path)  # 原始图的已扣图
-        cut_image, new_box = get_mini_crop_img(img=cut_image)
-        im_shadow = orign_im.crop(new_box)  # 切图
-        new_x, new_y = im_shadow.size
+        try:
+            cut_image, new_box = get_mini_crop_img(img=cut_image)
+            im_shadow = orign_im.crop(new_box)  # 切图
+            new_x, new_y = im_shadow.size
+        except:
+            im_shadow = cut_image
 
 
         # ================自动色阶处理
         # ================自动色阶处理
         _s = time.time()
         _s = time.time()

+ 1 - 3
python/sockets/connect_manager.py

@@ -26,14 +26,12 @@ class ConnectionManager:
 
 
     async def send_personal_message(self, message: str, websocket: WebSocket):
     async def send_personal_message(self, message: str, websocket: WebSocket):
         '''向用户发送消息'''
         '''向用户发送消息'''
-        print("ready message successfully")
         await websocket.send_json(message)
         await websocket.send_json(message)
-        print("sent message successfully")
 
 
     async def broadcast(self, message: str):
     async def broadcast(self, message: str):
         """广播消息"""
         """广播消息"""
         for connection in self.active_connections:
         for connection in self.active_connections:
             if connection.client_state == WebSocketState.DISCONNECTED:
             if connection.client_state == WebSocketState.DISCONNECTED:
                 continue
                 continue
-            print("connection", connection.client_state)
+            print("正在发送广播消息", "message", connection.client_state)
             await connection.send_json(message)
             await connection.send_json(message)

+ 162 - 51
python/sockets/message_handler.py

@@ -5,10 +5,33 @@ from mcu.DeviceControl import DeviceControl, checkMcuConnection
 from mcu.BlueToothMode import BlueToothMode
 from mcu.BlueToothMode import BlueToothMode
 from databases import DeviceConfig, SqlQuery, CRUD, PhotoRecord, SysConfigs
 from databases import DeviceConfig, SqlQuery, CRUD, PhotoRecord, SysConfigs
 from mcu.capture.module_digicam import DigiCam
 from mcu.capture.module_digicam import DigiCam
+from mcu.capture.smart_shooter_class import SmartShooter
+from models import RecordUpdate
+from sqlalchemy.exc import NoResultFound
+import os, datetime
+
+async def updateDataRecord(PhotoFilename, id):
+    await asyncio.sleep(0.01)
+    create_time = datetime.datetime.fromtimestamp(os.path.getctime(PhotoFilename))
+    data = {"id": id, "image_path": PhotoFilename, "photo_create_time": create_time}
+    # record_model = PhotoRecord(**data)
+    session = SqlQuery()
+    record_model = CRUD(PhotoRecord)
+    model = record_model.read(session, conditions={"id": id})
+    if model == None:
+        print(f"smart shooter 拍照记录更新失败,记录id:{id},不存在")
+    else:
+        # 走编辑逻辑
+        record_model.updateConditions(session, conditions={"id": id}, **data)
+        print(f"smart shooter 拍照记录更新成功,记录id:{id}")
+
 
 
 # socket消息发送逻辑处理方法
 # socket消息发送逻辑处理方法
 async def handlerSend(
 async def handlerSend(
-    manager: ConnectionManager, receiveData: str, websocket: WebSocket
+    manager: ConnectionManager,
+    receiveData: str,
+    websocket: WebSocket,
+    smart_shooter: SmartShooter,
 ):
 ):
     loop = asyncio.get_event_loop()
     loop = asyncio.get_event_loop()
     receiveData = json.loads(receiveData)
     receiveData = json.loads(receiveData)
@@ -18,8 +41,50 @@ async def handlerSend(
     code = receiveData.get("code")
     code = receiveData.get("code")
     msg = receiveData.get("msg")
     msg = receiveData.get("msg")
     data = receiveData.get("data")
     data = receiveData.get("data")
-    print("receiveData", receiveData)
-    print("jsonType", jsonType)
+
+    async def MsgCallback(msg):
+        msg_id = msg.get("msg_id")
+        match msg_id:
+            case "PhotoUpdated":
+                PhotoFilename = msg.get("PhotoFilename")
+                PhotoLocation = msg.get("PhotoLocation")
+                PhotoOrigin = msg.get("PhotoOrigin")
+                if (PhotoFilename != "" and PhotoFilename != None) and (
+                    PhotoLocation == "Local Disk"
+                ):
+                    # temp_photo_name = PhotoFilename
+                    # 更新拍照记录
+                    print("PhotoFilename", PhotoFilename, PhotoOrigin)
+                    if PhotoOrigin != "" and PhotoOrigin != "external":
+                        goods_art_no, id = PhotoOrigin.split(",")
+                        loop.create_task(
+                            updateDataRecord(PhotoFilename, id), name="PhotoFilename"
+                        )
+                    data = manager.jsonMessage(
+                        code=0,
+                        msg=f"照片获取成功",
+                        data={"photo_file_name": PhotoFilename},
+                        msg_type="smart_shooter_photo_take",
+                    )
+                    await manager.send_personal_message(data, websocket)
+            case "LiveviewUpdated":
+                CameraLiveviewImage = msg.get("CameraLiveviewImage", None)
+                # base64_to_image(CameraLiveviewImage, "liveview.jpg")
+                # print("收到直播画面:CameraLiveviewImage")
+                data = manager.jsonMessage(
+                    code=1,
+                    msg=f"预览数据发送",
+                    data={"smart_shooter_preview": CameraLiveviewImage},
+                    msg_type="smart_shooter_enable_preview",
+                )
+                await manager.send_personal_message(data, websocket)
+
+    # 构建监听条件
+    smart_shooter.callback_listen = MsgCallback
+    loop.create_task(
+        smart_shooter.connect_listen(),
+        name="smart_shooter_connect_listen",
+    )
     match jsonType:
     match jsonType:
         case "ping":
         case "ping":
             """发送心跳"""
             """发送心跳"""
@@ -30,10 +95,12 @@ async def handlerSend(
             pass
             pass
         case "forward_message":
         case "forward_message":
             data = receiveData.get("data")
             data = receiveData.get("data")
-            dictMsg = {"code":code,"msg":msg,"data":data}
+            dictMsg = {"code": code, "msg": msg, "data": data}
             await manager.broadcast(dictMsg)
             await manager.broadcast(dictMsg)
         case "connect_mcu":
         case "connect_mcu":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             device_ctrl.mcu_exit = False
             device_ctrl.mcu_exit = False
             # if device_ctrl.serial_ins.check_connect():
             # if device_ctrl.serial_ins.check_connect():
             #     print("未连接")
             #     print("未连接")
@@ -46,9 +113,11 @@ async def handlerSend(
             loop.create_task(blue_tooth.main_func(), name="blue_tooth")
             loop.create_task(blue_tooth.main_func(), name="blue_tooth")
             # loop.close()
             # loop.close()
         case "init_mcu":
         case "init_mcu":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             # 是否强制初始化
             # 是否强制初始化
-            is_force_init = data.get("value",False)
+            is_force_init = data.get("value", False)
             loop.create_task(device_ctrl.initDevice(is_force_init), name="init_mcu")
             loop.create_task(device_ctrl.initDevice(is_force_init), name="init_mcu")
         case "control_mcu":
         case "control_mcu":
             device_name = data.get("device_name")
             device_name = data.get("device_name")
@@ -56,15 +125,17 @@ async def handlerSend(
             if (device_name == "" or device_name == None) or (
             if (device_name == "" or device_name == None) or (
                 value == "" or value == None
                 value == "" or value == None
             ):
             ):
-                data = manager.jsonMessage(
-                    code=1, msg="参数错误", msg_type="mcu"
-                )
+                data = manager.jsonMessage(code=1, msg="参数错误", msg_type="mcu")
                 await manager.send_personal_message(data, websocket)
                 await manager.send_personal_message(data, websocket)
                 return
                 return
-            device_ctrl = DeviceControl(websocket_manager=manager)
-            device_ctrl.controlDevice(device_name, value)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
+            await device_ctrl.controlDevice(device_name, value)
         case "stop_action":
         case "stop_action":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             if device_ctrl.is_runn_action == True:
             if device_ctrl.is_runn_action == True:
                 print("动作执行中,停止")
                 print("动作执行中,停止")
                 device_ctrl.is_stop_action = True
                 device_ctrl.is_stop_action = True
@@ -74,7 +145,7 @@ async def handlerSend(
             msg_type = "run_mcu"
             msg_type = "run_mcu"
             action_info = data.get("action", "执行左脚程序")
             action_info = data.get("action", "执行左脚程序")
             goods_art_no = data.get("goods_art_no", None)
             goods_art_no = data.get("goods_art_no", None)
-            if goods_art_no == None or goods_art_no =="":
+            if goods_art_no == None or goods_art_no == "":
                 # 判断货号是否存在
                 # 判断货号是否存在
                 data = manager.jsonMessage(
                 data = manager.jsonMessage(
                     code=1, msg="goods_art_no不能为空", msg_type=msg_type
                     code=1, msg="goods_art_no不能为空", msg_type=msg_type
@@ -92,7 +163,9 @@ async def handlerSend(
                 action_flag = "right"
                 action_flag = "right"
             tab_id = action_configs_json.get(action_flag)
             tab_id = action_configs_json.get(action_flag)
             photoRecord = CRUD(PhotoRecord)
             photoRecord = CRUD(PhotoRecord)
-            goods_art_record = photoRecord.read(session,conditions={"goods_art_no": goods_art_no})
+            goods_art_record = photoRecord.read(
+                session, conditions={"goods_art_no": goods_art_no}
+            )
             if goods_art_record != None:
             if goods_art_record != None:
                 data = manager.jsonMessage(
                 data = manager.jsonMessage(
                     code=1,
                     code=1,
@@ -112,42 +185,35 @@ async def handlerSend(
                 await manager.send_personal_message(data, websocket, msg_type=msg_type)
                 await manager.send_personal_message(data, websocket, msg_type=msg_type)
                 return
                 return
             action_list = [device.model_dump() for device in all_devices]
             action_list = [device.model_dump() for device in all_devices]
-            print("action_list", action_list)
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            print("handl send smart_shooter", smart_shooter)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
-                device_ctrl.run_mcu_config(action_list, goods_art_no, action_info),
+                device_ctrl.run_mcu_config(
+                    action_list, goods_art_no, action_info, smart_shooter
+                ),
                 name="run_mcu_config",
                 name="run_mcu_config",
             )
             )
         case "run_mcu_single":
         case "run_mcu_single":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
-                device_ctrl.run_mcu_config_single(data, None, "run_mcu_single"),
+                device_ctrl.run_mcu_config_single(
+                    data, None, "run_mcu_single", -1, smart_shooter
+                ),
                 name="run_mcu_single",
                 name="run_mcu_single",
             )
             )
         case "handler_take_picture":
         case "handler_take_picture":
-            blue_tooth = BlueToothMode(websocket_manager=manager)
+            blue_tooth = BlueToothMode(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
-                blue_tooth.remote_control_v2.handlerTakePhoto(),
+                blue_tooth.remote_control_v2.handlerTakePhoto(smart_shooter),
                 name="run_mcu_config",
                 name="run_mcu_config",
             )
             )
-        case "re_take_picture":#重拍
-            # try:
-            #     # 判断拍照软件是否初始化
-            #     digicam = DigiCam()
-            #     camera_is_connect = digicam.checkCameraConnect()
-            #     if camera_is_connect is not True:
-            #         data = manager.jsonMessage(
-            #             code=1, msg="相机未连接,请检查", msg_type=msg_type
-            #         )
-            #         await manager.send_personal_message(data, websocket)
-            #         return
-            #     digicam.getCaptureFolderPath()
-            # except:
-            #     data = manager.jsonMessage(
-            #         code=1, msg="digicam未初始化,请检查", msg_type=msg_type
-            #     )
-            #     await manager.send_personal_message(data, websocket)
-            #     return
+        case "re_take_picture":  # 重拍
             msg_type = "re_take_picture"
             msg_type = "re_take_picture"
             record_id = data.get("record_id")
             record_id = data.get("record_id")
             session = SqlQuery()
             session = SqlQuery()
@@ -166,32 +232,42 @@ async def handlerSend(
             image_index = goods_art_record.image_index
             image_index = goods_art_record.image_index
             crud = CRUD(DeviceConfig)
             crud = CRUD(DeviceConfig)
             condtions = {"id": action_id}
             condtions = {"id": action_id}
-            device_action = crud.read(
-                session, conditions=condtions
-            )
+            device_action = crud.read(session, conditions=condtions)
             if device_action == None:
             if device_action == None:
                 # 判断是否有可用配置
                 # 判断是否有可用配置
                 data = manager.jsonMessage(code=1, msg="当前没有可用配置")
                 data = manager.jsonMessage(code=1, msg="当前没有可用配置")
                 await manager.send_personal_message(data, websocket, msg_type=msg_type)
                 await manager.send_personal_message(data, websocket, msg_type=msg_type)
                 return
                 return
+            print("device_action", device_action)
             # 清除图片记录,执行重拍
             # 清除图片记录,执行重拍
             reset_data = {"image_path": None}
             reset_data = {"image_path": None}
             photoRecord.update(session, record_id, **reset_data)
             photoRecord.update(session, record_id, **reset_data)
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
                 device_ctrl.run_mcu_config_single(
                 device_ctrl.run_mcu_config_single(
-                    device_action.model_dump(), goods_art_no, msg_type=msg_type,image_index=image_index
+                    device_action.model_dump(),
+                    goods_art_no,
+                    msg_type=msg_type,
+                    image_index=image_index,
+                    smart_shooter=smart_shooter,
+                    action_id=record_id,
                 ),
                 ),
                 name="run_mcu_config_single",
                 name="run_mcu_config_single",
             )
             )
         case "get_deviation":
         case "get_deviation":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
                 device_ctrl.getDeviationInfo(),
                 device_ctrl.getDeviationInfo(),
                 name="get_deviation",
                 name="get_deviation",
             )
             )
         case "set_deviation":
         case "set_deviation":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             value = data.get("value", None)
             value = data.get("value", None)
             action_name = data.get("action_name", None)
             action_name = data.get("action_name", None)
             loop.create_task(
             loop.create_task(
@@ -199,7 +275,9 @@ async def handlerSend(
                 name="set_deviation",
                 name="set_deviation",
             )
             )
         case "move_deviation":
         case "move_deviation":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             value = data.get("value", None)
             value = data.get("value", None)
             action_name = data.get("action_name", None)
             action_name = data.get("action_name", None)
             loop.create_task(
             loop.create_task(
@@ -207,23 +285,56 @@ async def handlerSend(
                 name="move_deviation",
                 name="move_deviation",
             )
             )
         case "get_mcu_other_info":
         case "get_mcu_other_info":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
                 device_ctrl.getMcuOtherInfo(),
                 device_ctrl.getMcuOtherInfo(),
                 name="mcu_other_set_get",
                 name="mcu_other_set_get",
             )
             )
         case "set_mcu_other_info":
         case "set_mcu_other_info":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
                 device_ctrl.setMcuOtherInfo(data),
                 device_ctrl.setMcuOtherInfo(data),
                 name="setMcuOtherInfo",
                 name="setMcuOtherInfo",
             )
             )
         case "send_command":
         case "send_command":
-            device_ctrl = DeviceControl(websocket_manager=manager)
+            device_ctrl = DeviceControl(
+                websocket_manager=manager, smart_shooter=smart_shooter
+            )
             loop.create_task(
             loop.create_task(
                 device_ctrl.sendCommand(data.get("command", None)),
                 device_ctrl.sendCommand(data.get("command", None)),
                 name="sendCommand",
                 name="sendCommand",
             )
             )
+        case "smart_shooter_getinfo":
+            """
+            获取相机信息,是否连接
+            """
+            loop.create_task(
+                smart_shooter.GetCameraInfo(msg_type="smart_shooter_getinfo"),
+                name="smart_shooter_getinfo",
+            )
+        case "smart_shooter_enable_preview":
+            """
+            启动相机或关闭实时预览
+            """
+            value = data.get("value", True)
+            loop.create_task(
+                smart_shooter.EnableCameraPreview(
+                    enable_status=value, msg_type="smart_shooter_enable_preview"
+                ),
+                name="smart_shooter_enable_preview",
+            )
+        case "smart_shooter_photo_take":
+            """
+            获取相机信息,是否连接
+            """
+            loop.create_task(
+                smart_shooter.CameraShooter(msg_type="smart_shooter_photo_take"),
+                name="smart_shooter_photo_take",
+            )
         case _:
         case _:
             data = manager.jsonMessage(code=1, msg="未知消息")
             data = manager.jsonMessage(code=1, msg="未知消息")
             await manager.send_personal_message(data, websocket)
             await manager.send_personal_message(data, websocket)

+ 7 - 2
python/sockets/socket_server.py

@@ -5,18 +5,20 @@ from .connect_manager import ConnectionManager
 from .message_handler import *
 from .message_handler import *
 from mcu.DeviceControl import DeviceControl,checkMcuConnection
 from mcu.DeviceControl import DeviceControl,checkMcuConnection
 from mcu.BlueToothMode import BlueToothMode
 from mcu.BlueToothMode import BlueToothMode
+from mcu.capture.smart_shooter_class import SmartShooter
 import time
 import time
 from .socket_client import socket_manager
 from .socket_client import socket_manager
 conn_manager = ConnectionManager()
 conn_manager = ConnectionManager()
 active_connections = set()
 active_connections = set()
 device_ctrl = DeviceControl(websocket_manager=conn_manager)
 device_ctrl = DeviceControl(websocket_manager=conn_manager)
 blue_tooth = BlueToothMode(websocket_manager=conn_manager)
 blue_tooth = BlueToothMode(websocket_manager=conn_manager)
+smart_shooter = SmartShooter(websocket_manager=conn_manager)
 from utils.common import message_queue
 from utils.common import message_queue
 @app.websocket("/ws")
 @app.websocket("/ws")
 async def websocket_endpoint(websocket: WebSocket):
 async def websocket_endpoint(websocket: WebSocket):
     await conn_manager.connect(websocket)
     await conn_manager.connect(websocket)
     active_connections.add(websocket)
     active_connections.add(websocket)
-
+    smart_shooter.websocket = websocket
     try:
     try:
         # await socket_manager.connect()
         # await socket_manager.connect()
         async def handler_messages():
         async def handler_messages():
@@ -25,6 +27,7 @@ async def websocket_endpoint(websocket: WebSocket):
                     byteDats = await websocket.receive()
                     byteDats = await websocket.receive()
                     socket_type = byteDats.get("type")
                     socket_type = byteDats.get("type")
                     if socket_type == "websocket.disconnect":
                     if socket_type == "websocket.disconnect":
+                        smart_shooter.stop_listen = True
                         device_ctrl.close_connect()
                         device_ctrl.close_connect()
                         device_ctrl.mcu_exit = True
                         device_ctrl.mcu_exit = True
                         device_ctrl.clearMyInstance()
                         device_ctrl.clearMyInstance()
@@ -42,7 +45,9 @@ async def websocket_endpoint(websocket: WebSocket):
                         blue_tooth.clearMyInstance()
                         blue_tooth.clearMyInstance()
                         break
                         break
                     print("byteDats", byteDats)
                     print("byteDats", byteDats)
-                    await handlerSend(conn_manager, json.dumps(byteDats), websocket)
+                    await handlerSend(
+                        conn_manager, json.dumps(byteDats), websocket, smart_shooter
+                    )
                 except Exception as e:
                 except Exception as e:
                     print(e)
                     print(e)
                     break
                     break