Browse Source

iot故障及iot测试数据对接

WIN-GH9CEESPLTB\Administrator 4 months ago
parent
commit
5946a15a40

+ 108 - 8
MainForm/ClassFile/ProjectClass/AlarmData.cs

@@ -12,21 +12,46 @@ namespace MainForm
         /// <summary>
         /// 主键
         /// </summary>
-        public string GUID;
+        public string GUID = "";
 
         /// <summary>
-        /// 线体名称
+        /// 工位名称;[S1]Tray盘上料装备
         /// </summary>
-        public string LineName;
+        public string LineName = "";
+
+        /// <summary>
+        /// 工站全称; [S1]Tray盘上料装备\n[S2]...\n...
+        /// </summary>
+        public string PlcStation = "";
+
+        /// <summary>
+        /// 分类层级1;
+        /// </summary>
+        public string Type1 { get; set; } = "";
+
+        /// <summary>
+        /// 分类层级2;
+        /// </summary>
+        public string Type2 { get; set; } = "";
+
+        /// <summary>
+        /// 分类层级3;
+        /// </summary>
+        public string Type3 { get; set; } = "";
+
+        /// <summary>
+        /// 分类层级4
+        /// </summary>
+        public string Type4 = "";
 
         /// <summary>
         /// 报警类型
         /// </summary>
-        public string AlarmType;
+        public string AlarmType = "";
         /// <summary>
         /// 报警内容
         /// </summary>
-        public string AlarmDesc;
+        public string AlarmDesc = "";
 
         /// <summary>
         /// 开始时间
@@ -40,6 +65,15 @@ namespace MainForm
         /// 耗时(s)
         /// </summary>
         public int PersistTime;
+
+        /// <summary>
+        /// Iot上传结果
+        /// </summary>
+        public int IotUpload = 0;
+        /// <summary>
+        /// Iot上传结果
+        /// </summary>
+        public string IotResultMsg = "";
         #endregion 数据
 
         /// <summary>
@@ -185,8 +219,75 @@ PersistTime
     /// </summary>
     public class Alarm
     {
-        public string 报警类型 { get; set; } = string.Empty;
-        public string 报警详情 { get; set; } = string.Empty;
+        /// <summary>
+        /// 设备名;
+        /// </summary>
+        public string plcName { get; set; } = string.Empty;
+        /// <summary>
+        /// 设备名;
+        /// </summary>
+        public string plcDeviceCode { get; set; } = string.Empty;
+        /// <summary>
+        /// 分类层级1;
+        /// </summary>
+        public string type1 { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 分类层级1;中文
+        /// </summary>
+        public string type1CH { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 分类层级2;
+        /// </summary>
+        public string type2 { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 分类层级2;中文
+        /// </summary>
+        public string type2CH { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 分类层级3;
+        /// </summary>
+        public string type3 { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 分类层级3;中文
+        /// </summary>
+        public string type3CH { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 故障部件英文;overall_module
+        /// </summary>
+        public string type4 { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 故障部件中文
+        /// </summary>
+        public string type4CH { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 故障编码;A40001
+        /// </summary>
+        public string fault_code { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 故障名称;AL[1000]_系统_HMI急停故障
+        /// </summary>
+        public string fault_name { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 故障描述;AL[1000]_系统_HMI急停故障
+        /// </summary>
+        public string fault_desc { get; set; } = string.Empty;
+
+        public string PLC地址 { get; set; } = string.Empty;
+        //记录当前警报数组下标,例:fault_codes[0].17   group_index=0
+        public int group_index { get; set; } = 0;
+
+        public string 工位 { get; set; } = string.Empty;
+
 
         /// <summary>
         /// true 报警
@@ -196,7 +297,6 @@ PersistTime
 
         public bool 是否报警 { get; set; } = false;
 
-        public int 关联的PLC地址 { get; set; }
 
         public AlarmData 报警数据 = null;
     }

+ 5 - 2
MainForm/ClassFile/ProjectClass/GlobalContext.cs

@@ -34,8 +34,9 @@ namespace MainForm
         public static string MqttLogDir = MainDir + @"MqttLog\";  // mqtt日志
         public static string MqttCallbackDir = MqttLogDir + @"Callback\";     // mqtt日志 - Callback内容
         public static string MqttDeviceStateDir = MqttLogDir + @"设备状态\";  // mqtt日志 - 设备状态日志
-        public static string MqttInputBeginDir = MqttLogDir + @"节拍日志";    // mqtt日志 - 节拍日志
-        public static string MqttOperateLogDir = MqttLogDir + @"用户操作";    // mqtt日志 - 用户操作日志
+        public static string MqttInputBeginDir = MqttLogDir + @"节拍日志\";    // mqtt日志 - 节拍日志
+        public static string MqttOperateLogDir = MqttLogDir + @"用户操作\";    // mqtt日志 - 用户操作日志
+        public static string MqttAlarmLogDir = MqttLogDir + @"故障日志\";    // mqtt日志 - 用户操作日志
 
         public static string MqttServerPath = AppDomain.CurrentDomain.BaseDirectory + @"\ThingsMode\MqttServer.exe";
         public static string MqttServerName = "MqttServer";
@@ -173,6 +174,8 @@ namespace MainForm
         public static bool IsMqttProcConfig;         // 上传⼯艺配置
         public static string MQTTAppId;            // IOT应用ID
         public static string MQTTAppPwd;           // IOT登录密码
+        public static int IsUsePLCNow { set; get; } = 0;              // 单机模式下,存储当前在用的plcNum
+        public static string IsUseStationName { set; get; } = "";     // 单机模式下,存储当前在用的主工站全称
 
         // IOT-AGV
         public static bool IsUseAGV;  // 是否 启用AGV

+ 15 - 3
MainForm/ClassFile/XiaomiAPI_IOT/Extend/XiaomiMqttClient_FaultLog.cs

@@ -1,4 +1,6 @@
-using Newtonsoft.Json;
+using BZFAStandardLib;
+using Newtonsoft.Json;
+using System;
 
 namespace MainForm.ClassFile.XiaomiAPI
 {
@@ -21,9 +23,10 @@ namespace MainForm.ClassFile.XiaomiAPI
         /// <param name="msg">事件数据;Json</param>
         /// <param name="dataId">自定义事件Id;如:guid</param>
         /// <returns></returns>
-        public static int Write_FaultLog(FaultLogRequest request, string dataId = "")
+        public static (int, string) Write_FaultLog(FaultLogRequest request, string dataId = "")
         {
             int result = 0;
+            string resultStr = "";
 
             string msg = JsonConvert.SerializeObject(request);
             byte[] bytes = ToUTF8(msg);
@@ -36,7 +39,16 @@ namespace MainForm.ClassFile.XiaomiAPI
             else
                 result = WriteWithDataId(faultLogId, bytes, dataId);
 
-            return result;
+            var try1 = Enum.TryParse(result.ToString(), out XiaomiMqttResponse_ErrCode errCode);
+            if (try1)
+                resultStr = errCode.ToString();
+            else
+                resultStr = XiaomiMqttResponse_ErrCode.ERR_UNKOWN.ToString();
+
+            string logPath = GlobalContext.MqttAlarmLogDir + "AlarmType" + DateTime.Now.ToString("yyyyMMdd") + ".txt";
+            FileOperate.NewTxtFile(logPath, "MQTT【故障日志】提交:" + msg + "\r\n==>提交结果:" + resultStr + "");
+
+            return (result, resultStr);
         }
 
         /// <summary>

+ 16 - 4
MainForm/ClassFile/XiaomiAPI_IOT/Extend/XiaomiMqttClient_OperateLog.cs

@@ -1,4 +1,6 @@
-using Newtonsoft.Json;
+using BZFAStandardLib;
+using Newtonsoft.Json;
+using System;
 
 namespace MainForm.ClassFile.XiaomiAPI
 {
@@ -20,9 +22,10 @@ namespace MainForm.ClassFile.XiaomiAPI
         /// <param name="msg">事件数据;Json</param>
         /// <param name="dataId">自定义事件Id;如:guid</param>
         /// <returns></returns>
-        public static int Write_OperateLog(OperateLogRequest request, string dataId = "")
+        public static (int,string) Write_OperateLog(OperateLogRequest request, string dataId = "")
         {
-            int result = 0;
+            int result =0;
+            string resultStr = "";
 
             string msg = JsonConvert.SerializeObject(request);
             byte[] bytes = ToUTF8(msg);
@@ -33,7 +36,16 @@ namespace MainForm.ClassFile.XiaomiAPI
             else
                 result = WriteWithDataId(OperateLogId, bytes, dataId);
 
-            return result;
+            var try1 = Enum.TryParse(result.ToString(), out XiaomiMqttResponse_ErrCode errCode);
+            if (try1)
+                resultStr = errCode.ToString();
+            else
+                resultStr = XiaomiMqttResponse_ErrCode.ERR_UNKOWN.ToString();
+
+            string logPath = GlobalContext.MqttOperateLogDir + "OperationRecord" + DateTime.Now.ToString("yyyyMMdd") + ".txt";
+            FileOperate.NewTxtFile(logPath, "MQTT【用户操作】提交:" + msg + "\r\n==>提交结果:" + resultStr + "");
+
+            return (result, resultStr);
         }
 
         /// <summary>

+ 15 - 3
MainForm/ClassFile/XiaomiAPI_IOT/Extend/XiaomiMqttClient_PassStationResult.cs

@@ -1,5 +1,7 @@
-using Newtonsoft.Json;
+using BZFAStandardLib;
+using Newtonsoft.Json;
 using System;
+using static System.Runtime.CompilerServices.RuntimeHelpers;
 
 namespace MainForm.ClassFile.XiaomiAPI
 {
@@ -20,9 +22,10 @@ namespace MainForm.ClassFile.XiaomiAPI
         /// <param name="msg">事件数据;Json</param>
         /// <param name="dataId">自定义事件Id;如:guid</param>
         /// <returns></returns>
-        public static int Write_PassStationResult(PassStationResultRequest request, string dataId = "")
+        public static (int, string) Write_PassStationResult(PassStationResultRequest request, string dataId = "")
         {
             int result = 0;
+            string resultStr = "";
 
             string msg = JsonConvert.SerializeObject(request);
             byte[] bytes = ToUTF8(msg);
@@ -33,7 +36,16 @@ namespace MainForm.ClassFile.XiaomiAPI
             else
                 result = WriteWithDataId(PassStationResultId, bytes, dataId);
 
-            return result;
+            var try1 = Enum.TryParse(result.ToString(), out XiaomiMqttResponse_ErrCode errCode);
+            if (try1)
+                resultStr = errCode.ToString();
+            else
+                resultStr = XiaomiMqttResponse_ErrCode.ERR_UNKOWN.ToString();
+
+            string logPath = GlobalContext.MqttAlarmLogDir + "PassStationResult" + DateTime.Now.ToString("yyyyMMdd") + ".txt";
+            FileOperate.NewTxtFile(logPath, "MQTT【过站结果】提交:" + msg + "\r\n==>提交结果:" + resultStr + "");
+
+            return (result, resultStr);
         }
 
         /// <summary>

+ 3 - 3
MainForm/ClassFile/XiaomiAPI_IOT/Extend/XiaomiMqttClient_StationInputBegin.cs

@@ -40,7 +40,7 @@ namespace MainForm.ClassFile.XiaomiAPI
             string msg = JsonConvert.SerializeObject(request);
             byte[] bytes = ToUTF8(msg);
 
-            request.action = string.Format(StationInputBeginId, request.action);
+            //request.action = string.Format(StationInputBeginId, request.action);
             // 发送
             if (string.IsNullOrEmpty(deviceCode))
             {
@@ -60,8 +60,8 @@ namespace MainForm.ClassFile.XiaomiAPI
                 resultStr = errCode.ToString();
             else
                 resultStr = XiaomiMqttResponse_ErrCode.ERR_UNKOWN.ToString();
-
-            FileOperate.NewTxtFile(GlobalContext.MqttInputBeginDir, "MQTT【节拍日志】提交:" + msg + "\r\n==>提交结果:" + resultStr + "");
+            string logPath = GlobalContext.MqttInputBeginDir + "beatType" + DateTime.Now.ToString("yyyyMMdd") + ".txt";
+            FileOperate.NewTxtFile(logPath, "MQTT【节拍日志】提交:" + msg + "\r\n==>提交结果:" + resultStr + "");
             return (result, resultStr);
         }
 

+ 525 - 207
MainForm/FaForm/Form_Home.cs

@@ -38,6 +38,9 @@ using System.Numerics;
 using MathNet.Numerics.RootFinding;
 using HslCommunication.Enthernet;
 using BZFAStandardLib;
+using MainForm.ClassFile;
+using NPOI.SS.Formula.Functions;
+using static MainForm.ClassFile.XiaomiAPI.XiaomiMqttClient_Extend;
 
 /*
  * 注:本源码对外提供,所以有些地方使用中文命名方法及变量
@@ -99,6 +102,11 @@ namespace MainForm
 
         private int IntervalAlarm = 1000; //ms 数据(报警)查询与设备运行信息
 
+        /// <summary>
+        /// 设备报警数据
+        /// </summary>
+        uint[] _FaultDatas;
+
         // 软件状态
         private bool IsRun = true;
 
@@ -165,41 +173,67 @@ namespace MainForm
             try
             {
                 AddMessage(LogType.Info, "开始初始化程序");
-                InitalDicAlarm(); // 实例化报警字典
 
                 //组建plc对象字典
                 //plc1Alarm = new ModbusClientHelper(GlobalContext.Machine1Address, GlobalContext.MachinePort);
                 //plc1Alarm = new Inovance_EIP(GlobalContext.PCAddress, GlobalContext.Machine1Address);
 
                 if (GlobalContext.IsUsePLC1)
-                    FunsEip.Add(1,
-                        new Inovance_EIP(GlobalContext.PC1Address, GlobalContext.Machine1Address)); //OP10 壳体清洁上料装备
-                if (GlobalContext.IsUsePLC2)
-                    //Funs.Add(2, new ModbusClientHelper(GlobalContext.Machine2Address, GlobalContext.MachinePort, 2001));  // FCT(板测),
-                    FunsEip.Add(2,
-                        new Inovance_EIP(GlobalContext.PC2Address, GlobalContext.Machine2Address)); //OP20 顶盖上料设备
-                if (GlobalContext.IsUsePLC3)
-                    FunsEip.Add(3,
-                        new Inovance_EIP(GlobalContext.PC3Address, GlobalContext.Machine3Address)); //OP30 点胶设备
+                {
+                    GlobalContext.IsUsePLCNow = 1;
+                    GlobalContext.IsUseStationName = "[OP10]壳体清洁上料";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC1Address, GlobalContext.Machine1Address)); //OP10 壳体清洁上料装备
+                }
+                if (GlobalContext.IsUsePLC2) 
+                {
+                    GlobalContext.IsUsePLCNow = 2;
+                    GlobalContext.IsUseStationName = "[OP20]上盖板上料装备";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC2Address, GlobalContext.Machine2Address)); //OP20 顶盖上料设备
+                }
+                if (GlobalContext.IsUsePLC3) 
+                {
+                    GlobalContext.IsUsePLCNow = 3;
+                    GlobalContext.IsUseStationName = "[OP30]点散热胶装备";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC3Address, GlobalContext.Machine3Address)); //OP30 点胶设备
+                }
                 if (GlobalContext.IsUsePLC4)
-                    FunsEip.Add(4,
-                        new Inovance_EIP(GlobalContext.PC4Address, GlobalContext.Machine4Address)); //OP40 3D胶线检测  
+                {
+                    GlobalContext.IsUsePLCNow = 4;
+                    GlobalContext.IsUseStationName = "[OP40]胶线检测";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC4Address, GlobalContext.Machine4Address)); //OP40 3D胶线检测  
+                }
                 if (GlobalContext.IsUsePLC5)
-                    FunsEip.Add(5,
-                        new Inovance_EIP(GlobalContext.PC5Address, GlobalContext.Machine5Address)); //OP50 ADD PCB板上料
+                {
+                    GlobalContext.IsUsePLCNow = 5;
+                    GlobalContext.IsUseStationName = "[OP50]ADD板上料组装装备";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC5Address, GlobalContext.Machine5Address)); //OP50 ADD PCB板上料
+                }
                 if (GlobalContext.IsUsePLC6)
-                    FunsEip.Add(6,
-                        new Inovance_EIP(GlobalContext.PC6Address, GlobalContext.Machine6Address)); //OP60 顶盖装配
+                {
+                    GlobalContext.IsUsePLCNow = 6;
+                    GlobalContext.IsUseStationName = "[OP60]组上盖板";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC6Address, GlobalContext.Machine6Address)); //OP60 顶盖装配
+                }
                 if (GlobalContext.IsUsePLC7)
-                    FunsEip.Add(7,
-                        new Inovance_EIP(GlobalContext.PC7Address, GlobalContext.Machine7Address)); //OP70 锁螺丝
+                {
+                    GlobalContext.IsUsePLCNow = 7;
+                    GlobalContext.IsUseStationName = "[OP70]上盖板锁螺丝";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC7Address, GlobalContext.Machine7Address)); //OP70 锁螺丝
+                }
                 if (GlobalContext.IsUsePLC8)
-                    FunsEip.Add(8,
-                        new Inovance_EIP(GlobalContext.PC8Address,
-                            GlobalContext.Machine8Address)); //OP80 3D螺丝高度检测,NG出料站
+                {
+                    GlobalContext.IsUsePLCNow = 8;
+                    GlobalContext.IsUseStationName = "[OP80]NG下料";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC8Address, GlobalContext.Machine8Address)); //OP80 3D螺丝高度检测,NG出料站
+                }
                 if (GlobalContext.IsUsePLC9)
-                    FunsEip.Add(9,
-                        new Inovance_EIP(GlobalContext.PC9Address, GlobalContext.Machine9Address)); //OP90 下料站
+                {
+                    GlobalContext.IsUsePLCNow = 9;
+                    GlobalContext.IsUseStationName = "[OP90]半成品下料";
+                    FunsEip.Add(GlobalContext.IsUsePLCNow, new Inovance_EIP(GlobalContext.PC9Address, GlobalContext.Machine9Address)); //OP90 下料站
+                }
+                (bool,string)DicResult=InitalDicAlarm(); // 实例化报警字典
+                AddMessage(LogType.Info, DicResult.Item2);
 
                 foreach (Inovance_EIP plcEIP in FunsEip.Values)
                 {
@@ -727,17 +761,13 @@ namespace MainForm
         private string _DeviceStates2 = "未知状态";
         private string _DeviceStates_Old2 = "未知状态";
 
+        private object dicAlarms_Cur_PLC1_Old;
+
         /// <summary>
         /// 获取设备报警数据与获取设备运行信息
         /// </summary>
         private async void ReadAlarmAllPLC()
         {
-            // [S1] Tray盘上料装备(板测)
-            // [S2] FCT(板测)
-            // [S3] 值板机
-            // [S4] 取放桁架
-            // [S5] Tray盘下料装备
-            /// 上位机心跳
             /// 获取设备报警数据与状态信息
             string stationNameStr = "获取设备报警数据与状态信息";
             // 已连接到PLC
@@ -745,6 +775,91 @@ namespace MainForm
             {
                 try
                 {
+                    DateTime dtNow = DateTime.Now;
+
+                    #region 报警数据
+                    try
+                    {
+                        List<DeviceAlarm_Cur> deviceAlarm_Curs = new List<DeviceAlarm_Cur>();  // 同步到报警页面用传输载体
+
+                        _FaultDatas=new uint[] { 4,0,0,10};
+
+
+                        bool isNeedUpdUI = false;  // 是否需要更新历史报警UI
+                        //解析报警信息
+                        List<(int, int)> AlarmIndexList = new List<(int, int)>();//收集所有报警信息的位置
+                        if (_FaultDatas.Length>0)
+                        {
+                            string binaryString = "";
+                            for (int i = 0; i <= _FaultDatas.Length-1; i++)
+                            {
+                                var num = 0;
+                                if (_FaultDatas[i]>0)
+                                {
+                                    binaryString = Convert.ToString(_FaultDatas[i], 2);
+                                    for (int j = binaryString.Length - 1; j >= 0; j--)
+                                    {
+                                        num++;
+                                        char s = binaryString[j];
+                                        if (binaryString[j]=='1')
+                                        {
+                                            AlarmIndexList.Add((i, num-1));
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        
+                        // 同步“设备报警信息”到“设备报警临时字典DicAlarms_Cur”
+                        var dicAlarms_Cur_PLC1 = DicAlarms_Cur[GlobalContext.IsUseStationName];
+                        int AlarmsLine = 0;//记录总循环行数
+                        foreach ((int index, int row) in AlarmIndexList)
+                        {
+                            var tempDic = dicAlarms_Cur_PLC1.Where(x => x.group_index == index).ToList();
+                            for (int i = 0; i < tempDic.Count -1; i++)  // 读取
+                            {
+                                if (tempDic[i].group_index == index && i == row)
+                                {
+                                    dicAlarms_Cur_PLC1[AlarmsLine].报警数据 = new AlarmData()
+                                    {
+                                        GUID = Guid.NewGuid().ToString(),
+                                        LineName = GlobalContext.IsUseStationName,       // 工站
+                                        PlcStation = tempDic[i].plcName,   // 工站全称;[S1]
+                                        Type1 = tempDic[i].type1,  // 故障层级1
+                                        Type2 = tempDic[i].type2,  // 故障层级2
+                                        Type3 = tempDic[i].type3,  // 故障层级3
+                                        Type4 = tempDic[i].type4,  // 故障层级4
+                                        AlarmType = tempDic[i].fault_code,    // 报警类型
+                                        AlarmDesc = tempDic[i].fault_name,    // 报警内容
+                                        StartTime = dtNow  // 开始时间
+                                    };
+                                }
+                                AlarmsLine += 1;
+                            }
+
+
+                        }
+
+
+                        //FaultLogRequest request = new FaultLogRequest();
+                        //request.station = mesStation;        // 工位
+                        //request.fault_name = xmFaultName;    // 故障名称(同数据字典中的事件名称)
+                        //request.fault_code = xmFaultCode2;   // 故障编码(A,B,C,D,E)
+                        //request.fault_cmpnt = xmFaultCmpnt;  // 故障部件
+                        //request.fault_desc = xmFaultDesc;    // 故障描述
+                        //request.fault_tm = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");  // 故障发生时间 2022-06-01 14:27:57.283
+                        //                                                                      // 上传
+                        //(int, string) iotResult = XiaomiMqttClient_Extend.Write_FaultLog(request, type1, type2, type3, request.fault_cmpnt, deciveCode);
+                    }
+                    catch (Exception ex)
+                    {
+                        string str = ex.StackTrace;
+                        AddMessage_Station(stationNameStr, LogType.Error, $"{stationNameStr}_获取报警数据出错!错误信息:" + ex.Message.ToString() + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                    }
+                    #endregion 报警数据
+
+
+                    #region 设备状态
                     //if (!GlobalContext._IsCon_plc1Alarm)
                     //{
                     //    UpdatePLCMonitor(1, -2, 0);
@@ -867,6 +982,9 @@ namespace MainForm
                         }
                     }
 
+                    #endregion
+
+
                     //if (plc1Alarm.IsConnected)  // 检查PLC是否已连接上
                     //{
 
@@ -2084,6 +2202,158 @@ namespace MainForm
             }
         }
 
+        /// <summary>
+        /// 实例化报警字典
+        /// </summary>
+        private (bool, string) InitalDicAlarm()
+        {
+            #region 加载报警表
+            string excelPath = "";
+            switch (GlobalContext.IsUsePLCNow)
+            {
+                case 1:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_10_壳体清洁上料.xlsx";
+                    break;
+                case 2:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_20_上盖板上料装备.xlsx";
+                    break;
+                case 3:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_30_点散热胶装备.xlsx";
+                    break;
+                case 4:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_40_胶线检测.xlsx";
+                    break;
+                case 5:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_50_ADD板上料组装装备.xlsx";
+                    break;
+                case 6:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_60_组上盖板.xlsx";
+                    break;
+                case 7:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_70_上盖板锁螺丝.xlsx";
+                    break;
+                case 8:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_80_NG下料.xlsx";
+                    break;
+                case 9:
+                    excelPath = AppDomain.CurrentDomain.BaseDirectory + "DBFile\\小米-IoT报警字典_90_半成品下料.xlsx";
+                    break;
+                default:
+                    return (false, $"不支持当前PLC[{GlobalContext.IsUsePLCNow}]的报警点位表!请在设置页切换到正确的plc后重启该软件!");
+            }
+
+            if (!File.Exists(excelPath))
+                return (false, $"未找到当前PLC[{GlobalContext.IsUsePLCNow}]的报警点位表!请检查文件路径:'{excelPath}'。");
+
+            DataTable DtModel = NPOIHelper.ReadExcel(excelPath);
+            if (DtModel == null || DtModel.Rows.Count < 1)
+                return (false, $"报警点位表未包含任何报警数据!请检查‘{excelPath}’文件!");
+
+            // 检查列名
+            List<string> isNeedParms = new List<string>() {"设备分类名称","设备分类编码","分类层级1","分类层级2","分类层级3" ,"分类层级4","事件名称"
+                ,"事件ID","描述","标签","PLC地址","工位"};  // 必须要有的列
+
+            // 指定列名 + 检查列是否完整
+            DataRow dtRowName = DtModel.Rows[0];
+            int count = DtModel.Columns.Count;
+            for (int i = 0; i < count; i++)
+            {
+                string columeName = dtRowName[i]?.ToString();
+                if (!string.IsNullOrEmpty(columeName))
+                    DtModel.Columns[i].ColumnName = columeName;
+
+                if ((!string.IsNullOrEmpty(columeName)) && isNeedParms.Count > 0 && isNeedParms.Contains(columeName))
+                    isNeedParms.Remove(columeName);
+            }
+            DtModel.Rows.RemoveAt(0);
+
+            if (isNeedParms.Count > 0)
+            {
+                string msg1 = string.Join(",", isNeedParms);
+                return (false, $"报警点位表未包含列:{msg1}!请检查‘{excelPath}’文件!");
+            }
+            #endregion 加载报警表
+
+            List<Alarm> keyValues1 = new List<Alarm>();
+            for (int i = 0; i < DtModel.Rows.Count; i++)
+            {
+                Alarm alarm = new Alarm();
+                alarm.plcName = DtModel.Rows[i]["设备分类名称"]?.ToString();     // 设备名;
+                string type1Str = DtModel.Rows[i]["分类层级1"]?.ToString();      // 分类层级1;
+                alarm.type1CH = type1Str;  // 分类层级1 中文
+                alarm.type1 = type1Str;    // 分类层级1
+                if (!string.IsNullOrEmpty(type1Str) && type1Str.Contains("\n"))
+                {
+                    string[] type1Strs = type1Str.Split('\n');
+                    if (type1Strs.Length >= 2)
+                    {
+                        alarm.type1CH = type1Strs[0].Trim();    // 分类层级1 中文
+                        alarm.type1 = type1Strs[1].Trim();      // 分类层级1 
+                        if (string.IsNullOrEmpty(alarm.type1))
+                            alarm.type1 = alarm.type1CH;
+                    }
+                }
+
+                string type2Str = DtModel.Rows[i]["分类层级2"]?.ToString();      // 分类层级2;电气控制 electric_control
+                alarm.type2CH = type2Str;  // 分类层级2 中文
+                alarm.type2 = type2Str;    // 分类层级2
+                if (!string.IsNullOrEmpty(type2Str) && type2Str.Contains("\n"))
+                {
+                    string[] type2Strs = type2Str.Split('\n');
+                    if (type2Strs.Length >= 2)
+                    {
+                        alarm.type2CH = type2Strs[0].Trim();    // 分类层级2 中文
+                        alarm.type2 = type2Strs[1].Trim();      // 分类层级2
+                        if (string.IsNullOrEmpty(alarm.type2))
+                            alarm.type2 = alarm.type2CH;
+                    }
+                }
+
+                string type3Str = DtModel.Rows[i]["分类层级3"]?.ToString();      // 分类层级3;故障 Fault
+                alarm.type3CH = type3Str;  // 分类层级3 中文
+                alarm.type3 = type3Str;    // 分类层级3
+                if (!string.IsNullOrEmpty(type3Str) && type3Str.Contains("\n"))
+                {
+                    string[] type3Strs = type3Str.Split('\n');
+                    if (type3Strs.Length >= 2)
+                    {
+                        alarm.type3CH = type3Strs[0].Trim();    // 分类层级3 中文
+                        alarm.type3 = type3Strs[1].Trim();      // 分类层级3
+                        if (string.IsNullOrEmpty(alarm.type3))
+                            alarm.type3 = alarm.type3CH;
+                    }
+                }
+
+                string faultStr = DtModel.Rows[i]["分类层级4"]?.ToString();      // 故障部件;overall_module
+                alarm.type4 = faultStr; // 分类层级4 中文
+                alarm.type4CH = faultStr;   // 分类层级4 
+                if (!string.IsNullOrEmpty(faultStr) && faultStr.Contains("\n"))
+                {
+                    string[] faultStrs = faultStr.Split('\n');
+                    if (faultStrs.Length >= 2)
+                    {
+                        alarm.type4CH = faultStrs[0].Trim();    // 故障部件;overall_module
+                        alarm.type4 = faultStrs[1].Trim();      // 故障部件
+                        if (string.IsNullOrEmpty(alarm.type4))
+                            alarm.type4 = alarm.type4CH;
+                    }
+                }
+                alarm.fault_code = DtModel.Rows[i]["事件ID"]?.ToString();     // 故障编码;A40001
+                alarm.fault_name = DtModel.Rows[i]["事件名称"]?.ToString();     // 故障名称;AL[1000]_系统_HMI急停故障
+                alarm.fault_desc = alarm.fault_name;                            // 故障描述;AL[1000]_系统_HMI急停故障
+                string plcAdress = DtModel.Rows[i]["PLC地址"]?.ToString();
+                alarm.PLC地址 = plcAdress;
+                plcAdress = plcAdress.Replace("fault_codes[", "");
+                plcAdress = plcAdress.Replace("]", "");
+                alarm.group_index = Convert.ToInt32(plcAdress.Split(".")[0]);
+
+                keyValues1.Add(alarm);
+
+            }
+            DicAlarms_Cur.Add(GlobalContext.IsUseStationName, keyValues1);  // 这里使用线体代替工位
+            return (true, "报警字典表初始化成功!");
+        }
+
         #endregion
 
         #region S1
@@ -2149,11 +2419,14 @@ namespace MainForm
                             xmDeviceStateData.left = (xmDeviceStateInt < 0 || xmDeviceStateInt > 7)
                                 ? XiaomiDeviceState.Unknown
                                 : (XiaomiDeviceState)xmDeviceStateInt;
-
-                            s1PLCData["a1OEEPartNo"] =
-                                stPLC_MesData.BarcodeSet.strProductBarcode; // 物料码(物料码还未绑定载具SN时必填)
-                            s1PLCData["a1OEEVehicleCode"] = stPLC_MesData.BarcodeSet.strCarrierBarcode; // 载具SN
-                            s1PLCData["a1OEEType"] = stPLC_MesData.iotData.BeatAction; // 节拍
+                            // 物料码(物料码还未绑定载具SN时必填)
+                            s1PLCData["a1OEEPartNo"] = stPLC_MesData.BarcodeSet.strProductBarcode;
+                            // 载具SN
+                            s1PLCData["a1OEEVehicleCode"] = stPLC_MesData.BarcodeSet.strCarrierBarcode; 
+                            // 节拍
+                            s1PLCData["a1OEEType"] = stPLC_MesData.iotData.BeatAction; 
+                            //报警信息
+                            _FaultDatas = stPLC_MesData.iotData.fault_codes;
                         }
 
                         #endregion 一次性读取所有数据
@@ -2903,45 +3176,21 @@ namespace MainForm
             string tagAgvCommName = "agvCommFrmPC";
             string tagBarsetName = "BarcodeSet";
 
+            //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0);             // PLC_FLAG 节拍接口
+            s3PLCSignal_Old.Add("a3OEEType_left", 0); // 节拍类型(plc写入) 
+            s3PLCSignal_Old.Add("a3OEEType_right", 0); // 节拍类型(plc写入) 
+
+            // PLC数据字典 赋值 
+            s3PLCData.Add("a3OEEType_left", 0); // 节拍类型(plc写入) 
+            s3PLCData.Add("a3OEEPartNo_left", ""); // 物料码(物料码还未绑定载具SN时必填)
+            s3PLCData.Add("a3OEEVehicleCode_left", ""); // 载具SN
+            s3PLCData.Add("a3OEEType_right", 0); // 节拍类型(plc写入) 
+            s3PLCData.Add("a3OEEPartNo_right", ""); // 物料码(物料码还未绑定载具SN时必填)
+            s3PLCData.Add("a3OEEVehicleCode_right", ""); // 载具SN
+
             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 创建字典
-
             while (true)
             {
                 try
@@ -2972,16 +3221,19 @@ namespace MainForm
                         else
                         {
                             //richTextBox1.AppendText("\n" + "读取成功");
-                            //int xmDeviceStateInt_L = stPLC_MesData.Left.iotData.machineState;
-                            //int xmDeviceStateInt_R = stPLC_MesData.Right.iotData.machineState;
-                            int xmDeviceStateInt_L = 1;
-                            int xmDeviceStateInt_R = 2;
+                            int xmDeviceStateInt_L = stPLC_MesData.Left.iotData.machineState;
+                            int xmDeviceStateInt_R = stPLC_MesData.Right.iotData.machineState;
                             xmDeviceStateData.left = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
                                 ? XiaomiDeviceState.Unknown
                                 : (XiaomiDeviceState)xmDeviceStateInt_L;
                             xmDeviceStateData.right = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
                                 ? XiaomiDeviceState.Unknown
                                 : (XiaomiDeviceState)xmDeviceStateInt_R;
+                            s1PLCData["a1OEEPartNo"] =stPLC_MesData.Left.BarcodeSet.strProductBarcode; // 物料码(物料码还未绑定载具SN时必填)
+                            s1PLCData["a1OEEVehicleCode"] = stPLC_MesData.Left.BarcodeSet.strCarrierBarcode; // 载具SN
+                            s1PLCData["a1OEEType"] = stPLC_MesData.Left.iotData.BeatAction; // 节拍
+                            s1PLCData["a1OEEVehicleCode_right"] = stPLC_MesData.Right.BarcodeSet.strCarrierBarcode; // 载具SN
+                            s1PLCData["a1OEEType_right"] = stPLC_MesData.Right.iotData.BeatAction; // 节拍
                         }
 
                         #endregion 一次性读取所有数据
@@ -3105,6 +3357,90 @@ namespace MainForm
 
                         #endregion 右边出站
 
+                        #region 节拍接口
+                        try
+                        {
+                            #region 左工位 节拍
+                            int a30EEType_left = (int)s3PLCData["a30EEType_left"];
+                            int a30EETypeGOld_left = (int)s3PLCSignal_Old["a30EEType_left"];
+                            //若设备紧急复原后节拍重置
+                            if (a30EEType_left == 1)
+                            {
+                                a30EETypeGOld_left = 0;
+                            }
+
+                            if (a30EEType_left != a30EETypeGOld_left)
+                            {
+                                stationNameStr = stationNameStr + "_Left";
+                                //节拍需要成双成对,有开始就要有结束,例如有1上料开始就必须有2上料结束
+                                if ((a30EETypeGOld_left == 1 && a30EEType_left != 2) || (a30EETypeGOld_left == 3 && a30EEType_left != 4) ||
+                                    (a30EETypeGOld_left == 5 && a30EEType_left != 6))
+                                {
+                                    //写入PLC
+                                    stPLC_MesData.Left.iotData.beatReturn = 2; //NG
+                                    WriteResultToPlc(plcNo, stationNameStr, tagBaseName + ".Left." + tagMesCommName, 1, stPLC_MesData.Left.iotData);
+                                    AddMessage(LogType.Info,
+                                        stationNameStr +
+                                        $"_节拍接口-- 设备本次上传节拍[{a30EEType_left}],未上传节拍[{a30EETypeGOld_left}]的结束信号,请检查;总用时" +
+                                        stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds +
+                                        "ms");
+                                    return;
+                                }
+                                else
+                                {
+                                    Task.Run(() =>
+                                        S3节拍接口(plcNo, stationNameStr, tagBaseName + ".Left." + tagMesCommName,
+                                            stPLC_MesData.Left.iotData)); // MreTasks[4].Set();
+                                }
+                                s3PLCSignal_Old["a30EEType_left"] = s3PLCData["a30EEType_left"];
+                            }
+                            #endregion 左工位 节拍
+
+                            #region 右工位 节拍
+                            int a30EEType_right = (int)s3PLCData["a30EEType_right"];
+                            int a30EETypeGOld_right = (int)s3PLCSignal_Old["a30EEType_right"];
+                            //若设备紧急复原后节拍重置
+                            if (a30EEType_right == 1)
+                            {
+                                a30EETypeGOld_right = 0;
+                            }
+
+                            if (a30EEType_right != a30EETypeGOld_right)
+                            {
+                                stationNameStr = stationNameStr + "_Right";
+                                //节拍需要成双成对,有开始就要有结束,例如有1上料开始就必须有2上料结束
+                                if ((a30EETypeGOld_right == 1 && a30EEType_right != 2) || (a30EETypeGOld_right == 3 && a30EEType_right != 4) ||
+                                    (a30EETypeGOld_right == 5 && a30EEType_right != 6))
+                                {
+                                    //写入PLC
+                                    stPLC_MesData.Right.iotData.beatReturn = 2; //NG
+                                    WriteResultToPlc(plcNo, stationNameStr, tagBaseName + ".Right." + tagMesCommName, 1, stPLC_MesData.Left.iotData);
+                                    AddMessage(LogType.Info,
+                                        stationNameStr +
+                                        $"_节拍接口-- 设备本次上传节拍[{a30EEType_right}],未上传节拍[{a30EETypeGOld_right}]的结束信号,请检查;总用时" +
+                                        stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds +
+                                        "ms");
+                                    return;
+                                }
+                                else
+                                {
+                                    Task.Run(() =>
+                                        S3节拍接口(plcNo, stationNameStr, tagBaseName + ".Right." + tagMesCommName,
+                                            stPLC_MesData.Left.iotData)); // MreTasks[4].Set();
+                                }
+                                s3PLCSignal_Old["a30EEType_right"] = s3PLCData["a30EEType_right"];
+                            }
+                            #endregion 右工位 节拍
+                        }
+                        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
 
                         UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI  // 更新PLC状态的UI
 
@@ -4861,6 +5197,8 @@ namespace MainForm
         #endregion
 
         #region S7
+        private Dictionary<string, object> s7PLCSignal_Old = new Dictionary<string, object>();
+        private Dictionary<string, object> s7PLCData = new Dictionary<string, object>();
 
         /// <summary>
         /// [S7] 锁螺丝设备
@@ -4876,8 +5214,22 @@ namespace MainForm
             string tagAgvCommName = "agvCommFrmPC";
             string tagBarsetName = "BarcodeSet";
             string tagScrewDataset = "screwDataset";
+
+            //s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0);             // PLC_FLAG 节拍接口
+            s7PLCSignal_Old.Add("a7OEEType_left", 0); // 节拍类型(plc写入) 
+            s7PLCSignal_Old.Add("a7OEEType_right", 0); // 节拍类型(plc写入) 
+
+            // PLC数据字典 赋值 
+            s7PLCData.Add("a7OEEType_left", 0); // 节拍类型(plc写入) 
+            s7PLCData.Add("a7OEEPartNo_left", ""); // 物料码(物料码还未绑定载具SN时必填)
+            s7PLCData.Add("a7OEEVehicleCode_left", ""); // 载具SN
+            s7PLCData.Add("a7OEEType_right", 0); // 节拍类型(plc写入) 
+            s7PLCData.Add("a7OEEPartNo_right", ""); // 物料码(物料码还未绑定载具SN时必填)
+            s7PLCData.Add("a7OEEVehicleCode_right", ""); // 载具SN
+
             OP70_MesData_t stPLC_MesData; //PLC的MES数据
             (int, string) result;
+
             AtlasScrew atlasScrewLeft = new AtlasScrew(GlobalContext.AtlasAddressLeft, GlobalContext.AtlasAddressPort,
                 3000, 3000, "Left");
             atlasScrewLeft.Initial();
@@ -4885,6 +5237,7 @@ namespace MainForm
                 3000, 3000, "Right");
             atlasScrewRight.Initial();
 
+
             while (true)
             {
                 try
@@ -4915,6 +5268,20 @@ namespace MainForm
                         else
                         {
                             //richTextBox1.AppendText("\n" + "读取成功");
+
+                            int xmDeviceStateInt_L = stPLC_MesData.Left.iotData.machineState;
+                            int xmDeviceStateInt_R = stPLC_MesData.Right.iotData.machineState;
+                            xmDeviceStateData.left = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
+                                ? XiaomiDeviceState.Unknown
+                                : (XiaomiDeviceState)xmDeviceStateInt_L;
+                            xmDeviceStateData.right = (xmDeviceStateInt_L < 0 || xmDeviceStateInt_L > 7)
+                                ? XiaomiDeviceState.Unknown
+                                : (XiaomiDeviceState)xmDeviceStateInt_R;
+                            s7PLCData["a7OEEPartNo"] =stPLC_MesData.Left.BarcodeSet.strProductBarcode; // 物料码(物料码还未绑定载具SN时必填)
+                            s7PLCData["a7OEEVehicleCode"] = stPLC_MesData.Left.BarcodeSet.strCarrierBarcode; // 载具SN
+                            s7PLCData["a7OEEType"] = stPLC_MesData.Left.iotData.BeatAction; // 节拍
+                            s7PLCData["a7OEEVehicleCode_right"] = stPLC_MesData.Right.BarcodeSet.strCarrierBarcode; // 载具SN
+                            s7PLCData["a7OEEType_right"] = stPLC_MesData.Right.iotData.BeatAction; // 节拍
                         }
 
                         #endregion 一次性读取所有数据
@@ -5041,6 +5408,90 @@ namespace MainForm
 
                         #endregion 右边出站
 
+                        #region 节拍接口
+                        try
+                        {
+                            #region 左工位 节拍
+                            int a70EEType_left = (int)s7PLCData["a70EEType_left"];
+                            int a70EETypeGOld_left = (int)s7PLCSignal_Old["a70EEType_left"];
+                            //若设备紧急复原后节拍重置
+                            if (a70EEType_left == 1)
+                            {
+                                a70EETypeGOld_left = 0;
+                            }
+
+                            if (a70EEType_left != a70EETypeGOld_left)
+                            {
+                                stationNameStr = stationNameStr + "_Left";
+                                //节拍需要成双成对,有开始就要有结束,例如有1上料开始就必须有2上料结束
+                                if ((a70EETypeGOld_left == 1 && a70EEType_left != 2) || (a70EETypeGOld_left == 3 && a70EEType_left != 4) ||
+                                    (a70EETypeGOld_left == 5 && a70EEType_left != 6))
+                                {
+                                    //写入PLC
+                                    stPLC_MesData.Left.iotData.beatReturn = 2; //NG
+                                    WriteResultToPlc(plcNo, stationNameStr, tagBaseName + ".Left." + tagMesCommName, 1, stPLC_MesData.Left.iotData);
+                                    AddMessage(LogType.Info,
+                                        stationNameStr +
+                                        $"_节拍接口-- 设备本次上传节拍[{a70EEType_left}],未上传节拍[{a70EETypeGOld_left}]的结束信号,请检查;总用时" +
+                                        stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds +
+                                        "ms");
+                                    return;
+                                }
+                                else
+                                {
+                                    Task.Run(() =>
+                                        S3节拍接口(plcNo, stationNameStr, tagBaseName + ".Left." + tagMesCommName,
+                                            stPLC_MesData.Left.iotData)); // MreTasks[4].Set();
+                                }
+                                s7PLCSignal_Old["a70EEType_left"] = s7PLCData["a70EEType_left"];
+                            }
+                            #endregion 左工位 节拍
+
+                            #region 右工位 节拍
+                            int a70EEType_right = (int)s7PLCData["a70EEType_right"];
+                            int a70EETypeGOld_right = (int)s7PLCSignal_Old["a70EEType_right"];
+                            //若设备紧急复原后节拍重置
+                            if (a70EEType_right == 1)
+                            {
+                                a70EETypeGOld_right = 0;
+                            }
+
+                            if (a70EEType_right != a70EETypeGOld_right)
+                            {
+                                stationNameStr = stationNameStr + "_Right";
+                                //节拍需要成双成对,有开始就要有结束,例如有1上料开始就必须有2上料结束
+                                if ((a70EETypeGOld_right == 1 && a70EEType_right != 2) || (a70EETypeGOld_right == 3 && a70EEType_right != 4) ||
+                                    (a70EETypeGOld_right == 5 && a70EEType_right != 6))
+                                {
+                                    //写入PLC
+                                    stPLC_MesData.Right.iotData.beatReturn = 2; //NG
+                                    WriteResultToPlc(plcNo, stationNameStr, tagBaseName + ".Right." + tagMesCommName, 1, stPLC_MesData.Left.iotData);
+                                    AddMessage(LogType.Info,
+                                        stationNameStr +
+                                        $"_节拍接口-- 设备本次上传节拍[{a70EEType_right}],未上传节拍[{a70EETypeGOld_right}]的结束信号,请检查;总用时" +
+                                        stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds +
+                                        "ms");
+                                    return;
+                                }
+                                else
+                                {
+                                    Task.Run(() =>
+                                        S3节拍接口(plcNo, stationNameStr, tagBaseName + ".Right." + tagMesCommName,
+                                            stPLC_MesData.Left.iotData)); // MreTasks[4].Set();
+                                }
+                                s7PLCSignal_Old["a70EEType_right"] = s7PLCData["a70EEType_right"];
+                            }
+                            #endregion 右工位 节拍
+                        }
+                        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
 
                         UpdatePLCMonitor(1, plcNo, 1); // 更新PLC状态的UI  // 更新PLC状态的UI
 
@@ -13133,139 +13584,6 @@ namespace MainForm
 
         #endregion 日志
 
-        /// <summary>
-        /// 实例化报警字典
-        /// </summary>
-        private void InitalDicAlarm()
-        {
-            #region 第一个工站(这里未区分工位,所以下面出现的‘工位代码’使用‘线别代码’代替)
-
-            List<Alarm> keyValues1 = new List<Alarm>
-            {
-                #region 第一组报警(电机)
-
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "料盘搬运_Y轴电机故障", 关联的PLC地址 = 5100 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "壳体取料_X轴电机故障", 关联的PLC地址 = 5101 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "壳体取料_Z轴电机故障", 关联的PLC地址 = 5102 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "载具搬运_X轴电机故障", 关联的PLC地址 = 5103 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "镭射_X轴电机故障", 关联的PLC地址 = 5104 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "上相机_X轴电机故障", 关联的PLC地址 = 5105 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "上相机_Z轴电机故障", 关联的PLC地址 = 5106 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "下相机_X轴电机故障", 关联的PLC地址 = 5107 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "下料_Y轴电机故障", 关联的PLC地址 = 5108 },
-                new Alarm { 报警类型 = "电机故障", 报警详情 = "下料_X轴电机故障", 关联的PLC地址 = 5109 },
-
-                #endregion 第一组报警(电机)
-
-                #region 第二组报警(气缸)
-
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "上料仓分料进退气缸故障", 关联的PLC地址 = 5200 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "上料仓分料升降气缸故障", 关联的PLC地址 = 5201 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "上料仓顶升气缸故障", 关联的PLC地址 = 5202 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体取料夹爪气缸故障", 关联的PLC地址 = 5203 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料仓顶升气缸故障", 关联的PLC地址 = 5204 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料平移气缸故障", 关联的PLC地址 = 5205 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料升降气缸故障", 关联的PLC地址 = 5206 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料夹爪气缸故障", 关联的PLC地址 = 5207 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "壳体上料旋转气缸故障", 关联的PLC地址 = 5208 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装平移气缸故障", 关联的PLC地址 = 5209 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装升降气缸故障", 关联的PLC地址 = 5210 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装夹爪气缸故障", 关联的PLC地址 = 5211 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "胶圈组装撑开气缸故障", 关联的PLC地址 = 5212 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具定位气缸1故障", 关联的PLC地址 = 5213 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具定位气缸2故障", 关联的PLC地址 = 5214 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具下料移载气缸故障", 关联的PLC地址 = 5215 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具侧推气缸故障", 关联的PLC地址 = 5216 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "载具回流气缸故障", 关联的PLC地址 = 5217 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位2压料气缸故障", 关联的PLC地址 = 5218 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位2电测气缸故障", 关联的PLC地址 = 5219 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位2气密气缸故障", 关联的PLC地址 = 5220 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位3下压气缸故障", 关联的PLC地址 = 5221 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位3上顶气缸故障", 关联的PLC地址 = 5222 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位5相机升降气缸故障", 关联的PLC地址 = 5223 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料模组升降气缸故障", 关联的PLC地址 = 5224 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料模组夹爪气缸1故障", 关联的PLC地址 = 5225 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "下料模组夹爪气缸2故障", 关联的PLC地址 = 5226 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "机械手夹爪气缸故障", 关联的PLC地址 = 5227 },
-                new Alarm { 报警类型 = "气缸故障", 报警详情 = "工位4:镭射压料气缸故障", 关联的PLC地址 = 5228 },
-
-                #endregion 第二组报警(气缸)
-
-                #region 第三组报警(其他故障)
-
-                new Alarm { 报警类型 = "其他故障", 报警详情 = "上料处缺料报警", 关联的PLC地址 = 5300 },
-                new Alarm { 报警类型 = "其他故障", 报警详情 = "震盘缺料报警", 关联的PLC地址 = 5301 },
-                new Alarm { 报警类型 = "其他故障", 报警详情 = "成品仓料满报警", 关联的PLC地址 = 5302 },
-                new Alarm { 报警类型 = "其他故障", 报警详情 = "检测拍照超时报警", 关联的PLC地址 = 5303 },
-                new Alarm { 报警类型 = "其他故障", 报警详情 = "检测拍照NG报警", 关联的PLC地址 = 5304 },
-                new Alarm { 报警类型 = "其他故障", 报警详情 = "玻璃门打开报警", 关联的PLC地址 = 5305 },
-
-                #endregion 第三组报警(其他故障)
-            };
 
-            DicAlarms_Cur.Add(GlobalContext.LineCode, keyValues1); // 这里使用线体代替工位
-
-            #endregion 第一个工站(这里使用线体代替工位)
-
-            # region 第二个工站-原来的写法(废弃)
-
-            //keyValues = new Dictionary<int, AlarmData[]>();
-            ////1
-            //dicAlarmName = new Dictionary<int, Alarm>();
-            //dicAlarmName.Add(0, new Alarm { Name = "M01衬套组模组X电机报警" });
-            //dicAlarmName.Add(1, new Alarm { Name = "M02衬套组模组Y电机报警" });
-            //dicAlarmName.Add(2, new Alarm { Name = "M03衬套组模组Z电机报警" });
-            //dicAlarmName.Add(3, new Alarm { Name = "M04衬套组模组U电机报警" });
-            //dicAlarmName.Add(4, new Alarm { Name = "M05外流线皮带电机报警" });
-            //alarmDatas = new AlarmData[dicAlarmName.Count];
-            //for (int i = 0; i < dicAlarmName.Count; i++)
-            //{
-            //    alarmDatas[i] = new AlarmData();
-            //    alarmDatas[i].Equipment_code = GlobalContext.LineCode + "-2";
-            //    alarmDatas[i].AlarmDesc = dicAlarmName[i].Name;
-            //    alarmDatas[i].AlarmName = dicAlarmName[i].Name;
-            //    alarmDatas[i].AlarmType = 1;
-            //}
-            //keyValues.Add(1, alarmDatas);
-            ////2
-            //dicAlarmName = new Dictionary<int, Alarm>();
-            //dicAlarmName.Add(0, new Alarm { Name = "C01定位气缸故障" });
-            //dicAlarmName.Add(1, new Alarm { Name = "C02左推料气缸故障" });
-            //dicAlarmName.Add(2, new Alarm { Name = "C03右推料气缸故障" });
-            //dicAlarmName.Add(3, new Alarm { Name = "C04左压料气缸故障" });
-            //dicAlarmName.Add(4, new Alarm { Name = "C05右压料气缸故障" });
-            //dicAlarmName.Add(5, new Alarm { Name = "C06切料气缸故障" });
-            //dicAlarmName.Add(6, new Alarm { Name = "C07左入料吹气气缸故障" });
-            //dicAlarmName.Add(7, new Alarm { Name = "C08右入料吹气气缸故障" });
-            //alarmDatas = new AlarmData[dicAlarmName.Count];
-            //for (int i = 0; i < dicAlarmName.Count; i++)
-            //{
-            //    alarmDatas[i] = new AlarmData();
-            //    alarmDatas[i].Equipment_code = GlobalContext.LineCode + "-2";
-            //    alarmDatas[i].AlarmDesc = dicAlarmName[i].Name;
-            //    alarmDatas[i].AlarmName = dicAlarmName[i].Name;
-            //    alarmDatas[i].AlarmType = 2;
-            //}
-            //keyValues.Add(2, alarmDatas);
-            ////3
-            //dicAlarmName = new Dictionary<int, Alarm>();
-            //dicAlarmName.Add(0, new Alarm { Name = "安全门报警" });
-            //dicAlarmName.Add(1, new Alarm { Name = "联机通信故障" });
-            //dicAlarmName.Add(2, new Alarm { Name = "连续NG报警" });
-            //dicAlarmName.Add(3, new Alarm { Name = "合格率低于设定值报警" });
-            //alarmDatas = new AlarmData[dicAlarmName.Count];
-            //for (int i = 0; i < dicAlarmName.Count; i++)
-            //{
-            //    alarmDatas[i] = new AlarmData();
-            //    alarmDatas[i].Equipment_code = GlobalContext.LineCode + "-3";
-            //    alarmDatas[i].AlarmDesc = dicAlarmName[i].Name;
-            //    alarmDatas[i].AlarmName = dicAlarmName[i].Name;
-            //    alarmDatas[i].AlarmType = 3;
-            //}
-            //keyValues.Add(3, alarmDatas);
-            //DicAlarms.Add(2, keyValues);
-
-            #endregion 第二个工站-原来的写法(废弃)
-        }
     }
 }

+ 2 - 2
MainForm/FaForm/Form_Home_SaveData.cs

@@ -392,8 +392,8 @@ namespace MainForm
                     passStaResultRequ.work_type = "OUT_STATION";             // 作业类型
 
                     iotJson = JsonConvert.SerializeObject(passStaResultRequ);
-                    int result_Result = XiaomiMqttClient_Extend.Write_PassStationResult(passStaResultRequ);
-
+                    //int result_Result = XiaomiMqttClient_Extend.Write_PassStationResult(passStaResultRequ);
+                    int result_Result = 0;
                     string result_ResultStr = string.Empty;
                     var try1 = Enum.TryParse(result_Result.ToString(), out XiaomiMqttResponse_ErrCode errCode);
                     if (try1)

+ 19 - 30
MainForm/FaForm/Form_MESTest.Designer.cs

@@ -309,12 +309,8 @@
             this.cmbResult.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
             this.cmbResult.FormattingEnabled = true;
             this.cmbResult.Items.AddRange(new object[] {
-            "上料开始",
-            "上料结束",
-            "作业开始",
-            "作业结束",
-            "下料开始",
-            "下料结束"});
+            "PASS",
+            "FAIL"});
             this.cmbResult.Location = new System.Drawing.Point(344, 87);
             this.cmbResult.Margin = new System.Windows.Forms.Padding(4);
             this.cmbResult.Name = "cmbResult";
@@ -338,13 +334,9 @@
             this.cmbWorkType.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
             this.cmbWorkType.FormattingEnabled = true;
             this.cmbWorkType.Items.AddRange(new object[] {
-            "Uninitialized",
-            "Initializing",
-            "Initialized",
-            "Running",
-            "Paused",
-            "Fault",
-            "Alarm"});
+            "PRESSURE_TEST",
+            "POINT_CHECK",
+            "OUT_STATION"});
             this.cmbWorkType.Location = new System.Drawing.Point(99, 123);
             this.cmbWorkType.Margin = new System.Windows.Forms.Padding(4);
             this.cmbWorkType.Name = "cmbWorkType";
@@ -363,13 +355,12 @@
             // 
             // txtSn_PassStation
             // 
-            this.txtSn_PassStation.Enabled = false;
             this.txtSn_PassStation.Location = new System.Drawing.Point(99, 8);
             this.txtSn_PassStation.Margin = new System.Windows.Forms.Padding(4);
             this.txtSn_PassStation.Name = "txtSn_PassStation";
             this.txtSn_PassStation.Size = new System.Drawing.Size(169, 28);
             this.txtSn_PassStation.TabIndex = 60;
-            this.txtSn_PassStation.Text = "A40001";
+            this.txtSn_PassStation.Text = "4B180055";
             // 
             // label37
             // 
@@ -383,13 +374,12 @@
             // 
             // txtSlot
             // 
-            this.txtSlot.Enabled = false;
             this.txtSlot.Location = new System.Drawing.Point(99, 46);
             this.txtSlot.Margin = new System.Windows.Forms.Padding(4);
             this.txtSlot.Name = "txtSlot";
             this.txtSlot.Size = new System.Drawing.Size(169, 28);
             this.txtSlot.TabIndex = 58;
-            this.txtSlot.Text = "BZ01_01";
+            this.txtSlot.Text = "4B1400103";
             // 
             // label19
             // 
@@ -408,13 +398,8 @@
             this.cmbEnterStatus.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
             this.cmbEnterStatus.FormattingEnabled = true;
             this.cmbEnterStatus.Items.AddRange(new object[] {
-            "Uninitialized",
-            "Initializing",
-            "Initialized",
-            "Running",
-            "Paused",
-            "Fault",
-            "Alarm"});
+            "PASS",
+            "FAIL"});
             this.cmbEnterStatus.Location = new System.Drawing.Point(99, 87);
             this.cmbEnterStatus.Margin = new System.Windows.Forms.Padding(4);
             this.cmbEnterStatus.Name = "cmbEnterStatus";
@@ -667,6 +652,7 @@
             this.txtVIndexSn.Name = "txtVIndexSn";
             this.txtVIndexSn.Size = new System.Drawing.Size(140, 28);
             this.txtVIndexSn.TabIndex = 70;
+            this.txtVIndexSn.Visible = false;
             // 
             // label29
             // 
@@ -677,6 +663,7 @@
             this.label29.Size = new System.Drawing.Size(80, 18);
             this.label29.TabIndex = 69;
             this.label29.Text = "载具穴位";
+            this.label29.Visible = false;
             // 
             // txtVSn
             // 
@@ -685,7 +672,7 @@
             this.txtVSn.Name = "txtVSn";
             this.txtVSn.Size = new System.Drawing.Size(140, 28);
             this.txtVSn.TabIndex = 68;
-            this.txtVSn.Text = "BZ01";
+            this.txtVSn.Text = "4B1400103";
             // 
             // label30
             // 
@@ -704,7 +691,7 @@
             this.txtPartSn.Name = "txtPartSn";
             this.txtPartSn.Size = new System.Drawing.Size(140, 28);
             this.txtPartSn.TabIndex = 66;
-            this.txtPartSn.Text = "A1449V000001";
+            this.txtPartSn.Text = "4B180055";
             // 
             // label31
             // 
@@ -752,7 +739,7 @@
             this.txtFaultDesc.Name = "txtFaultDesc";
             this.txtFaultDesc.Size = new System.Drawing.Size(385, 28);
             this.txtFaultDesc.TabIndex = 62;
-            this.txtFaultDesc.Text = "AL[1000]_系统_HMI急停故障";
+            this.txtFaultDesc.Text = "AL[1003]_系统_急停3触发报警";
             // 
             // label28
             // 
@@ -790,7 +777,7 @@
             this.txtFaultCode2.Name = "txtFaultCode2";
             this.txtFaultCode2.Size = new System.Drawing.Size(385, 28);
             this.txtFaultCode2.TabIndex = 58;
-            this.txtFaultCode2.Text = "A40001";
+            this.txtFaultCode2.Text = "A40003";
             // 
             // label26
             // 
@@ -809,7 +796,7 @@
             this.txtFaultName.Name = "txtFaultName";
             this.txtFaultName.Size = new System.Drawing.Size(385, 28);
             this.txtFaultName.TabIndex = 56;
-            this.txtFaultName.Text = "AL[1000]_系统_HMI急停故障";
+            this.txtFaultName.Text = "AL[1003]_系统_急停3触发报警";
             // 
             // label25
             // 
@@ -920,7 +907,9 @@
             "故障日志",
             "节拍日志",
             "操作记录",
-            "过站数据"});
+            "过站结果",
+            "过站明细",
+            "非结构化"});
             this.cmbSendType_Iot.Location = new System.Drawing.Point(426, 14);
             this.cmbSendType_Iot.Margin = new System.Windows.Forms.Padding(4);
             this.cmbSendType_Iot.Name = "cmbSendType_Iot";

+ 69 - 35
MainForm/FaForm/Form_MESTest.cs

@@ -365,7 +365,7 @@ namespace MainForm.FaForm
                             (int, string) resultOperateLog = SendIotOperateLogFun(mesStation);
                             ShowLog_Iot($"[{resultOperateLog.Item1}]" + resultOperateLog.Item2);
                             break;
-                        case "过站数据":
+                        case "过站结果":
                             (int, string) resultPassStation = SendIotPassStationFun(mesStation);
                             ShowLog_Iot($"[{resultPassStation.Item1}]" + resultPassStation.Item2);
                             break;
@@ -439,8 +439,8 @@ namespace MainForm.FaForm
             request.fault_desc = xmFaultDesc;    // 故障描述
             request.fault_tm = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");  // 故障发⽣时间 2022-06-01 14:27:57.283
             // 上传
-            //(int, string) iotResult = XiaomiMqttClient_Extend.Write_FaultLog(request);
-            (int, string) iotResult = (0, "");
+            (int, string) iotResult = XiaomiMqttClient_Extend.Write_FaultLog(request);
+            //(int, string) iotResult = (0, "");
             return iotResult;
         }
 
@@ -466,8 +466,8 @@ namespace MainForm.FaForm
                 return (999, "‘物料SN’不可为空!");
             else if (string.IsNullOrEmpty(vSn))
                 return (999, "‘载具SN’不可为空!");
-            else if (string.IsNullOrEmpty(vIndexSn))
-                return (999, "‘载具穴位编号’不可为空!");
+            //else if (string.IsNullOrEmpty(vIndexSn))
+            //    return (999, "‘载具穴位编号’不可为空!");
             else if (string.IsNullOrEmpty(class_level_1))
                 return (999, "‘分类层级1’不可为空!");
             else if (string.IsNullOrEmpty(class_level_2))
@@ -550,8 +550,9 @@ namespace MainForm.FaForm
             //request.operator_name = GlobalContext.currentRole;  // 操作账号名;填当前操作⽤⼾,如⽆则填default
 
             // 上传
-            //(int, string) iotResult = XiaomiMqttClient_Extend.Write_OperateLog(request);
-            (int, string) iotResult=(0,"");
+            (int, string) iotResult = XiaomiMqttClient_Extend.Write_OperateLog(request);
+
+            //(int, string) iotResult=(0,"");
             return iotResult;
         }
 
@@ -587,38 +588,50 @@ namespace MainForm.FaForm
             request.line_code = GlobalContext.LineCode;                         // 线体编码
             switch (stationStr)
             {
-                case "[S1]Tray盘上料装备":
+                case "[OP10]壳体清洁上料":
                     request.work_station = GlobalContext.S1_work_station;  // ⼯站
                     request.device_code = GlobalContext.S1_device_code;    // 装备编码
                     break;
-                case "[S2]FCT":
+                case "[OP20]上盖板上料装备":
                     request.work_station = GlobalContext.S2_work_station;  // ⼯站
                     request.device_code = GlobalContext.S2_device_code;    // 装备编码
                     break;
-                //case "[S3]值板机":
-                //    request.work_station = GlobalContext.S3_work_station;  // ⼯站
-                //    request.device_code = GlobalContext.S3_device_code;    // 装备编码
-                //    break;
-                //case "[S4_1]载具下线装备":
-                //    request.work_station = GlobalContext.S4_1_work_station;  // ⼯站
-                //    request.device_code = GlobalContext.S4_1_device_code;    // 装备编码
-                //    break;
-                //case "[S4_3]提升机1":
-                //    request.work_station = GlobalContext.S4_3_work_station;  // ⼯站
-                //    request.device_code = GlobalContext.S4_3_device_code;    // 装备编码
-                //    break;
-                //case "[S4_4]提升机2":
-                //    request.work_station = GlobalContext.S4_4_work_station;  // ⼯站
-                //    request.device_code = GlobalContext.S4_4_device_code;    // 装备编码
-                //    break;
-                //case "[S4_5]载具上线装备":
-                //    request.work_station = GlobalContext.S4_5_work_station;  // ⼯站
-                //    request.device_code = GlobalContext.S4_5_device_code;    // 装备编码
-                //    break;
-                //case "[S5]Tray盘下料装备":
-                //    request.work_station = GlobalContext.S5_work_station;  // ⼯站
-                //    request.device_code = GlobalContext.S5_device_code;    // 装备编码
-                //    break;
+                case "[OP30]点散热胶装备_Left":
+                    request.work_station = GlobalContext.s3_1_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s3_1_device_code;    // 装备编码
+                    break;
+                case "[OP30]点散热胶装备_Right":
+                    request.work_station = GlobalContext.s3_2_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s3_2_device_code;    // 装备编码
+                    break;
+                case "[OP40]胶线检测":
+                    request.work_station = GlobalContext.s4_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s4_device_code;    // 装备编码
+                    break;
+                case "[OP50]ADD板上料组装装备":
+                    request.work_station = GlobalContext.s5_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s5_device_code;    // 装备编码
+                    break;
+                case "[OP60]组上盖板":
+                    request.work_station = GlobalContext.s6_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s6_device_code;    // 装备编码
+                    break;
+                case "[OP70]上盖板锁螺丝_Left":
+                    request.work_station = GlobalContext.s7_1_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s7_1_device_code;    // 装备编码
+                    break;
+                case "[OP70]上盖板锁螺丝_Right":
+                    request.work_station = GlobalContext.s7_2_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s7_2_device_code;    // 装备编码
+                    break;
+                case "[OP80]NG下料":
+                    request.work_station = GlobalContext.s8_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s8_device_code;    // 装备编码
+                    break;
+                case "[OP90]半成品下料":
+                    request.work_station = GlobalContext.s9_work_station;  // ⼯站
+                    request.device_code = GlobalContext.s9_device_code;    // 装备编码
+                    break;
             }
             request.station = mesStation;
             request.process_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");  // 节拍发⽣时间(2022-06-01 14:27:57.283)
@@ -629,8 +642,8 @@ namespace MainForm.FaForm
             request.work_type = work_type;        // 作业类型
 
             // 上传过站结果
-            //(int, string) iotResult = XiaomiMqttClient_Extend.Write_PassStationResult(request);
-            (int, string) iotResult = (0, "");
+            (int, string) iotResult = XiaomiMqttClient_Extend.Write_PassStationResult(request);
+            //(int, string) iotResult = (0, "");
             return iotResult;
         }
 
@@ -740,6 +753,27 @@ namespace MainForm.FaForm
                     pnlDeviceState7.BackColor = Color.Gray;
                     pnlDeviceState8.BackColor = Color.Gray;
                     break;
+                case "过站结果":
+                    pnlDeviceState.Enabled = false;
+                    pnlFaultLog.Enabled = false;
+                    pnlStationInputBegin.Enabled = false;
+                    pnlOperateLog.Enabled = false;
+                    pnlPassStation.Enabled = true;
+                    pnlDeviceState5.Enabled = false;
+                    pnlDeviceState6.Enabled = false;
+                    pnlDeviceState7.Enabled = false;
+                    pnlDeviceState8.Enabled = false;
+
+                    pnlDeviceState.BackColor = Color.Gray;
+                    pnlFaultLog.BackColor = Color.Gray;
+                    pnlStationInputBegin.BackColor = Color.Gray;
+                    pnlOperateLog.BackColor = Color.Gray;
+                    pnlPassStation.BackColor = Color.Yellow;
+                    pnlDeviceState5.BackColor = Color.Gray;
+                    pnlDeviceState6.BackColor = Color.Gray;
+                    pnlDeviceState7.BackColor = Color.Gray;
+                    pnlDeviceState8.BackColor = Color.Gray;
+                    break;
                 default:
                     break;
             }

+ 2 - 1
MainForm/FaForm/Form_UserLogin.cs

@@ -24,7 +24,8 @@ namespace UserSettings
 
         private void Form_UserLogin_Load(object sender, EventArgs e)
         {
-            cbb_UserName.SelectedIndex = 0;
+            //cbb_UserName.SelectedIndex = 0;
+            cbb_UserName.SelectedIndex = 2;
         }
 
         private void bt_Login_Click(object sender, EventArgs e)

+ 28 - 18
MainForm/FaForm/Form_UserLogin.designer.cs

@@ -50,20 +50,23 @@
             "操作员",
             "管理员",
             "超级管理员"});
-            this.cbb_UserName.Location = new System.Drawing.Point(299, 98);
+            this.cbb_UserName.Location = new System.Drawing.Point(448, 147);
+            this.cbb_UserName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.cbb_UserName.MaxDropDownItems = 15;
             this.cbb_UserName.Name = "cbb_UserName";
-            this.cbb_UserName.Size = new System.Drawing.Size(131, 22);
+            this.cbb_UserName.Size = new System.Drawing.Size(194, 29);
             this.cbb_UserName.TabIndex = 9;
             // 
             // txt_Password
             // 
             this.txt_Password.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
-            this.txt_Password.Location = new System.Drawing.Point(299, 139);
+            this.txt_Password.Location = new System.Drawing.Point(448, 208);
+            this.txt_Password.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.txt_Password.Name = "txt_Password";
             this.txt_Password.PasswordChar = '*';
-            this.txt_Password.Size = new System.Drawing.Size(131, 23);
+            this.txt_Password.Size = new System.Drawing.Size(194, 31);
             this.txt_Password.TabIndex = 0;
+            this.txt_Password.Text = "123789";
             this.txt_Password.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txt_Password_KeyDown);
             // 
             // label1
@@ -71,9 +74,10 @@
             this.label1.BackColor = System.Drawing.Color.Transparent;
             this.label1.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
             this.label1.ForeColor = System.Drawing.Color.OrangeRed;
-            this.label1.Location = new System.Drawing.Point(235, 98);
+            this.label1.Location = new System.Drawing.Point(352, 147);
+            this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
             this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(58, 22);
+            this.label1.Size = new System.Drawing.Size(87, 33);
             this.label1.TabIndex = 11;
             this.label1.Text = "用户:";
             this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -83,9 +87,10 @@
             this.label2.BackColor = System.Drawing.Color.Transparent;
             this.label2.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
             this.label2.ForeColor = System.Drawing.Color.OrangeRed;
-            this.label2.Location = new System.Drawing.Point(235, 139);
+            this.label2.Location = new System.Drawing.Point(352, 208);
+            this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
             this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(58, 23);
+            this.label2.Size = new System.Drawing.Size(87, 34);
             this.label2.TabIndex = 12;
             this.label2.Text = "密码:";
             this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -96,9 +101,10 @@
             this.label7.BackColor = System.Drawing.Color.Transparent;
             this.label7.Font = new System.Drawing.Font("宋体", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
             this.label7.ForeColor = System.Drawing.Color.LightSalmon;
-            this.label7.Location = new System.Drawing.Point(294, 33);
+            this.label7.Location = new System.Drawing.Point(441, 50);
+            this.label7.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
             this.label7.Name = "label7";
-            this.label7.Size = new System.Drawing.Size(129, 29);
+            this.label7.Size = new System.Drawing.Size(195, 44);
             this.label7.TabIndex = 28;
             this.label7.Text = "用户登录";
             this.label7.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
@@ -109,9 +115,10 @@
             this.bt_Exit.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
             this.bt_Exit.Image = ((System.Drawing.Image)(resources.GetObject("bt_Exit.Image")));
             this.bt_Exit.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-            this.bt_Exit.Location = new System.Drawing.Point(321, 258);
+            this.bt_Exit.Location = new System.Drawing.Point(482, 387);
+            this.bt_Exit.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.bt_Exit.Name = "bt_Exit";
-            this.bt_Exit.Size = new System.Drawing.Size(109, 40);
+            this.bt_Exit.Size = new System.Drawing.Size(164, 60);
             this.bt_Exit.TabIndex = 2;
             this.bt_Exit.Text = "Exit";
             this.bt_Exit.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -124,9 +131,10 @@
             this.bt_Login.Font = new System.Drawing.Font("宋体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
             this.bt_Login.Image = ((System.Drawing.Image)(resources.GetObject("bt_Login.Image")));
             this.bt_Login.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-            this.bt_Login.Location = new System.Drawing.Point(197, 258);
+            this.bt_Login.Location = new System.Drawing.Point(296, 387);
+            this.bt_Login.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.bt_Login.Name = "bt_Login";
-            this.bt_Login.Size = new System.Drawing.Size(109, 40);
+            this.bt_Login.Size = new System.Drawing.Size(164, 60);
             this.bt_Login.TabIndex = 1;
             this.bt_Login.Text = "Login";
             this.bt_Login.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -139,9 +147,10 @@
             this.lab_Err.BackColor = System.Drawing.Color.Transparent;
             this.lab_Err.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
             this.lab_Err.ForeColor = System.Drawing.Color.Red;
-            this.lab_Err.Location = new System.Drawing.Point(297, 176);
+            this.lab_Err.Location = new System.Drawing.Point(446, 264);
+            this.lab_Err.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
             this.lab_Err.Name = "lab_Err";
-            this.lab_Err.Size = new System.Drawing.Size(143, 12);
+            this.lab_Err.Size = new System.Drawing.Size(215, 18);
             this.lab_Err.TabIndex = 32;
             this.lab_Err.Text = "密码错误,请重新输入...";
             this.lab_Err.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
@@ -149,11 +158,11 @@
             // 
             // Form_UserLogin
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
             this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
-            this.ClientSize = new System.Drawing.Size(459, 310);
+            this.ClientSize = new System.Drawing.Size(688, 465);
             this.Controls.Add(this.lab_Err);
             this.Controls.Add(this.bt_Exit);
             this.Controls.Add(this.bt_Login);
@@ -164,6 +173,7 @@
             this.Controls.Add(this.cbb_UserName);
             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+            this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4);
             this.MaximizeBox = false;
             this.MinimizeBox = false;
             this.Name = "Form_UserLogin";