Selaa lähdekoodia

Merge remote-tracking branch 'origin/anheng' into feature-frontend

panqiuyao 3 päivää sitten
vanhempi
commit
6938ef164a

+ 9 - 0
python/api.py

@@ -1212,6 +1212,7 @@ def get_photo_records(page: int = 1, size: int = 5, goods_art_no: str = None):
         # 按货号分组
         items_by_goods = {}
         for item in all_items:
+            print("all_items", all_items)
             goods_art_no = item.PhotoRecord.goods_art_no
             if goods_art_no not in items_by_goods:
                 items_by_goods[goods_art_no] = []
@@ -1223,10 +1224,18 @@ def get_photo_records(page: int = 1, size: int = 5, goods_art_no: str = None):
             if goods_art_no in items_by_goods:
                 # 获取该货号下时间最新的记录作为action_time
                 latest_record = items_by_goods[goods_art_no][0].PhotoRecord
+                extras = latest_record.extras
+                # extras 存储的是 json 字符串,解析成对象返回给前端
+                if extras:
+                    try:
+                        extras = json.loads(extras)
+                    except (json.JSONDecodeError, TypeError):
+                        extras = None
                 list_data.append(
                     {
                         "goods_art_no": goods_art_no,
                         "action_time": latest_record.create_time,
+                        "extras": extras,
                         "items": items_by_goods[goods_art_no],
                     }
                 )

+ 27 - 2
python/databases.py

@@ -291,7 +291,7 @@ def batch_insert_sys_configs(session: Session, data_list: list):
 
 # 插入照片记录
 async def insert_photo_records(
-        image_deal_mode: int, goods_art_no: str, image_index: int, action_id: int
+        image_deal_mode: int, goods_art_no: str, image_index: int, action_id: int, weight: str
 ):
     with SqlQuery() as session:  # 使用上下文管理器复用会话
         """批量插入数据到照片记录"""
@@ -300,6 +300,7 @@ async def insert_photo_records(
             "goods_art_no": goods_art_no,
             "image_index": image_index,
             "action_id": action_id,
+            "extras": json.dumps({"weight": str(weight)})
         }
         device_config = PhotoRecord(**data)
         session.add(device_config)
@@ -347,7 +348,8 @@ def auto_add_missing_columns():
             # 请在这里添加你实际新增的字段
             ("point_name", "VARCHAR", "DEFAULT 'A'"),
             ("is_move_device", "BOOLEAN", "DEFAULT 1"),
-            ("camera_focal_distance", "INT", "DEFAULT 0")
+            ("camera_focal_distance", "INT", "DEFAULT 0"),
+            ("camera_configs", "VARCHAR", "DEFAULT NULL")  # 扩展字段,存储 json 格式数据
         ]
 
         # 添加缺失的字段
@@ -361,6 +363,29 @@ def auto_add_missing_columns():
                     print(f"⚠️ 添加字段失败: {e}")
                     pass  # 忽略错误,继续下一个
 
+        # 检查 photo_record 表是否存在
+        cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='photo_record'")
+        if cursor.fetchone():
+            # 获取现有字段
+            cursor.execute("PRAGMA table_info(photo_record)")
+            existing_columns = [row[1] for row in cursor.fetchall()]
+
+            # 定义需要添加的字段 (字段名, SQL类型, 默认值)
+            photo_record_new_fields = [
+                ("extras", "VARCHAR", "DEFAULT NULL"),  # 扩展字段,存储 json 格式数据
+            ]
+
+            # 添加缺失的字段
+            for field_name, field_type, default_clause in photo_record_new_fields:
+                if field_name not in existing_columns:
+                    try:
+                        sql = f"ALTER TABLE photo_record ADD COLUMN {field_name} {field_type} {default_clause}"
+                        cursor.execute(sql)
+                        conn.commit()
+                    except Exception as e:
+                        print(f"⚠️ 添加字段失败: {e}")
+                        pass  # 忽略错误,继续下一个
+
         conn.close()
 
     except Exception as e:

+ 2 - 1
python/mcu/DeviceControl.py

@@ -1863,7 +1863,7 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
             return False
 
     async def run_mcu_config(
-            self, config_list, goods_art_no, action_info, smart_shooter
+            self, config_list, goods_art_no, action_info, smart_shooter, weight
     ):
         if self.checkDevice() == False:
             return
@@ -1900,6 +1900,7 @@ class DeviceControl(BaseClass, metaclass=SingletonType):
                         goods_art_no=goods_art_no,
                         image_index=idx,
                         action_id=action_id,
+                        weight=str(weight)
                     )
                 config_list[idx]["record_id"] = record_id
             total_len = len(config_list)

+ 4 - 2
python/mcu/ProgramItem.py

@@ -63,7 +63,8 @@ class ProgramItem(BaseClass):
         self.af_times = self.get_value(action_data, "number_focus", 0)
         self.shoe_overturn = self.get_value(action_data, "shoe_upturn", False)
         # 焦段距离
-        self.camera_focal_distance = self.get_value(action_data, "camera_focal_distance", 1)
+        self.camera_focal_distance = self.get_value(action_data, "camera_focal_distance", 0)
+        self.camera_configs = self.get_value(action_data, "camera_configs", None)
         self.is_photograph = self.get_value(action_data, "take_picture", True)
         self.turntable_position = float(
             self.get_value(action_data, "turntable_position", 0.0)
@@ -429,13 +430,14 @@ class ProgramItem(BaseClass):
                 )
                 print(" camera_configs p_item", camera_configs)
                 CameraKey = camera_configs[self.point_name].get("CameraKey", None)
-                print("smart shooter CameraShooter", record_id, goods_art_no, CameraKey)
+                # print("smart shooter CameraShooter", record_id, goods_art_no, CameraKey)
                 await self.smart_shooter.CameraShooter(
                     msg_type="run_mcu",
                     goods_art_no=goods_art_no,
                     id=record_id,
                     is_af=is_af,
                     CameraKey=CameraKey,
+                    camera_configs=self.camera_configs,
                 )
                 print("smart shooter CameraShooter end")
             else:

+ 54 - 9
python/mcu/capture/smart_shooter_class.py

@@ -174,6 +174,7 @@ class SmartShooter(metaclass=SingletonType):
                     await self.sendMessageSocket(message)
                 return False, msg_send
             cameraInfo = json_msg.get("CameraInfo")
+            print("相机状态msg_result", cameraInfo)
             if cameraInfo == None or len(cameraInfo) == 0:
                 self.connect_status = False
                 msg_send = (
@@ -332,6 +333,46 @@ class SmartShooter(metaclass=SingletonType):
             msg_send = "相机未连接或软件未打开"
             return False, msg_send
 
+    async def setCameraProperties(self, properties: dict, CameraKey=None):
+        """
+        批量设置相机参数(复用同一个 socket,连续发送多条 SetProperty 消息)
+        :param properties: 参数字典,如 {"ISO": "200", "Aperture": "8", "ShutterSpeed": "1/60"}
+        :return: (是否全部成功, {参数名: 是否成功})
+        """
+        if not properties:
+            return False, {}
+        camera_states, _ = await self.GetCameraInfo(is_send=False, CameraKey=CameraKey)
+        if not camera_states:
+            return False, "请先连接相机"
+        socket, context = self.__create_req()
+        results = {}
+        try:
+            for prop, value in properties.items():
+                req = {}
+                req["msg_type"] = "Request"
+                req["msg_id"] = "SetProperty"
+                req["msg_seq_num"] = 0
+                req["CameraSelection"] = "All"
+                if CameraKey is not None:
+                    req["CameraSelection"] = "Single"
+                    req["CameraKey"] = CameraKey
+                req["CameraPropertyType"] = str(prop)
+                req["CameraPropertyValue"] = str(value)
+                print("发送设置属性请求", req)
+                json_msg = self.__send_tcp_message(socket, req)
+                results[prop] = json_msg.get("msg_result")
+            all_ok = all(results.values())
+            return all_ok, results
+        except zmq.Again:
+            print(f"批量设置属性超时,继续监听...", results)
+            return all(results.values()) if results else False, results
+        except Exception as e:
+            print(f"批量设置属性异常", e)
+            return False, results
+        finally:
+            socket.close()
+            context.term()
+
     def getConfigIso(self, CameraKey=None):
         """获取ISO配置信息"""
         camera_configs = settings.getSysConfigs(
@@ -536,7 +577,8 @@ class SmartShooter(metaclass=SingletonType):
             return False, "相机未连接或软件未打开"
 
     async def CameraShooter(
-            self, msg_type="", goods_art_no="", id=0, is_af=False, delay=0.5, CameraKey=None
+            self, msg_type="", goods_art_no="", id=0, is_af=False, delay=0.5, CameraKey=None,
+            camera_configs=None
     ):
         # 这里延迟一秒钟 等待前置命令完成
         await asyncio.sleep(delay)
@@ -566,15 +608,18 @@ class SmartShooter(metaclass=SingletonType):
             return False, "请先连接相机"
         socket, context = self.__create_req()
         try:
-            low_iso, high_iso = self.getConfigIso(CameraKey=CameraKey)
-            print("LOW_ISO", low_iso)
-            print("HIGH_ISO", high_iso)
-            if str(low_iso).lower() != "auto":
-                await self.setCameraProperty(
-                    property="ISO", value=str(low_iso), CameraKey=CameraKey
-                )
+            if camera_configs is None:
+                low_iso, high_iso = self.getConfigIso(CameraKey=CameraKey)
+                print("LOW_ISO", low_iso)
+                print("HIGH_ISO", high_iso)
+                if str(low_iso).lower() != "auto":
+                    await self.setCameraProperty(
+                        property="ISO", value=str(low_iso), CameraKey=CameraKey
+                    )
+                else:
+                    print("low_iso 等于auto就不设置")
             else:
-                print("low_iso 等于auto就不设置")
+                await self.setCameraProperties(camera_configs, CameraKey=CameraKey)
             req = {}
             req["msg_type"] = "Request"
             req["msg_id"] = "Shoot"

+ 1 - 0
python/model/device_config.py

@@ -29,6 +29,7 @@ class DeviceConfig(SQLModel, table=True):
     point_name: Optional[str] = Field(default="A", description="点位名称,默认A点")
     is_move_device: Optional[bool] = Field(default=True, description="是否移动设备,默认移动设备")
     camera_focal_distance: Optional[int] = Field(default=None, description="相机焦距;最小0;最大动态获取")
+    camera_configs: Optional[str] = Field(default=None, description="相机配置;存储json格式数据")
     led_switch: Optional[bool] = Field(default=False, description="Led灯光开关;")
     is_wait: Optional[bool] = Field(default=False, description="没用;")
     is_need_confirm: Optional[bool] = Field(default=False, description="没用;")

+ 3 - 1
python/model/photo_record.py

@@ -19,4 +19,6 @@ class PhotoRecord(SQLModel, table=True):
     create_time: Optional[str] = Field(
         default_factory=lambda: datetime.now(TIME_ZONE).strftime("%Y-%m-%d %H:%M:%S")
     )
-    delete_time: Optional[str] = Field(default=None)
+    delete_time: Optional[str] = Field(default=None)
+    # 扩展字段,存储 json 格式数据
+    extras: Optional[str] = Field(default=None)

+ 4 - 2
python/sockets/message_handler.py

@@ -279,6 +279,7 @@ async def handlerSend(
             msg_type = "run_mcu"
             action_info = data.get("action", "执行左脚程序")
             goods_art_no = data.get("goods_art_no", None)
+            weight = data.get("weight", None)
             goods_art_no = goods_art_no.strip()
             if goods_art_no == None or goods_art_no == "":
                 # 判断货号是否存在
@@ -334,7 +335,7 @@ async def handlerSend(
             )
             loop.create_task(
                 device_ctrl.run_mcu_config(
-                    action_list, goods_art_no, action_info, smart_shooter
+                    action_list, goods_art_no, action_info, smart_shooter, weight
                 ),
                 name="run_mcu_config",
             )
@@ -586,6 +587,7 @@ async def handlerSend(
             temp_A_point = camera_configs.get(PointName, None)
             CameraKey = temp_A_point.get("CameraKey", None) if temp_A_point else None
             msg_type = "smart_shooter_get_camera_property"
+            print("CameraKey", CameraKey)
             code = 0
             status, info = await smart_shooter.GetCameraProperty(CameraKey=CameraKey)
             code = 1 if status == False else 0
@@ -878,7 +880,7 @@ async def handlerSend(
             if device_ctrl.anheng_scale._running == False:
                 data = manager.jsonMessage(
                     code=1,
-                    msg=f"记录不存在,请核实后重新操作~",
+                    msg=f"电子秤不存在,请核实后重新操作~",
                     msg_type="anheng_scale_status",
                 )
                 await manager.send_personal_message(data, websocket)

+ 14 - 2
python/temp2.py

@@ -21,6 +21,12 @@ async def setCameraProperty(property="Aperture", value=""):
     await smart.setCameraProperty(property=property, value=value)
 
 
+async def setCameraProperties(properties: dict):
+    '''批量设置多个参数,如 {"ISO": "200", "Aperture": "8", "ShutterSpeed": "1/60"}'''
+    all_ok, results = await smart.setCameraProperties(properties)
+    print("批量设置结果:", all_ok, results)
+
+
 async def main():
     '''
     Aperture:光圈
@@ -32,9 +38,15 @@ async def main():
     "CameraPropertyIsWriteable": 是否可写,
     "CameraPropertyRange" 参数范围
     '''
-    # camera_property = await parserProperty("Aperture")
+    camera_property = await parserProperty("Aperture")
     # print('property', camera_property)
-    await setCameraProperty('Exposure', '5.0')
+    # await setCameraProperty('Exposure', '5.0')
+    await setCameraProperties({
+        "ISO": "200",
+        "Aperture": "8",
+        "ShutterSpeed": "1/60",
+        "Exposure": "5.0"
+    })
 
 
 if __name__ == "__main__":