OPCUA实践之winnt服务源码分享
前言
孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说:“对呀,对呀!OPCUA,你用过么?”
大家好,我是44岁的大龄程序员码农阿峰。离开上一个项目近半年了,这时当时在项目做的3个winnt服务,算是OPCUA的初次使用,代码并没有什么出彩的地方,却是能正常运行,而且工作了近1年的时间,应该现在还在运行着。
1)OPCUA服务
直接上代码:
using log4net; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.Entity; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.ServiceProcess; using System.Text; using System.Threading; using System.Threading.Tasks; using OpcUaHelper; using System.Configuration; using Opc.Ua; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Modeling.Model.PalletStatus; using System.Net; namespace OpcuaDeviceSessionService { /// <summary> /// 行健OPC UA设备PLC交互服务(3.3-3.7)不包含3.5 /// </summary> public partial class OpcuaDeviceSessionService : ServiceBase { public static readonly log4net.ILog logger = log4net.LogManager.GetLogger(typeof(OpcuaDeviceSessionService).Name); private Dictionary<string, DeviceSessionTAG> nodeList = new Dictionary<string, DeviceSessionTAG>(); private readonly Dictionary<int, string> _HB_ACC_TAGS = new Dictionary<int, string>(); private OpcUaClient m_OpcUaClient; private bool m_runStatus = true; private object lockObject = new object(); List<Thread> threadList = new List<Thread>(); public OpcuaDeviceSessionService() { InitializeComponent(); } private void M_OpcUaClient_OpcStatusChange(object sender, OpcUaStatusEventArgs e) { if (!e.ToString().Contains("正常")) logger.Info(e.ToString()); } /// <summary> /// 启动服务 /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { #region TAG NODE初始化 _HB_ACC_TAGS.Clear(); for (int i = 1; i < 17; i++) { _HB_ACC_TAGS.Add(i, $"ns=2;s=D{i}_HB_PLC_ACC"); } nodeList.Clear(); for (int i = 1; i < 17; i++) { nodeList.Add($"D{i}_3.3", new DeviceSessionTAG { DeviceNo = $"D{i}", InterfaceVersion = "3.3", PLC_FLAG = $"ns=2;s=D{i}_MISQ_PLC_FLAG", PLC_DATA = $"ns=2;s=D{i}_MISQ_PLC_DATA", SYS_FLAG = $"ns=2;s=D{i}_MISQ_SYS_FLAG", SYS_DATA = $"ns=2;s=D{i}_MISQ_SYS_DATA" }); nodeList.Add($"D{i}_3.4", new DeviceSessionTAG { DeviceNo = $"D{i}", InterfaceVersion = "3.4", PLC_FLAG = $"ns=2;s=D{i}_MIRP_PLC_FLAG", PLC_DATA = $"ns=2;s=D{i}_MIRP_PLC_DATA", SYS_FLAG = $"ns=2;s=D{i}_MIRP_SYS_FLAG", SYS_DATA = $"ns=2;s=D{i}_MIRP_SYS_DATA" }); //nodeList.Add($"D{i}_3.5", new DeviceSessionTAG //{ // DeviceNo = $"D{i}", // InterfaceVersion = "3.5", // PLC_FLAG = $"ns=2;s=D{i}_PSRP_PLC_FLAG", // PLC_DATA = $"ns=2;s=D{i}_PSRP_PLC_DATA", // SYS_FLAG = $"ns=2;s=D{i}_PSRP_SYS_FLAG", // SYS_DATA = $"ns=2;s=D{i}_PSRP_SYS_DATA" //}); nodeList.Add($"D{i}_3.6", new DeviceSessionTAG { DeviceNo = $"D{i}", InterfaceVersion = "3.6", PLC_FLAG = $"ns=2;s=D{i}_MPRP_PLC_FLAG", PLC_DATA = $"ns=2;s=D{i}_MPRP_PLC_DATA", SYS_FLAG = $"ns=2;s=D{i}_MPRP_SYS_FLAG", SYS_DATA = $"ns=2;s=D{i}_MPRP_SYS_DATA" }); nodeList.Add($"D{i}_3.7", new DeviceSessionTAG { DeviceNo = $"D{i}", InterfaceVersion = "3.7", PLC_FLAG = $"ns=2;s=D{i}_CFCA_PLC_FLAG", PLC_DATA = $"ns=2;s=D{i}_CFCA_PLC_DATA", SYS_FLAG = $"ns=2;s=D{i}_CFCA_SYS_FLAG", SYS_DATA = $"ns=2;s=D{i}_CFCA_SYS_DATA" }); } #endregion m_OpcUaClient = new OpcUaClient(); Thread thread = new Thread(() => { int sleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["sleepTime"].ToString()); while (m_runStatus) { try { if (m_OpcUaClient.Session == null) { lock (lockObject) { m_OpcUaClient.OpcStatusChange += M_OpcUaClient_OpcStatusChange; ExecuteConnectAction(m_OpcUaClient); } } } catch (Exception loopEx) { logger.Error(loopEx.InnerException == null ? loopEx : loopEx.InnerException); Thread.Sleep(3000); } Thread.Sleep(sleepTime); } }); thread.Start(); logger.Debug("------------------------------------------------------------------"); logger.Debug(JsonConvert.SerializeObject(nodeList)); logger.Debug("------------------------------------------------------------------"); logger.Debug("============================服务启动=============================="); foreach (var item in nodeList) { Thread opcClientThread = new Thread(delegate () { Opcua_Client_Exceute(item.Value); }) { IsBackground = true }; threadList.Add(opcClientThread); } foreach (var opcClientThread in threadList) { opcClientThread.Start(); } } /// <summary> /// 处理一个PCL的TAG读取和交互 /// </summary> /// <param name="obj"></param> private void Opcua_Client_Exceute(DeviceSessionTAG deviceTag) { int sleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["sleepTime"].ToString()); while (true) { try { if (m_OpcUaClient.Session != null && m_OpcUaClient.Session.Connected) { lock (lockObject) { int deviceID = int.Parse(deviceTag.DeviceNo.Replace("D", "")); NodeId acc_Node = new NodeId(_HB_ACC_TAGS[deviceID]); DataValue dv = m_OpcUaClient.ReadNode(acc_Node); if (dv != null) { string jsonResult = JsonConvert.SerializeObject(dv); if (jsonResult.Contains("Int32")) { #region 业务处理 NodeId plc_FlagNode = new NodeId(deviceTag.PLC_FLAG); DataValue dv_PLC_Flag = m_OpcUaClient.ReadNode(plc_FlagNode); NodeId sys_FlagNode = new NodeId(deviceTag.SYS_FLAG); DataValue dv_SYS_Flag = m_OpcUaClient.ReadNode(sys_FlagNode); string jsonResult1 = JsonConvert.SerializeObject(dv_PLC_Flag); string jsonResult2 = JsonConvert.SerializeObject(dv_SYS_Flag); if (jsonResult1.Contains("Boolean") && jsonResult2.Contains("Boolean") && jsonResult1.Contains("true") && jsonResult2.Contains("false")) { NodeId plc_DataNode = new NodeId(deviceTag.PLC_DATA); DataValue dv_PLC_Data = m_OpcUaClient.ReadNode(plc_DataNode); string jsonPLC_Data = JsonConvert.SerializeObject(dv_PLC_Data); string value = jsonPLC_Data.Replace(((char)34).ToString(), "").Split("}}}".ToArray()).FirstOrDefault(); string plcData = value.Split("#text:".ToArray()).LastOrDefault(); //2.读取PLC发送的报文 logger.Debug(deviceTag.PLC_DATA + ":" + plcData + " 长度:" + plcData.Length); #region 报文固定变量 string SysDataTag = ""; string CMDID = ""; string MaterialPNo = ""; string PT = ""; string PalletNo = ""; string PointFlag = ""; string PalletState = ""; string MaterialList = ""; string PalletType = ""; #endregion //3.3 if (plcData.Length == 38 && plcData.Substring(5, 4).Equals("MISQ")) { try { CMDID = plcData.Substring(9, 3); MaterialPNo = plcData.Substring(12, 11).Replace("-", ""); PT = plcData.Substring(23, 14); using (var db = new MoldDbModel()) { var point = db.T_Mold_MaterialPoint_Status.Where(p => p.PointNo.Equals(MaterialPNo)).FirstOrDefault(); if (point == null) { //不是料点,查一下是否是料框 var palletObj = db.T_Mold_Pallet_Info.Where(p => p.PalletNo == MaterialPNo).FirstOrDefault(); if (palletObj != null) { #region 根据料框请求物料信息 var item = db.T_Mold_Material_SendLog.Where(p => p.PalletNo == MaterialPNo && p.Status == "0").ToList();//当前料点未下发的物料信息 if (item != null && item.Count > 0) { if (item.Count > 4) { item = item.Take(4).ToList(); } string materInfo = ""; foreach (var t in item) { int Quantity = t.Quantity.HasValue ? Convert.ToInt32(t.Quantity) : 0; materInfo += (t.MaterialNo.PadLeft(20, '-') + Convert.ToString(Quantity).PadLeft(2, '-') + t.OprStatus.PadLeft(4, '-') + t.LotNo.PadLeft(15, '-')); // 41 * 4 = 164 t.Status = "1"; db.Entry(t).State = EntityState.Modified; } db.SaveChanges(); string palletNo = item.FirstOrDefault().PalletNo; var pallet_info = db.T_Mold_Pallet_Info.Where(p => p.PalletNo == palletNo).FirstOrDefault(); string palletType = ""; if (pallet_info != null) palletType = pallet_info?.PalletType.PadLeft(4, '-'); string locationNo = item.FirstOrDefault().PointNo; point = db.T_Mold_MaterialPoint_Status.Where(p => p.PointNo.Equals(locationNo)).FirstOrDefault(); SysDataTag = "BSYSAMISY" + CMDID + locationNo.PadLeft(11, '-') + MaterialPNo.PadLeft(9, '-') + point.PointFlag + materInfo; SysDataTag = SysDataTag.PadRight(197, '-') + palletType.PadLeft(4, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"; } else { //查无物料 SysDataTag = "BSYSAMISY" + CMDID + MaterialPNo.PadRight(11, '-'); SysDataTag = SysDataTag.PadRight(201, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"; } #endregion } if (point == null && palletObj == null) { //传的编号有误,不是料点号也不是料框号 SysDataTag = "BSYSAMISN" + CMDID.PadLeft(3, '0') + MaterialPNo.PadRight(11, '-'); SysDataTag = SysDataTag.PadRight(201, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "01E"; } } else { if (point.PointFlag == "0")//上料点发送物料信息 { var item = db.T_Mold_Material_SendLog.Where(p => p.PointNo.Equals(MaterialPNo) && p.Status == "0").ToList();//当前料点未下发的物料信息 if (item != null && item.Count > 0) { if (item.Count > 4) { item = item.Take(4).ToList(); } string materInfoData = ""; foreach (var t in item) { int Quantity = t.Quantity.HasValue ? Convert.ToInt32(t.Quantity) : 0; materInfoData += (t.MaterialNo.PadLeft(20, '-') + Convert.ToString(Quantity).PadLeft(2, '-') + t.OprStatus.PadLeft(4, '-') + t.LotNo.PadLeft(15, '-')); t.Status = "1"; db.Entry(t).State = EntityState.Modified; } string no = item.FirstOrDefault().PalletNo; var pallet_info = db.T_Mold_Pallet_Info.Where(p => p.PalletNo == no).FirstOrDefault(); string palletType = ""; if (pallet_info != null) palletType = pallet_info?.PalletType.PadLeft(4, '-'); SysDataTag = "BSYSAMISY" + CMDID + MaterialPNo.PadLeft(11, '-') + no.PadLeft(9, '-') + point.PointFlag + materInfoData; SysDataTag = SysDataTag.PadRight(197, '-') + palletType.PadLeft(4, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"; } else { SysDataTag = "BSYSAMISY" + CMDID + MaterialPNo.PadLeft(11, '-'); SysDataTag = SysDataTag.PadRight(201, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E";//没有物料信息 } } else { SysDataTag = "BSYSAMISY" + CMDID + MaterialPNo.PadLeft(11, '-') + point.PalletNo.PadLeft(9, '-') + point.PointFlag; SysDataTag = (SysDataTag.PadRight(201, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"); } } #region LOG_PLCMESSAGE T_LOG_PLCMESSAGE log = new T_LOG_PLCMESSAGE { WIPORDER = "物料信息下发", Request = "PLC", RequestMsg = plcData, RequestTime = DateTime.ParseExact(PT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture),//发起方发送时间 Responsor = "中控", ResponseMsg = SysDataTag, ResponseTime = DateTime.Now }; db.T_LOG_PLCMESSAGE.Add(log); db.Entry(log).State = EntityState.Added; #endregion int cnt = db.SaveChanges(); logger.Debug($"3.3提交到数据库,受影响的行数:{cnt}。"); } } catch (Exception ex) { SysDataTag = "BSYSAMISN" + CMDID.PadLeft(3, '0') + MaterialPNo.PadRight(11, '-'); SysDataTag += SysDataTag.PadRight(201, '-') + DateTime.Now.ToString("yyyyMMddHHmmss") + "09E"; logger.Debug("解析报文异常消息:" + ex.InnerException == null ? ex.Message : ex.InnerException.Message.ToString()); } } //3.4 if (plcData.Length == 196 && plcData.Substring(5, 4).Equals("MIRP")) { try { CMDID = plcData.Substring(9, 3); MaterialPNo = plcData.Substring(12, 11).Replace("-", ""); PalletNo = plcData.Substring(23, 9).Replace("-", ""); PointFlag = plcData.Substring(32, 1).Replace("-", "0"); logger.Debug($"MaterialPNo:{MaterialPNo}|PalletNo:{PalletNo}|PointFlag:{PointFlag}"); if (!string.IsNullOrEmpty(PalletNo)) { List<string> lsMaterialNo = new List<string>(); List<string> lsMaterialQty = new List<string>(); List<string> lsLotNo = new List<string>(); int start = 33; for (int i = 0; i < 4; i++) { string mat = plcData.Substring(start, 20).Replace("-", ""); if (!string.IsNullOrEmpty(mat)) { lsMaterialNo.Add(mat); lsMaterialQty.Add(plcData.Substring((start + 20), 2).Replace("-", "")); lsLotNo.Add(plcData.Substring((start + 22), 15).Replace("-", "")); } start = start + 37; } PT = plcData.Substring(181, 14); try { using (MoldDbModel db = new MoldDbModel()) { var PointInfo = db.T_Mold_MaterialPoint_Status.Where(p => p.PointNo.Equals(MaterialPNo)).FirstOrDefault(); if (PointInfo != null) { //料框信息存在 if (db.T_Mold_Pallet_Info.Any(p => p.PalletNo == PalletNo)) { SysDataTag = "BSYSAMIRY" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"; } else { //料框号不存在 SysDataTag = "BSYSAMIRN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "01E"; } } else SysDataTag = "BSYSAMIRN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "03E"; } Task.Factory.StartNew(() => { logger.Debug($"lsMaterialNo:{JsonConvert.SerializeObject(lsMaterialNo)}|lsMaterialQty:{JsonConvert.SerializeObject(lsMaterialQty)}|lsLotNo:{JsonConvert.SerializeObject(lsLotNo)}"); UpdateInfo(MaterialPNo, PalletNo, PointFlag, lsMaterialNo, lsMaterialQty, lsLotNo); }); } catch (Exception efException) { logger.Error(efException); continue; } } else { //不是真实的料框号 SysDataTag = "BSYSAMIRN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "01E"; } Task.Factory.StartNew(() => { using (var db = new MoldDbModel()) { #region LOG_PLCMESSAGE T_LOG_PLCMESSAGE log = new T_LOG_PLCMESSAGE { WIPORDER = "PLC上报料框状态", Request = "PLC", RequestMsg = plcData, RequestTime = DateTime.ParseExact(PT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture),//发起方发送时间 Responsor = "中控", ResponseMsg = SysDataTag, ResponseTime = DateTime.Now }; db.T_LOG_PLCMESSAGE.Add(log); db.Entry(log).State = EntityState.Added; #endregion db.SaveChanges(); } }); } catch (Exception ex) { SysDataTag = "BSYSAMIRN" + CMDID.PadLeft(3, '0') + DateTime.Now.ToString("yyyyMMddHHmmss") + "09E"; logger.Debug("解析报文异常消息:" + ex.InnerException == null ? ex.Message : ex.InnerException.Message.ToString()); } } //3.6 if (plcData.Length == 44 && plcData.Substring(5, 4).Equals("MPRP")) { try { CMDID = plcData.Substring(9, 3); MaterialPNo = plcData.Substring(12, 11); PointFlag = plcData.Substring(20, 1).Replace("-", ""); PalletType = plcData.Substring(25, 4).Replace("-", ""); PT = plcData.Substring(29, 14); logger.Debug($"MaterialPNo:{MaterialPNo}|PointFlag:{PointFlag}|PalletType:{PalletType}"); using (var db = new MoldDbModel()) { //料点存在则状态修改为当前请求的状态 if (!string.IsNullOrEmpty(PointFlag) && db.T_Mold_MaterialPoint.Any(p => p.PointNo == MaterialPNo)) { var mat_point = db.T_Mold_MaterialPoint_Status.Where(p => p.PointNo == MaterialPNo).FirstOrDefault(); if (mat_point != null) { mat_point.PointState = PointFlag; db.Entry(mat_point).State = EntityState.Modified; } } else { //料点不存在或料点状态值错误(0/1) SysDataTag = "BSYSAMPRN" + CMDID.PadLeft(3, '0') + DateTime.Now.ToString("yyyyMMddHHmmss") + "01E"; } #region T_LOG_PLCMESSAGE T_LOG_PLCMESSAGE log = new T_LOG_PLCMESSAGE { WIPORDER = "3.6PLC料框状态更新请求", Request = "PLC", RequestMsg = plcData, RequestTime = DateTime.ParseExact(PT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture),//发起方发送时间 Responsor = "中控", ResponseMsg = SysDataTag, ResponseTime = DateTime.Now, SBDID = "" }; db.T_LOG_PLCMESSAGE.Add(log); db.Entry(log).State = EntityState.Added; int cnt = db.SaveChanges(); logger.Debug($"提交到数据库,受影响的行数:{cnt}。"); #endregion } SysDataTag = "BSYSAMPRY" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"; } catch (Exception ex) { SysDataTag = "BSYSAMPRN" + CMDID.PadLeft(3, '0') + DateTime.Now.ToString("yyyyMMddHHmmss") + "09E"; logger.Debug("解析报文异常消息:" + ex.InnerException == null ? ex.Message : ex.InnerException.Message.ToString()); } } //3.7 if (plcData.Length == 47 && plcData.Substring(5, 4).Equals("CFCA")) { CMDID = plcData.Substring(9, 3); MaterialPNo = plcData.Substring(12, 11).Replace("-", ""); PalletNo = plcData.Substring(23, 9); PT = plcData.Substring(32, 14); SysDataTag = "BSYSA"; using (var db = new MoldDbModel()) { if (!db.T_Mold_MaterialPoint.Any(p => p.PointNo == MaterialPNo)) { //料点编号错误 SysDataTag += ("CFCN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "02E"); } else { //料框号错误 if (!db.T_Mold_Pallet_Info.Any(p => p.PalletNo == PalletNo)) { SysDataTag += ("CFCN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "01E"); } else { //当前料框在其他料点已经使用 if (db.T_Mold_MaterialPoint_Status.Where(p => p.PointState == "1" && p.PalletNo == PalletNo).Any()) { SysDataTag += ("CFCN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "04E"); } else { //当前料点已有料框已使用 if (db.T_Mold_MaterialPoint_Status.Any(p => p.PointNo == MaterialPNo)) { var statusEntity = db.T_Mold_MaterialPoint_Status.Where(p => p.PointNo == MaterialPNo && p.PointState == "1").FirstOrDefault(); if (statusEntity != null && statusEntity.PalletNo != PalletNo) { SysDataTag += ("CFCN" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "01E"); } } } } } //没有任何错误 if (SysDataTag.Equals("BSYSA")) { SysDataTag += ("CFCY" + CMDID + DateTime.Now.ToString("yyyyMMddHHmmss") + "00E"); } try { T_LOG_PLCMESSAGE currentLog = new T_LOG_PLCMESSAGE { WIPORDER = "料框编号检查", Request = "PLC", RequestMsg = plcData, RequestTime = DateTime.ParseExact(PT, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture),//发起方发送时间 Responsor = "中控", ResponseMsg = SysDataTag, ResponseTime = DateTime.Now, SBDID = "" }; db.T_LOG_PLCMESSAGE.Add(currentLog); db.Entry(currentLog).State = EntityState.Added; int cnt = db.SaveChanges(); if (cnt > 0) logger.Debug($"料框编号检查,提交数据库:受影响{cnt}行."); } catch (Exception ex) { logger.Error(ex.Message); } } } try { if (SysDataTag.Contains("BSYSA") && m_OpcUaClient.Session != null && m_OpcUaClient.Connected) { m_OpcUaClient.WriteNode(deviceTag.PLC_FLAG, false); m_OpcUaClient.WriteNode(deviceTag.SYS_DATA, SysDataTag); m_OpcUaClient.WriteNode(deviceTag.SYS_FLAG, true); logger.Debug($"回复设备消息:{SysDataTag}"); } } catch (Exception writeNodeExp) { logger.Error("writeNodeExp出错!" + Environment.NewLine + writeNodeExp.InnerException == null ? writeNodeExp.Message : writeNodeExp.InnerException.Message); } } #endregion } } } } } catch (Exception threadExp) { logger.Error(threadExp); } finally { Thread.Sleep(sleepTime); } } } /// <summary> /// 执行料框物料更新逻辑 /// </summary> /// <param name="MaterialPNo"></param> /// <param name="PalletNo"></param> /// <param name="PointFlag"></param> /// <param name="lsMaterialNo"></param> /// <param name="lsMaterialQty"></param> /// <param name="lsLotNo"></param> public void UpdateInfo(string MaterialPNo, string PalletNo, string PointFlag, List<string> lsMaterialNo, List<string> lsMaterialQty, List<string> lsLotNo) { using (MoldDbModel db = new MoldDbModel()) { var PointInfo = db.T_Mold_MaterialPoint_Status.Where(p => p.PointNo.Equals(MaterialPNo)).FirstOrDefault(); if (PointInfo != null) { //料框信息存在 if (db.T_Mold_Pallet_Info.Any(p => p.PalletNo == PalletNo)) { string sql = $@"update T_Mold_MaterialPoint_Status set PointFlag='{PointFlag}',PalletNo = '{PalletNo}',UpdateTime=getdate() where PointNo='{MaterialPNo}'"; db.Database.ExecuteSqlCommand(sql); logger.Debug(sql); sql = $"delete T_Mold_Pallet_Materials where PalletNo='{PalletNo}'"; db.Database.ExecuteSqlCommand(sql); logger.Debug(sql); for (int i = 0; i < lsMaterialNo.Count; i++) { string MaterialNo = lsMaterialNo[i].ToString(); MaterialNo = MaterialNo.Replace("-", ""); if (!string.IsNullOrEmpty(lsMaterialNo[i].ToString())) { int qty; bool b = int.TryParse(lsMaterialQty[i], out qty); if (b && qty > 0) { T_Mold_Pallet_Materials m = new T_Mold_Pallet_Materials { ID = Guid.NewGuid().ToString(), PalletNo = PalletNo, MaterialNo = lsMaterialNo[i].ToString(), LotNo = string.IsNullOrEmpty(lsLotNo[i].ToString()) == true ? DateTime.Now.ToString("yyyyMMddhhmmss") + (new Random().Next(1000)).ToString().PadLeft(3, '0') : lsLotNo[i].ToString(), OprStatus = "0", Quantity = qty, UpdateTime = DateTime.Now }; logger.Debug(JsonConvert.SerializeObject(m)); db.T_Mold_Pallet_Materials.Add(m); db.Entry(m).State = EntityState.Added; } } } try { int cnt = db.SaveChanges(); logger.Debug($"料框更新物料信息,提交数据库,受影响的行数:{cnt}."); } catch (Exception ex) { logger.Error(ex); } } } } } private async void ExecuteConnectAction(OpcUaClient client) { string oPCUAServerUrl = ConfigurationManager.AppSettings["OPCUAServerUrl"].ToString(); string oPCUAServerUser = ConfigurationManager.AppSettings["OPCUAServerUser"].ToString(); string oPCUAServerPwd = ConfigurationManager.AppSettings["OPCUAServerPwd"].ToString(); if (!string.IsNullOrEmpty(oPCUAServerUser)) { client.UserIdentity = new Opc.Ua.UserIdentity(oPCUAServerUser, oPCUAServerPwd); } try { await client.ConnectServer(oPCUAServerUrl); } catch (Exception oo) { logger.Error(oo); } } protected override void OnStop() { logger.Debug("===服务停止==="); m_runStatus = false; if (m_OpcUaClient.Session != null) { m_OpcUaClient.Disconnect(); m_OpcUaClient = null; } foreach (var item in threadList) { item.Abort(); } threadList.Clear(); } } /// <summary> /// 报文交互Node TAG /// </summary> public class DeviceSessionTAG { /// <summary> /// 设备编号 /// </summary> public string DeviceNo { get; set; } /// <summary> /// 接口版本编号 /// </summary> public string InterfaceVersion { get; set; } /// <summary> /// 业务处理PLC FLAG /// </summary> public string PLC_FLAG { get; set; } /// <summary> /// 业务处理PLC报文FLAG /// </summary> public string PLC_DATA { get; set; } /// <summary> /// 业务处理中控系统FLAG /// </summary> public string SYS_FLAG { get; set; } /// <summary> /// 业务处理中控系统报文FLAG /// </summary> public string SYS_DATA { get; set; } /// <summary> /// 设备报警FLAG /// </summary> public string ALARM_FLAG { get; set; } /// <summary> /// 设备报警报文FLAG /// </summary> public string ALARM_DATA { get; set; } /// <summary> /// ANDON事件FLAG /// </summary> public string ANDON_FLAG { get; set; } /// <summary> /// ANDON报文FLAG /// </summary> public string ANDON_DATA { get; set; } /// <summary> ///工步读取 FLAG_T1 /// </summary> public string PLC_WorkStep_FLAG { get; set; } /// <summary> /// 工步读完 FLAG_T2 /// </summary> public string SYS_WorkStep_FLAG { get; set; } } }
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"作者:" 数据酷软件工作室
"出处:" http://datacool.cnblogs.com
"专注于CMS(综合赋码系统),MES,WCS(智能仓储设备控制系统),WMS,商超,桑拿、餐饮、客房、足浴等行业收银系统的开发,15年+从业经验。因为专业,所以出色。"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"作者:" 数据酷软件工作室
"出处:" http://datacool.cnblogs.com
"专注于CMS(综合赋码系统),MES,WCS(智能仓储设备控制系统),WMS,商超,桑拿、餐饮、客房、足浴等行业收银系统的开发,15年+从业经验。因为专业,所以出色。"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++