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; }
    }
}

 

posted @ 2023-04-16 13:06  数据酷软件  阅读(102)  评论(1编辑  收藏  举报