فهرست منبع

feat(mcu): 添加设备控制功能和相机高度限制

- 在 DeviceControl 类中添加 camera_height 属性和 command 命令字典
- 实现 get_device_info 方法获取相机高度信息并更新设备状态
- 将相机高度作为移动命令的最大值限制,防止超出安全范围
- 在消息处理器中添加对 point_name 参数的支持,优化拍照处理
- 更新蓝牙遥控器拍照逻辑,统一使用传入的点名称进行拍摄
- 修复 SmartShooter 类中的消息类型传递问题,改进错误处理
rambo 1 هفته پیش
والد
کامیت
3f250d4f40
5فایلهای تغییر یافته به همراه71 افزوده شده و 80 حذف شده
  1. 5 2
      python/databases.py
  2. 36 22
      python/mcu/DeviceControl.py
  3. 19 49
      python/mcu/RemoteControlV2.py
  4. 6 6
      python/mcu/capture/smart_shooter_class.py
  5. 5 1
      python/sockets/message_handler.py

+ 5 - 2
python/databases.py

@@ -319,6 +319,7 @@ async def insert_photo_records(
 
 
 def auto_add_missing_columns():
+
     """
     自动检测并添加缺失的数据库字段(最简化版本)
     只为 device_config 表添加缺失的字段
@@ -356,12 +357,14 @@ def auto_add_missing_columns():
                     sql = f"ALTER TABLE device_config ADD COLUMN {field_name} {field_type} {default_clause}"
                     cursor.execute(sql)
                     conn.commit()
-                except Exception:
+                except Exception as e:
+                    print(f"⚠️ 添加字段失败: {e}")
                     pass  # 忽略错误,继续下一个
         
         conn.close()
         
-    except Exception:
+    except Exception as e:
+        print(f"⚠️ 添加字段失败: {e}")
         pass  # 静默失败,不影响启动
 
 

+ 36 - 22
python/mcu/DeviceControl.py

@@ -36,8 +36,26 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
         super().__init__(
             websocket_manager=websocket_manager, smart_shooter=smart_shooter
         )
+        self.camera_height = 350
         self.config_manager = None
         self.msg_type = "mcu"
+        self.command = {
+            "to_device_move": 1,  # 设备运动
+            "to_init_device": 2,  # 初始化设备
+            "to_deal_other_device": 3,  # 处理其他设备
+            "get_all_info": 29,  # 获取所有信息
+            "set_deviation": 40,  # 设置偏移量
+            "get_deviation": 41,  # 读取偏移量
+            "signal_forwarding": 91,  # 信号转发处理
+            "signal_forwarding_return": 92,  # 信号转发返回
+            "get_other_info": 44,  # 获取其他信息
+            "open_rgb_led": 43,  ## RGB灯的处理与通讯
+            "set_other_info": 45,  # 设置其他信息
+            "query_remote_control_battery": 47,  # 查询遥控器电量
+            "set_turntable_mode": 48,  # 设置转盘通讯方式 1、串口、2、无线、3 混合
+            "stop_mcu": 93,  # 停止运行mcu
+        }
+        self.serial_ins = None
         self.mcu_deviation_set = McuDeviationSet(self)
         self.mcu_other_set = OtherSet(self)
         self.debug_uart = DebugUart(self)
@@ -62,7 +80,7 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
         self.port_name = ""
         self.mcu_exit = False
         self.t_n = 0
-        self.serial_ins = None
+
         self.connected_ports_dict = {}  # 已连接的ports
         self.p_list = []
         self.temp_ports_dict = {}
@@ -109,22 +127,7 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             "data": {},
         }
 
-        self.command = {
-            "to_device_move": 1,  # 设备运动
-            "to_init_device": 2,  # 初始化设备
-            "to_deal_other_device": 3,  # 处理其他设备
-            "get_all_info": 29,  # 获取所有信息
-            "set_deviation": 40,  # 设置偏移量
-            "get_deviation": 41,  # 读取偏移量
-            "signal_forwarding": 91,  # 信号转发处理
-            "signal_forwarding_return": 92,  # 信号转发返回
-            "get_other_info": 44,  # 获取其他信息
-            "open_rgb_led": 43,  ## RGB灯的处理与通讯
-            "set_other_info": 45,  # 设置其他信息
-            "query_remote_control_battery": 47,  # 查询遥控器电量
-            "set_turntable_mode": 48,  # 设置转盘通讯方式 1、串口、2、无线、3 混合
-            "stop_mcu": 93,  # 停止运行mcu
-        }
+
         # self.window = window
         self.last_push_time = defaultdict(float)
         self.is_running = False
@@ -156,16 +159,26 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             return False
         cmd = [124]
         cmd.extend([0xff & 106 >> 8, 0xff & 106])
-        print("get_device_info cmd",cmd)
+        # print("get_device_info cmd",cmd)
         data = self.get_basic_info_mcu_without_async(data=cmd)
-        print("get_device_info====>",data)
+        # print("get_device_info====>",data)
         if not data:
             return False
         return_data = self.analysis_data(data[1:])
         if return_data:
-            print("get_device_info====>",return_data)
+            camera_height = return_data.get('value',35)
+            self.camera_height = camera_height
         else:
-            print("get_device_info====>","数据不存在")
+            self.camera_height = 350
+        self.msg_type = 'get_device_info'
+        self.sendSocketMessage(
+            code=0,
+            msg="设置mcu其他配置信息完成",
+            device_status=2,
+            data={"camera_height":self.camera_height}
+        )
+        self.msg_type = 'mcu'
+        return self.camera_height
     # 获取异步数据
     def analysis_data(self, _data):
         _addr = _data[0] << 8 | _data[1]
@@ -1500,7 +1513,8 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                     else down_speed
                 )
                 value = value / 10  # value 单位毫米
-                assert 0 <= value <= 40
+                max_camera_hight = self.camera_height/10
+                assert 0 <= value <= max_camera_hight
                 assert 0 <= max_speed <= 10000
             case "camera_steering":
                 # 角度为度 未放大 精确到0.1度

+ 19 - 49
python/mcu/RemoteControlV2.py

@@ -234,7 +234,7 @@ class RemoteControlV2(BaseClass):
         self.msg_type = "blue_tooth"
         self.photo_take_state = 2
 
-    async def handlerTakePhoto(self, smart_shooter=None,session=None,record=None):
+    async def handlerTakePhoto(self, smart_shooter=None,session=None,record=None,PointName="A"):
         """处理单独拍照"""
         await asyncio.sleep(0.1)
         print("开始单拍1")
@@ -248,16 +248,6 @@ class RemoteControlV2(BaseClass):
             )
             self.msg_type = "blue_tooth"
             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(
@@ -273,54 +263,34 @@ class RemoteControlV2(BaseClass):
             )
             self.msg_type = "blue_tooth"
             return
-        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
         state, record_id = await insert_photo_records(
             record.image_deal_mode,
             record.goods_art_no,
             image_index,
-            action_id,
+            record.action_id,
         )
         session.close()
         print("开始单拍1-插入数据")
         try:
-            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:
-                camera_configs = settings.getSysConfigs(
-                    "camera_configs",
-                    "iso_config",
-                    None,
-                )
-                CameraKey = camera_configs[record.point_name].get("CameraKey", None)
-                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,
-                        CameraKey=CameraKey,
-                    ),
-                    name="CameraShooter",
-                )
+            camera_configs = settings.getSysConfigs(
+                "camera_configs",
+                "iso_config",
+                None,
+            )
+            CameraKey = camera_configs[PointName].get("CameraKey", None)
+            print("单排CameraKey",CameraKey)
+            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,
+                    CameraKey=CameraKey,
+                ),
+                name="CameraShooter",
+            )
             await asyncio.sleep(0.1)
             # await asyncio.sleep(1)
             self.msg_type = "photo_take"

+ 6 - 6
python/mcu/capture/smart_shooter_class.py

@@ -593,7 +593,7 @@ class SmartShooter(metaclass=SingletonType):
                     "code": 1,
                     "msg": msg_send,
                     "data": None,
-                    "msg_type": self.msg_type,
+                    "msg_type": msg_type,
                     "device_status": -1,
                 }
                 await self.sendMessageSocket(message)
@@ -603,19 +603,19 @@ class SmartShooter(metaclass=SingletonType):
                 "code": 0,
                 "msg": msg_send,
                 "data": None,
-                "msg_type": self.msg_type,
+                "msg_type": msg_type,
                 "device_status": 2,
             }
             await self.sendMessageSocket(message)
             return True, "拍照成功"
         except zmq.Again:
             print("拍照超时")
-            msg_send = "相机未连接或软件未打开"
+            msg_send = "拍照失败"
             message = {
                 "code": 1,
                 "msg": msg_send,
                 "data": {goods_art_no: goods_art_no, "id": id},
-                "msg_type": self.msg_type,
+                "msg_type": msg_type,
                 "device_status": -1,
             }
             await self.sendMessageSocket(message)
@@ -624,12 +624,12 @@ class SmartShooter(metaclass=SingletonType):
             print("拍照出错",e)
             socket.close()
             context.term()
-            msg_send = "相机未连接或软件未打开"
+            msg_send = "拍照失败"
             message = {
                 "code": 1,
                 "msg": msg_send,
                 "data": None,
-                "msg_type": self.msg_type,
+                "msg_type": msg_type,
                 "device_status": -1,
             }
             await self.sendMessageSocket(message)

+ 5 - 1
python/sockets/message_handler.py

@@ -289,6 +289,10 @@ async def handlerSend(
             )
             device_ctrl.get_device_info()
         case "handler_take_picture":
+            if data is None:
+                PointName = "A"
+            else:
+                PointName = data.get("point_name", "A")
             device_ctrl = DeviceControl(
                 websocket_manager=manager, smart_shooter=smart_shooter
             )
@@ -323,7 +327,7 @@ async def handlerSend(
                 await manager.send_personal_message(data, websocket)
                 return
             loop.create_task(
-                blue_tooth.remote_control_v2.handlerTakePhoto(smart_shooter,session,record),
+                blue_tooth.remote_control_v2.handlerTakePhoto(smart_shooter,session,record,PointName),
                 name="run_mcu_config",
             )
             await asyncio.sleep(2.5)