소스 검색

进出站修改

liu.ben 5 달 전
부모
커밋
01902343e3
3개의 변경된 파일855개의 추가작업 그리고 350개의 파일을 삭제
  1. 15 56
      MainForm/ClassFile/Inovance_EIP.cs
  2. 538 16
      MainForm/ClassFile/ProjectClass/SQLHelper.cs
  3. 302 278
      MainForm/FaForm/Form_Home.cs

+ 15 - 56
MainForm/ClassFile/Inovance_EIP.cs

@@ -61,19 +61,6 @@ namespace EIP_Protocol
         public short cmdResult;         //指令执行结果 1:OK   110:失败
     }
 
-    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
-    public struct agvCommFrmPC
-    {
-        [MarshalAs(UnmanagedType.U1)]
-        public byte cmd;                //1:AGV请求进料 2:AGV请求进料完成确认   3:AGV请求出料  4:AGV请求出料完成确认   PLC:成功回被PC清零
-
-        [MarshalAs(UnmanagedType.I2)]
-        public short cmdParam;          //1:左边接口    2:右边接口
-
-        [MarshalAs(UnmanagedType.I2)]
-        public short cmdResult;         //指令执行结果 1:OK   110:失败
-    }
-
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
     public struct CommandFromPLC
     {
@@ -87,19 +74,6 @@ namespace EIP_Protocol
         public short cmdResult;         //指令执行结果 1:OK   110:失败
     }
 
-    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
-    public struct mesCommToPC
-    {
-        [MarshalAs(UnmanagedType.U1)]
-        public byte cmd;                //1:工站进站申请  2:工站出站申请
-
-        [MarshalAs(UnmanagedType.I2)]
-        public short cmdParam;          //指令参数
-
-        [MarshalAs(UnmanagedType.I2)]
-        public short cmdResult;         //指令执行结果 1:OK   110:失败
-    }
-
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
     public struct OP10_From_PLC
     {
@@ -177,7 +151,7 @@ namespace EIP_Protocol
     }
 
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
-    public struct OP30_stnDataSet_t                          //站数据集
+    public struct OP30_DataSet_t                          //站数据集
     {
         [MarshalAs(UnmanagedType.R4)]
         public float fGlueSupplySpeed;                       //供胶速度
@@ -199,11 +173,11 @@ namespace EIP_Protocol
     }
 
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
-    public struct OP30_DataSet_t
+    public struct OP30_stnDataSet_t
     {
         public BarcodeSet_t BarcodeSet;        //条码集合
         public CommandFromPLC mesCommFrmPLC;   //MES通讯
-        public OP30_stnDataSet_t mesData;
+        public OP30_DataSet_t mesData;
         public IoT_DataSet_t iotData;
     }
 
@@ -280,6 +254,15 @@ namespace EIP_Protocol
         public float fCircles;                            //上位机传到PLC的锁螺丝圈数  每次读到阿特拉斯的数据都传一次
     }
 
+    [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
+    public struct OP70_ScrewDataSet_t
+    {
+        [MarshalAs(UnmanagedType.R4)]
+        public float fTorque;                             //上位机传到PLC的锁螺丝扭力  每次读到阿特拉斯的数据都传一次
+        [MarshalAs(UnmanagedType.R4)]
+        public float fCircles;                            //上位机传到PLC的锁螺丝圈数  每次读到阿特拉斯的数据都传一次
+    }
+
     public class OP70_PC_CollectDataSet_t
     {
         //需要自己收集
@@ -295,7 +278,7 @@ namespace EIP_Protocol
         public CommandFromPLC mesCommFrmPLC;   //MES通讯
         public OP70_DataSet_t mesData;
         public IoT_DataSet_t iotData;
-        public OP70_ScrewData_t screwDataToPLC;  //传到PLC的锁螺丝数据,用于HMI显示用
+        public OP70_ScrewDataSet_t screwDataToPLC;  //传到PLC的锁螺丝数据,用于HMI显示用
     }
 
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
@@ -348,8 +331,8 @@ namespace EIP_Protocol
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
     public struct OP30_MesData_t
     {
-        OP30_DataSet_t Left;
-        OP30_DataSet_t Right;
+        public OP30_stnDataSet_t Left;
+        public OP30_stnDataSet_t Right;
     }
 
     [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
@@ -430,30 +413,6 @@ namespace EIP_Protocol
         public IoT_DataSet_t iotData;
     }
     #endregion  MES与PLC通讯结构
-    public struct OP10_MesData_r
-    {
-        public BarcodeSet_t BarcodeSet;         //条码集合
-        public agvCommFrmPC agvCommFrmPC;       //AGV通讯
-        public mesCommToPC mesCommToPC;    //MES通讯
-    }
-
-    public struct OP20_MesData_r
-    {
-        public BarcodeSet_t BarcodeSet;         //条码集合
-        public agvCommFrmPC agvCommFrmPC;       //AGV通讯
-        public mesCommToPC mesCommToPC;    //MES通讯
-    }
-
-    public struct OP30_MesData_r
-    {
-        public BarcodeSet_t BarcodeSet;         //条码集合
-        public agvCommFrmPC agvCommFrmPC;       //AGV通讯
-        public mesCommToPC mesCommToPC;    //MES通讯
-    }
-
-    #region 写入PLC的通讯结构
-
-    #endregion
 
     public class Inovance_EIP
     {

+ 538 - 16
MainForm/ClassFile/ProjectClass/SQLHelper.cs

@@ -54,7 +54,7 @@ namespace MainForm
             if (!Directory.Exists(DBDir + subDir)) Directory.CreateDirectory(DBDir + subDir);
             //创建数据库和表
             SQLHelper.CreateDataBase(DBDir, subDir, dataBaseName);
-            SQLHelper.CreateDataBase();
+            //SQLHelper.CreateDataBase();
         }
 
         /// <summary>
@@ -549,7 +549,7 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
 
             return result;
         }
-        //创建 载具绑定物料码表、物料码绑定部件码表、PLC返回数据记录表
+        //创建 载具绑定物料码表、物料码绑定部件码表、PLC返回MES数据记录表
         public static void CreateDataBase()
         {
             try
@@ -603,8 +603,7 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             var CarrierBind_sumRecord = new CarrierBind
             {
                 CarrierCode = carrierCode,
-                ProductBarcode = productBarcode,
-                stationId = stationId,
+                ProductBarcode = productBarcode
             };
 
             // 检查记录是否已经存在
@@ -630,27 +629,58 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             #endregion
         }
 
-        public void InsertOp10Data(string carrierCode, string productBarcode, string stationId, string userId, string hydrocooling_Barcode, int bindOrder,
+        public static ResponseMessage InsertOp10Data(SqlSugarClient db, string carrierCode, string hydrocooling_Barcode, int bindOrder,
                                           int throwingAmount, float cleaningPower, float cleaningPressure, float cleaningSpeed,
                                           float airKnifeHeight, float cleaningTime, int cleaningCount)
         {
+            #region 新建CarrierBind实体,并将数据插入carrierBind表格
+            // 创建 CarrierBind 实体,并通过传入的参数设置字段值
+            var CarrierBind_sumRecord = new CarrierBind
+            {
+                CarrierCode = carrierCode,
+                ProductBarcode = hydrocooling_Barcode,
+            };
+
+            // 检查记录是否已经存在
+            bool CarrierBind_exists = db.Queryable<CarrierBind>().Any(x => x.CarrierCode == CarrierBind_sumRecord.CarrierCode &&
+                                                          x.ProductBarcode == CarrierBind_sumRecord.ProductBarcode);
+            if (CarrierBind_exists)
+            {
+                var maxBindOrder = db.Queryable<CarrierBind>()
+                                      .Where(x => x.CarrierCode == CarrierBind_sumRecord.CarrierCode &&
+                                                  x.ProductBarcode == CarrierBind_sumRecord.ProductBarcode);
+                db.Deleteable<CarrierBind>().Where(x => x.CarrierCode == carrierCode).ExecuteCommand();
+            }
+            else
+            {
+                // 插入数据
+                try
+                {
+                    db.Insertable(CarrierBind_sumRecord).ExecuteCommand();
+                }
+                catch (Exception ex)
+                {
+                    return new ResponseMessage { result = true, text = "OP10数据-载具码与产品码绑定失败,错误码:" + ex.Message };
+                }
+            }
+            #endregion
 
             #region 新建ProductBind实体,并将数据插入productBind表格
             // 创建 ProductBind 实体,并通过传入的参数设置字段值
             var ProductBind_sumRecord = new ProductBind
             {
                 CarrierCode = carrierCode,//载具码
-                Hydrocooling_Barcode = hydrocooling_Barcode,  // 水冷壳体条码
+                ProductBarcode = hydrocooling_Barcode,  // 水冷壳体条码
                 BindOrder = bindOrder                         // 绑定顺序
             };
 
             // 检查记录是否已经存在
             bool ProductBind_exists = db.Queryable<ProductBind>().Any(x => x.CarrierCode == ProductBind_sumRecord.CarrierCode &&
-                                                          x.Hydrocooling_Barcode == ProductBind_sumRecord.Hydrocooling_Barcode &&
+                                                          x.ProductBarcode == ProductBind_sumRecord.ProductBarcode &&
                                                           x.BindOrder == ProductBind_sumRecord.BindOrder);
             if (ProductBind_exists)
             {
-                logNet.WriteError("OP10-ProductBind:记录已经存在!bindOrder:" + bindOrder);
+      
             }
             else
             {
@@ -658,7 +688,7 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
                 try
                 {
                     db.Insertable(ProductBind_sumRecord).ExecuteCommand();
-                    logNet.WriteInfo("OP10-数据插入到 productbind 表格成功!");
+                    logNet.WriteError("OP10-数据插入到 productbind 表格成功!");
                 }
                 catch (Exception ex)
                 {
@@ -670,19 +700,19 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             #region 将OP10数据插入testdata表格
             // 检查主键是否存在
             var existingRecord = db.Queryable<TestData>()
-                    .Where(x => x.CarrierCode == carrierCode && x.Hydrocooling_Barcode == hydrocooling_Barcode && x.BindOrder == bindOrder)
+                    .Where(x => x.CarrierCode == carrierCode && x.ProductBarcode == hydrocooling_Barcode && x.BindOrder == bindOrder)
                     .First();
             if (existingRecord != null)
             {
                 logNet.WriteError("OP10错误:数据已存在,载具码、水冷壳体码和绑定顺序相同!");
-                return; // 如果数据已存在,停止插入
+                return new ResponseMessage { result = false, text = "OP10错误:数据已存在,载具码、水冷壳体码和绑定顺序相同!" };
             }
 
             // 创建 Op10 实体,并通过传入的参数设置字段值
             var op10 = new TestData
             {
                 CarrierCode = carrierCode,                  // 载具码
-                Hydrocooling_Barcode = hydrocooling_Barcode,// 水冷壳体码
+                ProductBarcode = hydrocooling_Barcode,// 水冷壳体码
                 BindOrder = bindOrder,                      // 绑定顺序
 
                 OP10_ThrowingAmount = throwingAmount,       // 抛料数量
@@ -697,13 +727,506 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             try
             {
                 db.Insertable(op10).ExecuteCommand();
-                logNet.WriteInfo("OP10记录插入成功!");
+                logNet.WriteError("OP10记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP10记录插入成功"};
             }
             catch (Exception ex)
             {
                 logNet.WriteError("OP10记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP10记录插入出错!错误码:" + ex.Message };
+            }
+            #endregion
+        }
+
+        // op20向testdata表格插入数据
+        public static ResponseMessage InsertOp20Data( int throwingAmount, string topCover_Barcode)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.OP10_ThrowingAmount != 0 &&
+                            x.OP10_CleaningPower != 0.0f &&
+                            x.OP10_CleaningPressure != 0.0f &&
+                            x.OP10_CleaningSpeed != 0.0f &&
+                            x.OP10_AirKnifeHeight != 0.0f &&
+                            x.OP10_CleaningTime != 0.0f &&
+                            x.OP10_CleaningCount != 0) // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP20错误:OP10插入的记录存在值为空!");
+            }
+
+            if (lastRecord.OP20_ThrowingAmount != 0 || lastRecord.TopCover_Barcode != "")
+            {
+                logNet.WriteError("OP20错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+            }
+
+            #region 往productBind表格中插入topCover_Barcode数据
+            // 检查上一次插入的记录是否存在
+            var productBind_lastRecord = db.Queryable<ProductBind>()
+                .Where(x => x.CarrierCode != "" && x.ProductBarcode != "" && x.BindOrder != 0)
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (productBind_lastRecord == null)
+            {
+                logNet.WriteError("OP20-错误:ProductBind表中最新插入的数据为空!");
+            }
+
+            if (productBind_lastRecord.TopCover_Barcode != "")
+            {
+                logNet.WriteError("OP20-错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+            }
+
+            productBind_lastRecord.TopCover_Barcode = topCover_Barcode;
+
+            try
+            {
+                db.Updateable(productBind_lastRecord)
+                    .UpdateColumns(x => new {
+                        x.TopCover_Barcode
+                    }).ExecuteCommand();
+                logNet.WriteError("OP20往ProductBind表中插入TopCover_Barcode成功!");
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP20往ProductBind表中插入TopCover_Barcode出错!错误码:" + ex.Message);
             }
             #endregion
+
+            lastRecord.OP20_ThrowingAmount = throwingAmount;
+            lastRecord.TopCover_Barcode = topCover_Barcode;
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new { x.OP20_ThrowingAmount, x.TopCover_Barcode })
+                    .ExecuteCommand();
+                logNet.WriteError("OP20记录插入成功!");
+                return new ResponseMessage { result = false, text = "OP20记录插入成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP20记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP20记录插入出错!错误码:" + ex.Message };
+            }
+        }
+
+        // op301向testdata表格插入数据
+        public static ResponseMessage InsertOp301Data( float gluingSpeed, float pressureA, float pressureB, float pressureDifferenceAB,
+                                            float productHeightInfo, float periodicWeightData, float remainingGlueAmount)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.OP20_ThrowingAmount != 0 && x.TopCover_Barcode != "") // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP301错误:OP20插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP301错误:OP20插入的记录存在值为空!" };
+            }
+
+            if (lastRecord.OP301_GluingSpeed != 0.0f || lastRecord.OP301_PressureA != 0.0f || lastRecord.OP301_PressureB != 0.0f ||
+                lastRecord.OP301_PressureDifferenceAB != 0.0f || lastRecord.OP301_ProductHeightInfo != 0.0f ||
+                lastRecord.OP301_PeriodicWeightData != 0.0f || lastRecord.OP301_RemainingGlueAmount != 0.0f)
+            {
+                logNet.WriteError("OP301错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP301错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.OP301_GluingSpeed = gluingSpeed;                   // 供胶速度
+            lastRecord.OP301_PressureA = pressureA;                       // A管气压
+            lastRecord.OP301_PressureB = pressureB;                       // B管气压
+            lastRecord.OP301_PressureDifferenceAB = pressureDifferenceAB; // AB管气压差
+            lastRecord.OP301_ProductHeightInfo = productHeightInfo;       // 产品测高信息
+            lastRecord.OP301_PeriodicWeightData = periodicWeightData;     // 定期称重数据
+            lastRecord.OP301_RemainingGlueAmount = remainingGlueAmount;   // 剩余胶量
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.OP301_GluingSpeed,
+                        x.OP301_PressureA,
+                        x.OP301_PressureB,
+                        x.OP301_PressureDifferenceAB,
+                        x.OP301_ProductHeightInfo,
+                        x.OP301_PeriodicWeightData,
+                        x.OP301_RemainingGlueAmount
+                    }).ExecuteCommand();
+                logNet.WriteError("OP301记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP301记录插入成功"};
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP301记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP301记录插入出错!错误码:" + ex.Message };
+            }
+        }
+
+        // op302向testdata表格插入数据
+        public static ResponseMessage InsertOp302Data( float gluingSpeed, float pressureA, float pressureB, float pressureDifferenceAB,
+                                            float productHeightInfo, float periodicWeightData, float remainingGlueAmount)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.OP301_GluingSpeed != 0.0f && x.OP301_PressureA != 0.0f && x.OP301_PressureB != 0.0f &&
+                x.OP301_PressureDifferenceAB != 0.0f && x.OP301_ProductHeightInfo != 0.0f &&
+                x.OP301_PeriodicWeightData != 0.0f && x.OP301_RemainingGlueAmount != 0.0f) // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP302错误:OP301插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP302错误:OP301插入的记录存在值为空!" };
+            }
+
+            if (lastRecord.OP302_GluingSpeed != 0.0f || lastRecord.OP302_PressureA != 0.0f || lastRecord.OP302_PressureB != 0.0f ||
+                lastRecord.OP302_PressureDifferenceAB != 0.0f || lastRecord.OP302_ProductHeightInfo != 0.0f ||
+                lastRecord.OP302_PeriodicWeightData != 0.0f || lastRecord.OP302_RemainingGlueAmount != 0.0f)
+            {
+                logNet.WriteError("OP302错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP302错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.OP302_GluingSpeed = gluingSpeed;                   // 供胶速度
+            lastRecord.OP302_PressureA = pressureA;                       // A管气压
+            lastRecord.OP302_PressureB = pressureB;                       // B管气压
+            lastRecord.OP302_PressureDifferenceAB = pressureDifferenceAB; // AB管气压差
+            lastRecord.OP302_ProductHeightInfo = productHeightInfo;       // 产品测高信息
+            lastRecord.OP302_PeriodicWeightData = periodicWeightData;     // 定期称重数据
+            lastRecord.OP302_RemainingGlueAmount = remainingGlueAmount;   // 剩余胶量
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.OP302_GluingSpeed,
+                        x.OP302_PressureA,
+                        x.OP302_PressureB,
+                        x.OP302_PressureDifferenceAB,
+                        x.OP302_ProductHeightInfo,
+                        x.OP302_PeriodicWeightData,
+                        x.OP302_RemainingGlueAmount
+                    }).ExecuteCommand();
+                logNet.WriteError("OP302记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP302记录插入成功" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP302记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP302错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+        }
+
+        // op40向testdata表格插入数据
+        public static ResponseMessage InsertOp40Data( string gluePosition, float glueLineArea,
+            float glueLineHeight, string inspectionImagePath)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.OP302_GluingSpeed != 0.0f && x.OP302_PressureA != 0.0f && x.OP302_PressureB != 0.0f &&
+                x.OP302_PressureDifferenceAB != 0.0f && x.OP302_ProductHeightInfo != 0.0f &&
+                x.OP302_PeriodicWeightData != 0.0f && x.OP302_RemainingGlueAmount != 0.0f) // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP40错误:OP302插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP40错误:OP302插入的记录存在值为空!" };
+            }
+
+            if (lastRecord.OP40_GluePosition != "" || lastRecord.OP40_GlueLineArea != 0.0f ||
+                lastRecord.OP40_GlueLineHeight != 0.0f || lastRecord.OP40_InspectionImagePath != "")
+            {
+                logNet.WriteError("OP40错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP40错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.OP40_GluePosition = gluePosition;                 // 点胶位置
+            lastRecord.OP40_GlueLineArea = glueLineArea;                 // 胶线面积
+            lastRecord.OP40_GlueLineHeight = glueLineHeight;             // 胶线高度
+            lastRecord.OP40_InspectionImagePath = inspectionImagePath;  // 检测图片路径
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.OP40_GluePosition,
+                        x.OP40_GlueLineArea,
+                        x.OP40_GlueLineHeight,
+                        x.OP40_InspectionImagePath
+                    }).ExecuteCommand();
+                logNet.WriteError("OP40记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP40记录插入成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP40记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = true, text = "OP40记录插入出错!错误码:" + ex.Message };
+            }
+        }
+
+        //OP50 往product塞数据
+        public static ResponseMessage InsertOp50Product( string CarrierCode,string ProductBarcode, string addPCB_Barcode)
+        {
+       
+            #region 往productBind表格中插入addPCB_Barcode数据
+            // 检查上一次插入的记录是否存在
+            var productBind_lastRecord = db.Queryable<ProductBind>()
+                .Where(x => x.CarrierCode == CarrierCode && x.ProductBarcode == ProductBarcode && x.BindOrder != 0)
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (productBind_lastRecord == null)
+            {
+                logNet.WriteError("OP50-错误:ProductBind表数据为空!");
+                return new ResponseMessage { result = false, text = "OP50-错误:ProductBind表数据为空!" };
+            }
+
+            if (productBind_lastRecord.AddPCB_Barcode != "")
+            {
+                logNet.WriteError("OP50-错误:即将插入ProductBind的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP50-错误:即将插入ProductBind的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            productBind_lastRecord.AddPCB_Barcode = addPCB_Barcode;
+
+            try
+            {
+                db.Updateable(productBind_lastRecord)
+                    .UpdateColumns(x => new {
+                        x.AddPCB_Barcode
+                    }).ExecuteCommand();
+                logNet.WriteError("OP50往ProductBind表中插入AddPCB_Barcode成功!");
+                return new ResponseMessage { result = false, text = "OP50往ProductBind表中插入AddPCB_Barcode成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP50往ProductBind表中插入AddPCB_Barcode出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP50往ProductBind表中插入AddPCB_Barcode出错!错误码:" + ex.Message };
+            }
+            #endregion
+        }
+
+
+        // op50向testdata表格插入数据
+        public static ResponseMessage InsertOp50Data(string CarrierCode,string ProductBarcode,string addPCB_Barcode, int assemblyStatus,
+            string reinspectionImagePath, int addBoardStatus, float addBoardPressure)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.CarrierCode == CarrierCode && x.ProductBarcode == ProductBarcode && x.OP40_GluePosition != "" && x.OP40_GlueLineArea != 0.0f &&
+                x.OP40_GlueLineHeight != 0.0f && x.OP40_InspectionImagePath != "") // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP50错误:OP40插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP50错误:OP40插入的记录存在值为空!!" };
+            }
+
+            if (lastRecord.AddPCB_Barcode != "" || lastRecord.OP50_AssemblyStatus != 2 || lastRecord.OP50_ReinspectionImagePath != "" ||
+                lastRecord.OP50_AddBoardStatus != 2 || lastRecord.OP50_AddBoardPressure != 0.0f)
+            {
+                logNet.WriteError("OP50错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP50错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.AddPCB_Barcode = addPCB_Barcode;
+            lastRecord.OP50_AssemblyStatus = assemblyStatus;                // 组装是否到位
+            lastRecord.OP50_ReinspectionImagePath = reinspectionImagePath;    // 设备复检图片路径
+            lastRecord.OP50_AddBoardStatus = addBoardStatus;                // ADD板有无
+            lastRecord.OP50_AddBoardPressure = addBoardPressure;            // ADD板压合压力
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.AddPCB_Barcode,
+                        x.OP50_AssemblyStatus,
+                        x.OP50_ReinspectionImagePath,
+                        x.OP50_AddBoardStatus,
+                        x.OP50_AddBoardPressure
+                    }).ExecuteCommand();
+                logNet.WriteError("OP50记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP50记录插入成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP50记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP50记录插入出错!错误码:" + ex.Message };
+            }
+        }
+
+        // op60向testdata表格插入数据
+        public static ResponseMessage InsertOp60Data(string CarrierCode,string ProductBarcode, int assemblyStatus, string reinspectionImagePath,
+            int topCoverStatus, float topCoverPressure)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.CarrierCode == CarrierCode && x.ProductBarcode == ProductBarcode && x.AddPCB_Barcode != "" && x.OP50_AssemblyStatus != 2 && x.OP50_ReinspectionImagePath != "" &&
+                x.OP50_AddBoardStatus != 2 && x.OP50_AddBoardPressure != 0.0f) // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP60错误:OP50插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP60错误:OP50插入的记录存在值为空!" };
+             }
+
+            if (lastRecord.OP60_AssemblyStatus != 2 || lastRecord.OP60_ReinspectionImagePath != "" ||
+                lastRecord.OP60_TopCoverStatus != 2 || lastRecord.OP60_TopCoverPressure != 0.0f)
+            {
+                logNet.WriteError("OP60错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP60错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.OP60_AssemblyStatus = assemblyStatus;                // 组装是否到位
+            lastRecord.OP60_ReinspectionImagePath = reinspectionImagePath;  // 设备复检图片路径
+            lastRecord.OP60_TopCoverStatus = topCoverStatus;                // 上盖板有无
+            lastRecord.OP60_TopCoverPressure = topCoverPressure;            // 上盖板压合压力
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.OP60_AssemblyStatus,
+                        x.OP60_ReinspectionImagePath,
+                        x.OP60_TopCoverStatus,
+                        x.OP60_TopCoverPressure
+                    }).ExecuteCommand();
+                logNet.WriteError("OP60记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP60记录插入成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP60记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP60记录插入出错!错误码:" + ex.Message };
+            }
+        }
+
+        // op701向testdata表格插入数据
+        public static ResponseMessage InsertOp701Data(string CarrierCode,string ProductBarcode, string torqueCurveDataPath,
+                                            float screwPressure, int turns, float lockTime, string lockOrder, string lockResult)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.CarrierCode == CarrierCode && x.ProductBarcode == ProductBarcode && x.OP60_AssemblyStatus != 2 && x.OP60_ReinspectionImagePath != "" &&
+                x.OP60_TopCoverStatus != 2 && x.OP60_TopCoverPressure != 0.0f) // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP701错误:OP60插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP701错误:OP60插入的记录存在值为空!" };
+            }
+
+            if (lastRecord.OP701_TorqueCurveDataPath != "" || lastRecord.OP701_ScrewPressure != 0.0f || lastRecord.OP701_Turns != 0 ||
+                lastRecord.OP701_LockTime != 0 || lastRecord.OP701_LockOrder != "" || lastRecord.OP701_LockResult != "")
+            {
+                logNet.WriteError("OP701错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP701错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.OP701_TorqueCurveDataPath = torqueCurveDataPath;
+            lastRecord.OP701_ScrewPressure = screwPressure;
+            lastRecord.OP701_Turns = turns;
+            lastRecord.OP701_LockTime = lockTime;
+            lastRecord.OP701_LockOrder = lockOrder;
+            lastRecord.OP701_LockResult = lockResult;
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.OP701_TorqueCurveDataPath,
+                        x.OP701_ScrewPressure,
+                        x.OP701_Turns,
+                        x.OP701_LockTime,
+                        x.OP701_LockOrder,
+                        x.OP701_LockResult
+                    }).ExecuteCommand();
+                logNet.WriteError("OP701记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP701记录插入成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP701记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP701记录插入出错!错误码:" + ex.Message };
+            }
+        }
+
+        // op702向testdata表格插入数据
+        public static ResponseMessage InsertOp702Data(string CarrierCode,string ProductBarcode, string torqueCurveDataPath,
+                                            float screwPressure, int turns, float lockTime, string lockOrder, string lockResult)
+        {
+            // 检查上一次插入的记录是否存在
+            var lastRecord = db.Queryable<TestData>()
+                .Where(x => x.CarrierCode == CarrierCode && x.ProductBarcode == ProductBarcode && x.OP701_TorqueCurveDataPath != "" && x.OP701_ScrewPressure != 0.0f &&
+                x.OP701_Turns != 0 && x.OP701_LockTime != 0 && x.OP701_LockOrder != "" &&
+                x.OP701_LockResult != "") // 只查找有效插入的数据
+                .OrderBy(x => x.ID, OrderByType.Desc) // 按照ID降序查找最新记录
+                .Take(1) // 只取一条记录
+                .First(); // 获取第一条记录,若没有则返回null
+
+            if (lastRecord == null)
+            {
+                logNet.WriteError("OP702错误:OP701插入的记录存在值为空!");
+                return new ResponseMessage { result = false, text = "OP702错误:OP701插入的记录存在值为空!" };
+            }
+
+            if (lastRecord.OP702_TorqueCurveDataPath != "" || lastRecord.OP702_ScrewPressure != 0.0f || lastRecord.OP702_Turns != 0 ||
+                lastRecord.OP702_LockTime != 0 || lastRecord.OP702_LockOrder != "" || lastRecord.OP702_LockResult != "")
+            {
+                logNet.WriteError("OP702错误:即将插入的数据存在值不为空,插入失败,请按标准操作!");
+                return new ResponseMessage { result = false, text = "OP702错误:即将插入的数据存在值不为空,插入失败,请按标准操作!" };
+            }
+
+            lastRecord.OP702_TorqueCurveDataPath = torqueCurveDataPath;
+            lastRecord.OP702_ScrewPressure = screwPressure;
+            lastRecord.OP702_Turns = turns;
+            lastRecord.OP702_LockTime = lockTime;
+            lastRecord.OP702_LockOrder = lockOrder;
+            lastRecord.OP702_LockResult = lockResult;
+
+            try
+            {
+                db.Updateable(lastRecord)
+                    .UpdateColumns(x => new {
+                        x.OP702_TorqueCurveDataPath,
+                        x.OP702_ScrewPressure,
+                        x.OP702_Turns,
+                        x.OP702_LockTime,
+                        x.OP702_LockOrder,
+                        x.OP702_LockResult
+                    }).ExecuteCommand();
+                logNet.WriteError("OP702记录插入成功!");
+                return new ResponseMessage { result = true, text = "OP702记录插入成功!" };
+            }
+            catch (Exception ex)
+            {
+                logNet.WriteError("OP702记录插入出错!错误码:" + ex.Message);
+                return new ResponseMessage { result = false, text = "OP702记录插入出错!错误码:" + ex.Message };
+            }
         }
 
 
@@ -720,7 +1243,6 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             // 其他列
             public string CarrierCode { get; set; } = "";           // 载具码
             public string ProductBarcode { get; set; } = "";  // 产品码
-            public string stationId { get; set; } = "";  // 工位ID
             public DateTime CreateTime { get; set; } = DateTime.Now;    // 创建时间
         }
 
@@ -734,7 +1256,7 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             // 其他列
             public DateTime CreateTime { get; set; } = DateTime.Now;    // 创建时间
             public string CarrierCode { get; set; } = "";               // 载具码
-            public string Hydrocooling_Barcode { get; set; } = "";      // 水冷壳体
+            public string ProductBarcode { get; set; } = "";      // 产品条
             public string TopCover_Barcode { get; set; } = "";          // 上盖板条码
             public string AddPCB_Barcode { get; set; } = "";            // ADD板条码
             public int BindOrder { get; set; } = 0;                     // 绑定顺序
@@ -750,7 +1272,7 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单信息
             // 其他列
             public DateTime CreateTime { get; set; } = DateTime.Now;    // 创建时间
             public string CarrierCode { get; set; } = "";               // 载具码
-            public string Hydrocooling_Barcode { get; set; } = "";      // 水冷壳体
+            public string ProductBarcode { get; set; } = "";      // 产品条
             public string TopCover_Barcode { get; set; } = "";          // 上盖板条码
             public string AddPCB_Barcode { get; set; } = "";            // ADD板条码
             public int BindOrder { get; set; } = 0;                     // 绑定顺序

+ 302 - 278
MainForm/FaForm/Form_Home.cs

@@ -27,6 +27,9 @@ using EIP_Protocol;
 using DevComponents.DotNetBar.Controls;
 using ICSharpCode.SharpZipLib.Zip;
 using static MainForm.SQLHelper;
+using NPOI.SS.Formula.Functions;
+using MainForm.ClassFile.ProjectClass;
+using HslCommunication.Controls;
 
 /*
  * 注:本源码对外提供,所以有些地方使用中文命名方法及变量
@@ -200,6 +203,7 @@ namespace MainForm
                                                                  //TaskReadProcess.Add(new Task(() => { ReadStation_DownOrderInfo(1); }));  // 下发机种
 
                 if (GlobalContext.IsUsePLC1)
+                    //ReadStation_S1(1);
                     TaskReadProcess.Add(new Task(() => { ReadStation_S1(1); }));             //OP10 壳体清洁上料装备
                 if (GlobalContext.IsUsePLC2)
                     TaskReadProcess.Add(new Task(() => { ReadStation_S2(2); }));             //OP20 顶盖上料设备
@@ -907,6 +911,7 @@ namespace MainForm
          
             OP10_MesData_t stPLC_MesData;        //PLC的MES数据
             (int, string)  result;
+            bool ProgressState = true;
 
             #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
             // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
@@ -982,21 +987,18 @@ namespace MainForm
                         #endregion 一次性读取所有数据
                         stopwatch2.Stop();
 
-                        #region 回写操作,写后清空flag
-                        mesCommToPC WriteBackToPLC = new mesCommToPC();
-                        result = Funs[plcNo].Write_SingleTag<mesCommToPC>(tagBaseName +"." + tagMesCommName, 1, WriteBackToPLC);  //写入单个结构体数据
-                        #endregion 回写操作,写后清空flag
-
                         #region 进站
                         try
                         {
-                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
                             {
-                                Task.Run(() => S1进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName));
+                                    ProgressState = false;
+                                    Task.Run(() => S1进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName,out ProgressState));
                             }
                         }
                         catch (Exception ex)
                         {
+                            ProgressState = false;
                             string str = ex.StackTrace;
                             AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
                         }
@@ -1005,9 +1007,10 @@ namespace MainForm
                         #region 出站
                         try
                         {
-                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
                             {
-                                Task.Run(() => S1出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName));
+                                ProgressState = false;
+                                Task.Run(() => S1出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName,out ProgressState));
                             }
                         }
                         catch (Exception ex)
@@ -1049,76 +1052,101 @@ namespace MainForm
         /// <param name="stationNameStr">工站全称</param>
         /// <param name="stPLC_MesData"></param>
         /// <param name="tagMesCommName"></param>
-        private void S1进站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName)
+        private void S1进站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName,out bool ProgressState)
         {
             int nRet=0;
             string strRet = "";
             Stopwatch stopwatch1 = new Stopwatch();
             Stopwatch stopwatch2 = new Stopwatch();
+            ProgressState = true;
             try
             {
                 stopwatch1.Start();
                 string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品SN(物料码)
-                sn = sn.Replace("\0", "");
+                string MachineId = GlobalContext.S1_MachineId;  // 装备ID(可配置)
+                string StationId = GlobalContext.S1_StationId;  // 工位ID(可配置)
 
                 // 产品SN(物料码)校验
                 List<TestItem> item = new List<TestItem>();
                 stopwatch2.Start();
-                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item);
+                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
                 stopwatch2.Stop();
 
                 //指令执行结果 1:OK   110:失败
                 byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
 
                 //进站结果写入PLC
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = mesResultFrmWeb;
-
-                (nRet,strRet)=Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
-                //3次控制,弹出
-                if (nRet != 0 )
-                {
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
 
-                }
+                WriteResultToPlc(plcNo,stationNameStr, tagMesCommName,1, resultToPlC);
             }
             catch (Exception ex)
             {
                 string str = ex.StackTrace;
                 AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
 
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 110;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);  
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
             }
 
             stopwatch1.Stop();
             AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
         }
 
+        /// <summary>
+        /// 进出站结果写入PLC
+        /// </summary>
+        public void WriteResultToPlc(int plcNo,string stationNameStr,string strTagName, int nCount, CommandFromPLC resultToPlC)
+        {
+            int i = 0;
+            int nRet = 0;
+            string strRet = "";
+            while (i < 3)  // 最多上传三次
+            {
+                (nRet, strRet) = Funs[plcNo].Write_SingleTag<CommandFromPLC>(strTagName, nCount, resultToPlC);
+                if (nRet == 0)  //成功
+                {
+                    break;
+                }
+                else
+                {
+                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站结果写入PLC出错!错误信息:" + strRet);
+                    i++;
+                }
+            }
+        }
+
         /// <summary>
         /// [S1] 壳体清洁上料 - 出站接口
         /// </summary>
-        private void S1出站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName)
+        private void S1出站(int plcNo, string stationNameStr, OP10_MesData_t stPLC_MesData, string tagMesCommName,string stationCode,string stationName, out bool ProgressState)
         {
+            ProgressState = true;
             Stopwatch stopwatch1 = new Stopwatch();
             Stopwatch stopwatch2 = new Stopwatch();
 
-         
+
             try
             {
                 stopwatch1.Start();
 
+                string equipmentCode = GlobalContext.LineCode + "-" + stationCode;  // 设备编号
+                string processItem = stationName;  // 测试项目
+                string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
+                string supplierCode = "";     // 供应商代码
                 string workorder_code = GlobalContext.WorkOrderCode;  // 工单号
                 string batch_num = GlobalContext.BatchNumber;         // 批次号
-                string mtltmrk = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品条码;               // 产品型号
-                mtltmrk = mtltmrk.Replace("\0", "");
+                string mtltmrk = GlobalContext.Mtltmrk;               // 产品型号
+                string sn=(string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品条码;
                 string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode;  // 载具条码;
-                CarrierBarcode = CarrierBarcode.Replace("\0", "");
-    
+                string MachineId = GlobalContext.S1_MachineId;  // 装备id(可配置)  // ZS
+                string StationId = GlobalContext.S1_StationId;  // ⼯位ID(可配置)  // ZS
                 int a1Result = (int)stPLC_MesData.iotData.testStatus;          // 产品结果
                 bool pass = a1Result == 1;
 
@@ -1146,19 +1174,18 @@ namespace MainForm
 
                 //绑定PLC返回MES数据到本地
 
+                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
+    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
 
-                int result1 = SwitctProcessData(stationNameStr, items, "", ""
-                    , workorder_code, batch_num, mtltmrk, "", "", "", pass, CarrierBarcode, "1");
-
-                byte cmdToPC = (byte)(result1 == 1 ? 1 : 110);
+                byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
                 stopwatch2.Start();
                 //进站结果写入PLC
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = cmdToPC;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 1;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
                 stopwatch2.Stop();
 
                 WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
@@ -1166,11 +1193,11 @@ namespace MainForm
             catch (Exception ex)
             {
                 stopwatch2.Start();
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 110;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
                 stopwatch2.Stop();
 
                 string str = ex.StackTrace;
@@ -1598,6 +1625,7 @@ namespace MainForm
 
             OP20_MesData_t stPLC_MesData;        //PLC的MES数据
             (int, string) result;
+            bool ProgressState = true;
 
             while (true)
             {
@@ -1629,36 +1657,30 @@ namespace MainForm
                         #endregion 一次性读取所有数据
                         stopwatch2.Stop();
 
-                        #region 回写操作,写后清空flag
-                        mesCommToPC WriteBackToPLC = new mesCommToPC();
-                        result = Funs[plcNo].Write_SingleTag<mesCommToPC>(tagBaseName + "." + tagMesCommName, 1, WriteBackToPLC);  //写入单个结构体数据
-                        #endregion 回写操作,写后清空flag
-
                         #region 进站
                         try
                         {
-                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation)
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
                             {
-                                Task.Run(() => S2进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName));
-                                //进站
+                                ProgressState = false;
+                                Task.Run(() => S2进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName, out ProgressState));
                             }
                         }
                         catch (Exception ex)
                         {
-                            //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6);  // 6代表上位机报警
-
+                            ProgressState = false;
                             string str = ex.StackTrace;
-                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
                         }
                         #endregion 进站
 
-
                         #region 出站
                         try
                         {
-                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
                             {
-                                Task.Run(() => S2出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName));
+                                ProgressState = false;
+                                Task.Run(() => S2出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
                             }
                         }
                         catch (Exception ex)
@@ -1666,7 +1688,7 @@ namespace MainForm
                             string str = ex.StackTrace;
                             AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
                         }
-                        #endregion 
+                        #endregion 
 
 
                         UpdatePLCMonitor(1, plcNo, 1);  // 更新PLC状态的UI  // 更新PLC状态的UI
@@ -1700,18 +1722,19 @@ namespace MainForm
         /// </summary>
         /// <param name="plcNo">PLC编号</param>
         /// <param name="stationNameStr">工站全称</param>
-        private void S2进站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,string tagBarsetName)
+        private void S2进站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,string tagBarsetName, out bool ProgressState)
         {
             Stopwatch stopwatch1 = new Stopwatch();
             Stopwatch stopwatch2 = new Stopwatch();
+            ProgressState = true;
             try
             {
                 stopwatch1.Start();
                 string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品SN(物料码)
-                sn = sn.Replace("\0", "");
+                string MachineId = GlobalContext.S1_MachineId;  // 装备ID(可配置)
+                string StationId = GlobalContext.S1_StationId;  // 工位ID(可配置)
                 string strCarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode;  // 产品SN(物料码)
                 strCarrierBarcode = strCarrierBarcode.Replace("\0", "");
-
                 //载具码验证产品码    错误码111
                 string strProductBarcode = SQLHelper.GetProductBarcodeByCarrierCode(strCarrierBarcode);
                 if (string.IsNullOrEmpty(strProductBarcode))
@@ -1720,26 +1743,32 @@ namespace MainForm
                 }
                 if (!string.IsNullOrEmpty(strProductBarcode) && !string.IsNullOrEmpty(sn) && strProductBarcode!=sn)
                 {
-                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC S2 上盖板上料装备未能成功绑定载具信息");
+                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC S2 上盖板上料装备PLC返回产品码与载具绑定物料码不同");
                 }
 
                 // 产品SN(物料码)校验
                 List <TestItem> item = new List<TestItem>();
                 stopwatch2.Start();
-                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item);
+                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
                 stopwatch2.Stop();
 
                 //指令执行结果 1:OK   110:失败
-                byte cmdToPC = (byte)(result == 1 ? 1 : 110);
+                byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
+
+                if (!string.IsNullOrEmpty(strProductBarcode) && !string.IsNullOrEmpty(sn) && strProductBarcode != sn)
+                {
+                   mesResultFrmWeb = 111;
+                }
 
                 //进站结果写入PLC
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = cmdToPC;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 1;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
 
-                if (string.IsNullOrEmpty(sn))
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+
+                if (string.IsNullOrEmpty(sn) && !string.IsNullOrEmpty(strProductBarcode))
                 {
                     BarcodeSet_t BarcodeToPlc= new BarcodeSet_t();
                     BarcodeToPlc.strCarrierBarcode = strCarrierBarcode;
@@ -1752,11 +1781,11 @@ namespace MainForm
                 string str = ex.StackTrace;
                 AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
 
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 110;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
             }
 
             stopwatch1.Stop();
@@ -1766,8 +1795,9 @@ namespace MainForm
         /// <summary>
         /// [S2] 上盖板上料装备 - 出站接口
         /// </summary>
-        private void S2出站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName)
+        private void S2出站(int plcNo, string stationNameStr, OP20_MesData_t stPLC_MesData, string tagMesCommName,string stationCode,string stationName, out bool ProgressState)
         {
+            ProgressState = true;
             Stopwatch stopwatch1 = new Stopwatch();
             Stopwatch stopwatch2 = new Stopwatch();
 
@@ -1776,13 +1806,17 @@ namespace MainForm
             {
                 stopwatch1.Start();
 
+                string equipmentCode = GlobalContext.LineCode + "-" + stationCode;  // 设备编号
+                string processItem = stationName;  // 测试项目
+                string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
+                string supplierCode = "";     // 供应商代码
                 string workorder_code = GlobalContext.WorkOrderCode;  // 工单号
                 string batch_num = GlobalContext.BatchNumber;         // 批次号
-                string mtltmrk = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品条码;               // 产品型号
-                mtltmrk = mtltmrk.Replace("\0", "");
+                string mtltmrk = GlobalContext.Mtltmrk;               // 产品型号
+                string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品条码;
                 string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode;  // 载具条码;
-                CarrierBarcode = CarrierBarcode.Replace("\0", "");
-
+                string MachineId = GlobalContext.S1_MachineId;  // 装备id(可配置)  // ZS
+                string StationId = GlobalContext.S1_StationId;  // ⼯位ID(可配置)  // ZS
                 int a1Result = (int)stPLC_MesData.iotData.testStatus;          // 产品结果
                 bool pass = a1Result == 1;
 
@@ -1801,20 +1835,20 @@ namespace MainForm
                 });
 
                 //保存PLC返回MES数据到本地
-         
 
-                int result1 = SwitctProcessData(stationNameStr, items, "", ""
-                    , workorder_code, batch_num, mtltmrk, "", "", "", pass, CarrierBarcode, "1");
 
-                byte cmdToPC = (byte)(result1 == 1 ? 1 : 110);
+                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
+   , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
+
+                byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
 
                 stopwatch2.Start();
                 //进站结果写入PLC
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = cmdToPC;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 1;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
                 stopwatch2.Stop();
 
                 WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
@@ -1822,11 +1856,11 @@ namespace MainForm
             catch (Exception ex)
             {
                 stopwatch2.Start();
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 110;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
                 stopwatch2.Stop();
 
                 string str = ex.StackTrace;
@@ -1951,148 +1985,143 @@ namespace MainForm
         /// [S3] 值板机
         /// </summary>
         /// <param name="plcNo">PLC编号</param>
-        //private void ReadStation_S3(int plcNo)
-        //{
-        //    string stationCode = "[S3]";
-        //    string stationName = "点散热胶装备";
-        //    string stationNameStr = stationCode + stationName;
-        //    string tagBaseName = "g_OP30_MES";   //标签变量名称
-        //    string tagMesCommName = "mesCommToPC";   //标签变量名称
-        //    string tagAgvCommName = "agvCommFrmPC";
-        //    string tagBarsetName = "BarcodeSet";
-
-        //    OP30_MesData_t stPLC_MesData;        //PLC的MES数据
-        //    (int, string) result;
-
-        //    #region 创建字典
-        //    // 触发信号字典 赋值
-        //    s3PLCSignal_Old.Add("c1PLC_FLAG_Check", 0);   // PLC_FLAG 进站校验
-        //    s3PLCSignal_Old.Add("c1PLC_FLAG_Unbind", 0);  // PLC_FLAG 二穴载具解绑
-        //    s3PLCSignal_Old.Add("c1PLC_FLAG_Bind", 0);    // PLC_FLAG 二穴载具绑定
-        //    s3PLCSignal_Old.Add("c1PLC_FLAG", 0);         // PLC_FLAG 出站接口
-        //    s3PLCSignal_Old.Add("c1OEEPLC_FLAG", 0);      // PLC_FLAG 节拍接口
-
-        //    // PLC数据字典 赋值
-        //    s3PLCData.Add("c1PLC_FLAG_Check", 0);    // PLC_FLAG 进站校验
-        //    s3PLCData.Add("c1MES_FLAG_Check", 0);    // MES_FLAG
-        //    s3PLCData.Add("c1ProductSN_Check", "");  // 产品SN(二穴载具SN)
-        //    s3PLCData.Add("c1PLC_FLAG_Unbind", 0);       // PLC_FLAG 二穴载具解绑
-        //    s3PLCData.Add("c1MES_FLAG_Unbind", 0);       // MES_FLAG
-        //    //s3PLCData.Add("c1ProductSN_Check", "");      // 产品SN(二穴载具SN)
-        //    s3PLCData.Add("c1VehicleCavity_Unbind", 0);  // 二穴载具穴位号(产品取自二穴载具哪个穴位)
-        //    s3PLCData.Add("c1PLC_FLAG_Bind", 0);           // PLC_FLAG 二穴载具绑定
-        //    s3PLCData.Add("c1MES_FLAG_Bind", 0);           // MES_FLAG
-        //    //s3PLCData.Add("c1ProductSN_Check", "");        // 产品SN(二穴载具SN)
-        //    s3PLCData.Add("c1CavityReverse_Bind", 0);      // 是否是两个穴位交换
-        //    s3PLCData.Add("c1VehicleCavityFr_Bind", 0);    // 来源穴位号(产品取自二穴载具哪个穴位)
-        //    s3PLCData.Add("c1VehicleCavityTo_Bind", 0);    // 目标载具穴位号(产品放到二穴载具哪个穴位)
-        //    s3PLCData.Add("c1PLC_FLAG", 0);         // PLC_FLAG 出站接口
-        //    s3PLCData.Add("c1MES_FLAG", 0);         // MES_FLAG
-        //    s3PLCData.Add("c1ProductSN", "");       // 产品SN(一穴载具SN)
-        //    //s3PLCData.Add("c1ProductSN_Check", ""); // 二穴载具SN(产品取自哪个二穴载具)
-        //    s3PLCData.Add("c1VehicleCavity", 0);   // 二穴载具穴位号(产品取自二穴载具哪个穴位)
-        //    s3PLCData.Add("c1Result", 0);          // 产品结果
-        //    s3PLCData.Add("c1OEEPLC_FLAG", 0);  // PLC_FLAG 节拍接口
-        //    s3PLCData.Add("c1OEEMES_FLAG", 0);  // MES_FLAG
-        //    s3PLCData.Add("c1OEEProductSN", "");// 产品SN(载具SN)
-        //    s3PLCData.Add("c1OEEType", 0);      // 节拍类型(plc写入)
-        //    #endregion 创建字典
+        private void ReadStation_S3(int plcNo)
+        {
+            string stationCode = "[S3]";
+            string stationName = "点散热胶装备";
+            string stationNameStr = stationCode + stationName;
+            string tagBaseName = "g_OP30_MES";   //标签变量名称
+            string tagMesCommName = "mesCommToPC";   //标签变量名称
+            string tagAgvCommName = "agvCommFrmPC";
+            string tagBarsetName = "BarcodeSet";
 
-        //    while (true)
-        //    {
-        //        try
-        //        {
-        //            if (!GlobalContext._IsCon_Funs2)
-        //            {
-        //                UpdatePLCMonitor(1, plcNo, 0);
-        //                continue;
-        //            }
-        //            if (Funs[plcNo].IsConnected)  // 检查PLC是否已连接上
-        //            {
-        //                Stopwatch stopwatch1 = new Stopwatch();
-        //                Stopwatch stopwatch2 = new Stopwatch();
-        //                stopwatch1.Start();
-
-        //                stopwatch2.Start();
-        //                #region 一次性读取所有数据
-        //                // 一次性读取所有数据
-        //                result = Funs[plcNo].Read_SingleTag<OP30_MesData_t>(tagBaseName, 1, out stPLC_MesData);  //读取单个结构体数据
-        //                if (result.Item1 != 0)
-        //                {
-        //                    //richTextBox1.AppendText("\n" + strRet);
-        //                }
-        //                else
-        //                {
-        //                    //richTextBox1.AppendText("\n" + "读取成功");
-        //                }
-        //                #endregion 一次性读取所有数据
-        //                stopwatch2.Stop();
+            OP30_MesData_t stPLC_MesData;        //PLC的MES数据
+            (int, string) result;
 
-        //                #region 回写操作,写后清空flag
-        //                mesCommToPC WriteBackToPLC = new mesCommToPC();
-        //                result = Funs[plcNo].Write_SingleTag<mesCommToPC>(tagBaseName + "." + tagMesCommName, 1, WriteBackToPLC);  //写入单个结构体数据
-        //                #endregion 回写操作,写后清空flag
+            #region 创建字典
+            // 触发信号字典 赋值
+            s3PLCSignal_Old.Add("c1PLC_FLAG_Check", 0);   // PLC_FLAG 进站校验
+            s3PLCSignal_Old.Add("c1PLC_FLAG_Unbind", 0);  // PLC_FLAG 二穴载具解绑
+            s3PLCSignal_Old.Add("c1PLC_FLAG_Bind", 0);    // PLC_FLAG 二穴载具绑定
+            s3PLCSignal_Old.Add("c1PLC_FLAG", 0);         // PLC_FLAG 出站接口
+            s3PLCSignal_Old.Add("c1OEEPLC_FLAG", 0);      // PLC_FLAG 节拍接口
 
-        //                #region 左边进站
-        //                try
-        //                {
-        //                    if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && !string.IsNullOrEmpty(stPLC_MesData.iotData.Left.work_type.ToString()))
-        //                    {
-        //                        Task.Run(() => S3进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName));
-        //                        //进站
-        //                    }
-        //                }
-        //                catch (Exception ex)
-        //                {
-        //                    //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6);  // 6代表上位机报警
+            // PLC数据字典 赋值
+            s3PLCData.Add("c1PLC_FLAG_Check", 0);    // PLC_FLAG 进站校验
+            s3PLCData.Add("c1MES_FLAG_Check", 0);    // MES_FLAG
+            s3PLCData.Add("c1ProductSN_Check", "");  // 产品SN(二穴载具SN)
+            s3PLCData.Add("c1PLC_FLAG_Unbind", 0);       // PLC_FLAG 二穴载具解绑
+            s3PLCData.Add("c1MES_FLAG_Unbind", 0);       // MES_FLAG
+            //s3PLCData.Add("c1ProductSN_Check", "");      // 产品SN(二穴载具SN)
+            s3PLCData.Add("c1VehicleCavity_Unbind", 0);  // 二穴载具穴位号(产品取自二穴载具哪个穴位)
+            s3PLCData.Add("c1PLC_FLAG_Bind", 0);           // PLC_FLAG 二穴载具绑定
+            s3PLCData.Add("c1MES_FLAG_Bind", 0);           // MES_FLAG
+            //s3PLCData.Add("c1ProductSN_Check", "");        // 产品SN(二穴载具SN)
+            s3PLCData.Add("c1CavityReverse_Bind", 0);      // 是否是两个穴位交换
+            s3PLCData.Add("c1VehicleCavityFr_Bind", 0);    // 来源穴位号(产品取自二穴载具哪个穴位)
+            s3PLCData.Add("c1VehicleCavityTo_Bind", 0);    // 目标载具穴位号(产品放到二穴载具哪个穴位)
+            s3PLCData.Add("c1PLC_FLAG", 0);         // PLC_FLAG 出站接口
+            s3PLCData.Add("c1MES_FLAG", 0);         // MES_FLAG
+            s3PLCData.Add("c1ProductSN", "");       // 产品SN(一穴载具SN)
+            //s3PLCData.Add("c1ProductSN_Check", ""); // 二穴载具SN(产品取自哪个二穴载具)
+            s3PLCData.Add("c1VehicleCavity", 0);   // 二穴载具穴位号(产品取自二穴载具哪个穴位)
+            s3PLCData.Add("c1Result", 0);          // 产品结果
+            s3PLCData.Add("c1OEEPLC_FLAG", 0);  // PLC_FLAG 节拍接口
+            s3PLCData.Add("c1OEEMES_FLAG", 0);  // MES_FLAG
+            s3PLCData.Add("c1OEEProductSN", "");// 产品SN(载具SN)
+            s3PLCData.Add("c1OEEType", 0);      // 节拍类型(plc写入)
+            #endregion 创建字典
 
-        //                    string str = ex.StackTrace;
-        //                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
-        //                }
-        //                #endregion 进站
+            while (true)
+            {
+                try
+                {
+                    if (!GlobalContext._IsCon_Funs2)
+                    {
+                        UpdatePLCMonitor(1, plcNo, 0);
+                        continue;
+                    }
+                    if (Funs[plcNo].IsConnected)  // 检查PLC是否已连接上
+                    {
+                        Stopwatch stopwatch1 = new Stopwatch();
+                        Stopwatch stopwatch2 = new Stopwatch();
+                        stopwatch1.Start();
 
+                        stopwatch2.Start();
+                        #region 一次性读取所有数据
+                        // 一次性读取所有数据
+                        result = Funs[plcNo].Read_SingleTag<OP30_MesData_t>(tagBaseName, 1, out stPLC_MesData);  //读取单个结构体数据
+                        if (result.Item1 != 0)
+                        {
+                            //richTextBox1.AppendText("\n" + strRet);
+                        }
+                        else
+                        {
+                            //richTextBox1.AppendText("\n" + "读取成功");
+                        }
+                        #endregion 一次性读取所有数据
+                        stopwatch2.Stop();
 
-        //                #region 左边出站
-        //                try
-        //                {
-        //                    if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
-        //                    {
-        //                        Task.Run(() => S3出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName,"Left"));
-        //                    }
-        //                }
-        //                catch (Exception ex)
-        //                {
-        //                    string str = ex.StackTrace;
-        //                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
-        //                }
-        //                #endregion 出站
+                        #region 左边进站
+                        try
+                        {
+                            //if (stPLC_MesData.Left.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && !string.IsNullOrEmpty(stPLC_MesData.iotData.Left.work_type.ToString()))
+                            //{
+                            //    Task.Run(() => S3进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, tagBaseName + "." + tagBarsetName));
+                            //    //进站
+                            //}
+                        }
+                        catch (Exception ex)
+                        {
+                            //Funs[plcNo].WriteMultipleRegisters<short>(2003, (short)6);  // 6代表上位机报警
 
+                            string str = ex.StackTrace;
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                        }
+                        #endregion 进站
 
-        //                UpdatePLCMonitor(1, plcNo, 1);  // 更新PLC状态的UI  // 更新PLC状态的UI
 
-        //                stopwatch1.Stop();
-        //                //if (stopwatch1.ElapsedMilliseconds > 60)  // ZS 稳定后取消注释该项
-        //                OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
-        //            }
-        //            else
-        //            {
-        //                UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
-        //                AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
+                        #region 左边出站
+                        try
+                        {
+                            //if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation)
+                            //{
+                            //    Task.Run(() => S3出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, "Left"));
+                            //}
+                        }
+                        catch (Exception ex)
+                        {
+                            string str = ex.StackTrace;
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                        }
+                        #endregion 出站
 
-        //                Funs[plcNo].Connect();
-        //            }
-        //        }
-        //        catch (Exception ex)
-        //        {
-        //            UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
-        //            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
 
-        //            //Funs[plcNo].ReConnect();
-        //        }
+                        UpdatePLCMonitor(1, plcNo, 1);  // 更新PLC状态的UI  // 更新PLC状态的UI
 
-        //        Thread.Sleep(IntervalReadPLC);
-        //    }
-        //}
+                        stopwatch1.Stop();
+                        //if (stopwatch1.ElapsedMilliseconds > 60)  // ZS 稳定后取消注释该项
+                        OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
+                    }
+                    else
+                    {
+                        UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
+                        AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
+
+                        Funs[plcNo].Connect();
+                    }
+                }
+                catch (Exception ex)
+                {
+                    UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
+                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
+
+                    //Funs[plcNo].ReConnect();
+                }
+
+                Thread.Sleep(IntervalReadPLC);
+            }
+        }
 
         /// <summary>
         /// [S3] 点散热胶装备
@@ -2125,19 +2154,15 @@ namespace MainForm
                 // 产品SN(物料码)校验
                 List<TestItem> item = new List<TestItem>();
                 stopwatch2.Start();
-                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item);
+                int result = 0;
+                //int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item);
                 stopwatch2.Stop();
 
                 //指令执行结果 1:OK   110:失败
                 byte cmdToPC = (byte)(result == 1 ? 1 : 110);
 
                 //进站结果写入PLC
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = cmdToPC;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 1;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
-
+        
                 if (string.IsNullOrEmpty(sn))
                 {
                     BarcodeSet_t BarcodeToPlc = new BarcodeSet_t();
@@ -2151,11 +2176,7 @@ namespace MainForm
                 string str = ex.StackTrace;
                 AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
 
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 110;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+           
             }
 
             stopwatch1.Stop();
@@ -2210,19 +2231,15 @@ namespace MainForm
 
                 //保存PLC返回MES数据到本地
 
-
-                int result1 = SwitctProcessData(stationNameStr, items, "", ""
-                    , workorder_code, batch_num, mtltmrk, "", "", "", pass, CarrierBarcode, "1");
+                int result1 = 0;
+                //int result1 = SwitctProcessData(stationNameStr, items, "", ""
+                //    , workorder_code, batch_num, mtltmrk, "", "", "", pass, CarrierBarcode, "1");
 
                 byte cmdToPC = (byte)(result1 == 1 ? 1 : 110);
 
                 stopwatch2.Start();
                 //进站结果写入PLC
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = cmdToPC;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 1;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+             
                 stopwatch2.Stop();
 
                 WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
@@ -2230,11 +2247,7 @@ namespace MainForm
             catch (Exception ex)
             {
                 stopwatch2.Start();
-                mesCommToPC MesToPLC = new mesCommToPC();
-                MesToPLC.cmd = 0;
-                MesToPLC.cmdParam = 0; //指令参数
-                MesToPLC.cmdResult = 110;
-                Funs[plcNo].Write_SingleTag<mesCommToPC>(tagMesCommName, 1, MesToPLC);
+           
                 stopwatch2.Stop();
 
                 string str = ex.StackTrace;
@@ -2289,8 +2302,9 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-                        , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, productSN, pass, sn, "1");
+                int result1 = 0;
+                //int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
+                //        , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, productSN, pass, sn, "1");
 
                 short result = result1 == 1 ? (short)1 : (short)2;
 
@@ -3115,7 +3129,8 @@ namespace MainForm
                         Parameter_value = "1",
                     });
                     stopwatch2.Start();
-                    int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
+                    int result = 0;
+                    //int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
                     stopwatch2.Stop();
                     d1VehicleScanCode = (short)result == 1 ? d1VehicleScanCode : (short)result;
                 }
@@ -3219,8 +3234,9 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                int result1 = SwitctProcessData(stationNameStr, items1, equipmentCode, processItem
-                    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, d1VehicleCode1, "1");
+                int result1 = 0;
+                //int result1 = SwitctProcessData(stationNameStr, items1, equipmentCode, processItem
+                    //, workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, d1VehicleCode1, "1");
                 //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
                 short result = result1 == 1 ? (short)1 : (short)3;
 
@@ -3482,7 +3498,7 @@ namespace MainForm
                             Parameter_name = "载具穴号",
                             Parameter_value = "1",
                         });
-                        results[i] = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, portNo, item);
+                        results[i] = 0;//SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, portNo, item);
                     }
                 }
                 stopwatch2.Stop();
@@ -3590,8 +3606,11 @@ namespace MainForm
                             Parameter_name = "产品结果",
                             Parameter_value = isPass ? "OK" : "NG",
                         });
-                        int mesResult = SwitctProcessData(stationNameStr, items1, "", ""
-                            , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, portNo, isPass, vehicleCodes[i], "1");
+
+                        int mesResult = 0;
+                        //int mesResult = SwitctProcessData(stationNameStr, items1, "", ""
+                        //    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, portNo, isPass, vehicleCodes[i], "1");
+
                         results[i] = mesResult == 1 ? 1 : 2;
                     }
                 }
@@ -3687,7 +3706,7 @@ namespace MainForm
                             Parameter_name = "载具穴号",
                             Parameter_value = "1",
                         });
-                        results[i] = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, portNo, item);
+                        results[i] = 0;// SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, portNo, item);
                     }
                 }
                 stopwatch2.Stop();
@@ -3795,8 +3814,10 @@ namespace MainForm
                             Parameter_name = "产品结果",
                             Parameter_value = isPass ? "OK" : "NG",
                         });
-                        int mesResult = SwitctProcessData(stationNameStr, items1, "", ""
-                            , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, portNo, isPass, vehicleCodes[i], "1");
+                        int mesResult = 0;
+                        //int mesResult = SwitctProcessData(stationNameStr, items1, "", ""
+                        //    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, portNo, isPass, vehicleCodes[i], "1");
+                       
                         results[i] = mesResult == 1 ? 1 : 2;
                     }
                 }
@@ -3940,7 +3961,7 @@ namespace MainForm
                         Parameter_value = "1",
                     });
                     stopwatch2.Start();
-                    int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
+                    int result = 0;//SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
                     stopwatch2.Stop();
                     d5VehicleScanCode = (short)result == 1 ? d5VehicleScanCode : (short)result;
                 }
@@ -4043,8 +4064,9 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                int result1 = SwitctProcessData(stationNameStr, items1, equipmentCode, processItem
-                    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, d5VehicleCode1, "1");
+                int result1 = 0;
+                //int result1 = SwitctProcessData(stationNameStr, items1, equipmentCode, processItem
+                  //  , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, d5VehicleCode1, "1");
                 //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
                 short result = result1 == 1 ? (short)1 : (short)3;
 
@@ -4510,7 +4532,8 @@ namespace MainForm
                     Parameter_value = "1",
                 });
                 stopwatch2.Start();
-                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
+                int result = 0;
+                //int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, partNo, item);
                 stopwatch2.Stop();
                 short e1MES_FLAG_Check = (short)result;
 
@@ -4587,8 +4610,9 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
-                    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, partNo, pass, sn, "1");
+                int result1 = 0;
+                //int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
+                    //, workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, partNo, pass, sn, "1");
                 //int result = result1 == 1 ? 1 : (GlobalContext.IsSendProcessData ? 4 : 1);
                 short result = result1 == 1 ? (short)1 : (short)3;
 
@@ -5139,13 +5163,13 @@ namespace MainForm
         /// <param name="sn">产品SN</param>
         /// <param name="items">进站数据</param>
         /// <returns>1成功;5MES报警;6上位机报警</returns>
-        public int SaveStationInData(string stationNameStr, string workorder_code, string mtltmrk, string sn, List<TestItem> items)
+        public int SaveStationInData(string stationNameStr, string workorder_code, string mtltmrk, string sn, List<TestItem> items,string MachineId,string StationId)
         {
             int result = 0;
 
             XmMES_StationInRequest_Body inRequest_Body = new XmMES_StationInRequest_Body();
-            inRequest_Body.machineId = GlobalContext.S1_MachineId;  // 装备ID(可配置)
-            inRequest_Body.stationId = GlobalContext.S1_StationId;  // ⼯位ID(可配置)
+            inRequest_Body.machineId = MachineId;  // 装备ID(可配置)
+            inRequest_Body.stationId = StationId;  // ⼯位ID(可配置)
             inRequest_Body.clientMac = GlobalContext.MacStr;                               // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
             inRequest_Body.clientTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");  // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
             inRequest_Body.unitSn = sn;                             // 产品SN
@@ -5235,10 +5259,10 @@ namespace MainForm
         /// <returns>上传成功时返回1;失败返回0</returns>
         private int SwitctProcessData(string stationNameStr, List<TestItem> items, string equipmentCode, string processItem,
             string workorder_code, string batch_num, string mtltmrk, string proDate,
-            string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot)
+            string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot, string MachineId, string StationId)
         {
             return SaveProcessDataByDB(stationNameStr, items, equipmentCode, processItem, workorder_code, batch_num, mtltmrk,
-                proDate, supplierCode, sn, pass, vehicleSn, vehicleSlot);
+                proDate, supplierCode, sn, pass, vehicleSn, vehicleSlot, MachineId, StationId);
         }
 
         /// <summary>
@@ -5256,7 +5280,7 @@ namespace MainForm
         /// <returns>上传成功时返回1;失败返回0</returns>
         public int SaveProcessDataByDB(string stationNameStr, List<TestItem> items, string equipmentCode,
             string processItem, string workorder_code, string batch_num, string mtltmrk,
-            string proDate, string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot)
+            string proDate, string supplierCode, string sn, bool pass, string vehicleSn, string vehicleSlot,string machineId,string stationId)
         {
             int upload = 0;
             int result = 0;
@@ -5284,8 +5308,8 @@ namespace MainForm
                     string id = processData.ID.Copy();
 
                     XmMES_StationOutRequest_Body outRequest_Body = new XmMES_StationOutRequest_Body();
-                    outRequest_Body.machineId = GlobalContext.S1_MachineId;  // 装备id(可配置)  // ZS
-                    outRequest_Body.stationId = GlobalContext.S1_StationId;  // ⼯位ID(可配置)  // ZS
+                    outRequest_Body.machineId = machineId;  // 装备id(可配置)  // ZS
+                    outRequest_Body.stationId = stationId;  // ⼯位ID(可配置)  // ZS
                     outRequest_Body.clientMac = GlobalContext.MacStr;    // 客⼾端本机MAC地址,格式:XX-XX-XX-XX-XX-XX
                     outRequest_Body.clientTime = processData.Test_time;  // 客⼾端请求时间,格式yyyy-MM-dd HH:mm:ss.fff
                     outRequest_Body.unitSn = sn;                         // 产品SN