这脚本写得真帅,记录一下;很少这么佩服自己

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UNI.MES.Core;
using UNI.MES.Services;

namespace UNI_IPC_MES.modules
{
    /// <summary>
    /// 气密检查流程
    /// </summary>
    public class AirtightnessWorkFlow : ModuleBaseFlow
    {
        //线程池,负责存取已扫条码到出库记录
        private CoreThreadPool pool = new CoreThreadPool();
        //检测通过的数据
        private Queue<AirtghtnessResult> scanQueue = new Queue<AirtghtnessResult>();

        private Regex codeRegex = new Regex(@"^C\d{8}$");
        protected IModuleFlowFormService FlowFormService { get; private set; }
        /// <summary>
        /// Com端口的集合
        /// </summary>
        protected Dictionary<string, object> ComPorts = new Dictionary<string, object>();
        /// <summary>
        /// 缓存区集合,每个串口使用自己的缓冲区
        /// </summary>
        protected Dictionary<string, List<byte>> revBuffer = new Dictionary<string, List<byte>>();
        public AirtightnessWorkFlow(IModuleFlowFormService fromService)
        {
            FlowFormService = fromService;
        }

        /// <summary>
        /// 扫码条码处理
        /// </summary>
        /// <param name="data"></param>
        public override void OnExecScanReceiving(string data)
        {
            var temp = data.Split("|".ToCharArray());
            string flag = temp.LastOrDefault();
            data = temp.FirstOrDefault();
            if (data.IndexOf("NR") != -1)
            {
                string msg = string.Format("{0}道读取条码错误,NOREAD!", flag);
                RaiseException(this, msg, new object[] { data });
            }
            if (codeRegex.IsMatch(data))
            {
                RaiseInfo(this, string.Format("{0}道读取到条码[{1}]。", flag, data));
                using (var db = new MESDb())
                {
                    string cmd = string.Format("select line from hkwsAll with(nolock) where code3='{0}'", data);
                    string lineNo = db.Database.SqlQuery<string>(cmd).FirstOrDefault();
                    if (!lineNo.Equals(flowContext.LineNo))
                    {
                        string msg = string.Format("{0}道校验条码错误,条码{1}上一站测试未通过,或者非本线产品!", flag, data);
                        RaiseException(this, msg, new object[] { data });
                    }
                }
                if (flag.Equals("A"))
                {
                    flowContext.L1Code = data;
                }
                if (flag.Equals("B"))
                {
                    flowContext.L2Code = data;
                }
                RaiseCustomEvent("StartNewTest", "", flag, data);
            }
            else
            {
                string msg = string.Format("{0}道读取条码错误,编码规则错误!条码:{1}", flag, data);
                RaiseException(this, msg, new object[] { data });
            }
        }
        /// <summary>
        /// 脚本初始化
        /// </summary>
        protected override void BeforeWorkInit()
        {
            ComPorts.Clear();
            revBuffer.Clear();
            string path = AppDomain.CurrentDomain.BaseDirectory + "portname.txt";
            using (var sr = new StreamReader(path, false))
            {
                string str = "";
                while ((str = sr.ReadLine()) != null)
                {
                    #region 读取每一行
                    if (str.IndexOf("线体=") != -1)    //找到txt中通道1的各行
                    {
                        string[] mm = Regex.Split(str, "=", RegexOptions.IgnoreCase);   //通过txt中_分隔符取出文件名信息,和超时信息 
                        flowContext.LineNo = mm[1];
                    }
                    else if (str.IndexOf("上层条码a=") != -1)    //找到txt中通道1的各行
                    {
                        string[] mm = Regex.Split(str, "=", RegexOptions.IgnoreCase);   //通过txt中_分隔符取出文件名信息,和超时信息 
                        ComPorts.Add("COM_Up_A", new SerialPort()
                        {
                            PortName = mm[1],
                            BaudRate = 9600,
                            DataBits = 8,
                            StopBits = StopBits.One,
                            //ParityReplace = 63,
                            ReadBufferSize = 4096,
                            WriteBufferSize = 2048
                        });
                    }
                    else if (str.IndexOf("上层条码b=") != -1)    //找到txt中通道1的各行
                    {
                        string[] mm = Regex.Split(str, "=", RegexOptions.IgnoreCase);   //通过txt中_分隔符取出文件名信息,和超时信息 
                        ComPorts.Add("COM_Up_B", new SerialPort()
                        {
                            PortName = mm[1],
                            BaudRate = 9600,
                            DataBits = 8,
                            StopBits = StopBits.One,
                            //ParityReplace = 63,
                            ReadBufferSize = 4096,
                            WriteBufferSize = 2048
                        });
                    }
                    else if (str.IndexOf("下层条码a=") != -1)    //找到txt中通道1的各行
                    {
                        string[] mm = Regex.Split(str, "=", RegexOptions.IgnoreCase);   //通过txt中_分隔符取出文件名信息,和超时信息 
                        ComPorts.Add("COM_Down_A", new SerialPort()
                        {
                            PortName = mm[1],
                            BaudRate = 9600,
                            DataBits = 8,
                            StopBits = StopBits.One,
                            //ParityReplace = 63,
                            ReadBufferSize = 4096,
                            WriteBufferSize = 2048
                        });
                    }
                    else if (str.IndexOf("下层条码b=") != -1)    //找到txt中通道1的各行
                    {
                        string[] mm = Regex.Split(str, "=", RegexOptions.IgnoreCase);   //通过txt中_分隔符取出文件名信息,和超时信息 
                        ComPorts.Add("COM_Down_B", new SerialPort()
                        {
                            PortName = mm[1],
                            BaudRate = 9600,
                            DataBits = 8,
                            StopBits = StopBits.One,
                            //ParityReplace = 63,
                            ReadBufferSize = 4096,
                            WriteBufferSize = 2048
                        });
                    }
                    #endregion
                }
                sr.Close();
            }
            #region 启动参数检测
            if (string.IsNullOrEmpty(flowContext.WorkStation))
            {
                RaiseException(this, "请联系管理员设置工位或者线号!");
            }
            if (string.IsNullOrEmpty(flowContext.Operator))
            {
                RaiseException(this, "请点击'切换员工'进行身份验证!");
            }
            #endregion
            #region 打开全部COM口
            foreach (var com in ComPorts)
            {
                var sp = com.Value as SerialPort;
                try
                {
                    sp.Open();
                    sp.DataReceived += Sp_DataReceived;
                    revBuffer.Add(com.Key, new List<byte>(4096));
                }
                catch (Exception ex)
                {
                    RaiseException(this, ex.Message);
                }
            }
            #endregion
            pool.Exceute += Pool_Exceute;
            pool.Start();
            flowContext.L1CountEx = 0;
            RaiseInfo(this, "程序初始化完成,准备就绪请开始作业!");
        }
        /// <summary>
        /// 接收数据逻辑,是扫描枪的调用OnExecScanReceiving,是PLC的消息调用OnExecDataReceived
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            var sp = sender as SerialPort;
            var dict = ComPorts.SingleOrDefault(port => port.Value == sp);
            if (sp.BytesToRead == 0)
            {
                revBuffer[dict.Key].Clear();
                return;
            }
            byte[] buffer = new byte[sp.BytesToRead];
            int numofbyte = sp.Read(buffer, 0, buffer.Length);
            if (numofbyte > 0)
            {
                revBuffer[dict.Key].AddRange(buffer);
            }
            string revMessage = Encoding.UTF8.GetString(revBuffer[dict.Key].ToArray()).Trim();
            if (dict.Key.IndexOf("Up") != -1 && revMessage.Length > 8)
            {
                string[] temp = revMessage.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                string message = temp.FirstOrDefault().Length > 9 ? temp.FirstOrDefault().Substring(0, 9) : temp.FirstOrDefault();
                FrameAppContext.GetInstance().AppLogger.Info(string.Format("收到扫描枪数据:[{0}]", message));
                OnExecScanReceiving(message + "|" + dict.Key.Split("_".ToCharArray()).LastOrDefault());
                revBuffer[dict.Key].Clear();
            }
            if (dict.Key.IndexOf("Down") != -1 && revMessage.Contains("OK"))
            {
                FrameAppContext.GetInstance().AppLogger.Info(string.Format("收到PLC数据:[{0}]", revMessage));
                OnExecDataReceived(revMessage + "|" + dict.Key.Split("_".ToCharArray()).LastOrDefault());
                revBuffer[dict.Key].Clear();
            }
            //try
            //{
            //    if (sp.BytesToRead == 0)
            //    {
            //        revBuffer.Clear();
            //        return;
            //    }
            //    byte[] buffer = new byte[sp.BytesToRead];
            //    int numofbyte = sp.Read(buffer, 0, buffer.Length);
            //    if (numofbyte > 0)
            //    {
            //        revBuffer.AddRange(buffer);
            //    }
            //    string line = Encoding.UTF8.GetString(revBuffer.ToArray()).Trim();
            //    if (line.Length > 8)
            //    {
            //        FrameAppContext.GetInstance().AppLogger.Info(string.Format("收到数据:[{0}]", line));
            //    }
            //    回车换行符是结束标志
            //    if (revBuffer)
            //    {
            //        var dict = ComPorts.SingleOrDefault(port => port.Value == sp);
            //        if (dict.Key.IndexOf("Up") != -1)
            //        {
            //            if (line.Length < 11)
            //                return;
            //            string message = line.Substring(0, line.IndexOf(Environment.NewLine));
            //            FrameAppContext.GetInstance().AppLogger.Info(string.Format("收到扫描枪数据:[{0}]", message));
            //            OnExecScanReceiving(message + "|" + dict.Key.Split("_".ToCharArray()).LastOrDefault());
            //        }
            //        if (dict.Key.IndexOf("Down") != -1)
            //        {
            //            string message = line.Substring(0, line.IndexOf(Environment.NewLine));
            //            FrameAppContext.GetInstance().AppLogger.Info(string.Format("收到PLC数据:[{0}]", message));
            //            OnExecDataReceived(message + "|" + dict.Key.Split("_".ToCharArray()).LastOrDefault());
            //        }
            //    }
            //}
            //catch (Exception ex)
            //{
            //    FrameAppContext.GetInstance().AppLogger.Error(ex);
            //}
        }
        /// <summary>
        /// 执行数据库操作
        /// </summary>
        /// <param name="obj"></param>
        private void Pool_Exceute(object obj)
        {
            if (obj is AirtghtnessResult && scanQueue.Contains(obj))
            {
                AirtghtnessResult result = scanQueue.Peek();
                using (var db = new MESDb())
                {
                    try
                    {
                        string cmd = string.Format(@"update hkwsAll set code4='{0}',name4='{1}',time4='{2}',fth=1,Res='成功' where code3='{3}'",
                                                                      result.Barcode, result.Oper, result.ResultTime, result.Barcode);
                        db.Database.ExecuteSqlCommand(cmd);
                    }
                    finally
                    {
                        scanQueue.Dequeue();
                    }
                }
            }
            System.Threading.Thread.Sleep(100);
        }
        /// <summary>
        /// 接收到PLC返回的数据
        /// </summary>
        /// <param name="data"></param>
        protected void OnExecDataReceived(string data)
        {
            var temp = data.Split("|".ToCharArray());
            string flag = temp.LastOrDefault();
            data = temp.FirstOrDefault();
            string barcode = string.Empty;
            if (flag.Equals("A"))
                barcode = flowContext.L1Code;
            if (flag.Equals("B"))
                barcode = flowContext.L2Code;
            data.Replace("|" + flag, "");
            #region 获取检测结果
            byte[] buffer = Encoding.UTF8.GetBytes(data);
            int mol = 0;
            for (int i = 0; i < buffer.Length; i++)
            {
                if (buffer[i] == 0x6c)
                {
                    mol = i;
                }
            }
            byte[] xlv = new byte[9];
            xlv[0] = buffer[mol - 10];
            xlv[1] = buffer[mol - 9];
            xlv[2] = buffer[mol - 8];
            xlv[3] = buffer[mol - 7];
            xlv[4] = buffer[mol - 6];
            xlv[5] = buffer[mol - 5];
            xlv[6] = buffer[mol - 4];
            xlv[7] = buffer[mol - 3];
            xlv[8] = buffer[mol - 2];
            if (flag.Equals("A"))
                flowContext.Parameter1 = Encoding.UTF8.GetString(xlv);
            if (flag.Equals("B"))
                flowContext.Parameter2 = Encoding.UTF8.GetString(xlv);
            #endregion
            AirtghtnessResult result = new AirtghtnessResult()
            {
                Barcode = barcode,
                LineNo = flowContext.LineNo,
                Oper = flowContext.Operator,
                ResultTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            };
            data.Replace("NOK","NG");
            //测试不通过
            if (data.Contains("NG"))
            {
                if (flag.Equals("A"))
                    flowContext.L1Code = string.Empty;
                if (flag.Equals("B"))
                    flowContext.L2Code = string.Empty;
                RaiseCustomEvent("DataReceived", flag, "NG", string.Join("|", new string[] { barcode, data }));
            }
            else if (data.Contains("OK"))
            {
                scanQueue.Enqueue(result);
                pool.Post(result);
                RaiseCustomEvent("DataReceived", flag, "OK", string.Join("|", new string[] { barcode, data }));
                //计数加1
                flowContext.L1CountEx++;
            }
            else
            {
                if (flag.Equals("A"))
                    flowContext.L1Code = string.Empty;
                if (flag.Equals("B"))
                    flowContext.L2Code = string.Empty;
                RaiseCustomEvent("DataReceived", flag, "NG", string.Join("|", new string[] { barcode, data }));
            }
        }
        /// <summary>
        /// 停止作业时的检查
        /// </summary>
        protected override void StopWorkCheck()
        {
            if (scanQueue.Count > 0)
            {
                var list = scanQueue.ToArray();
                if (list != null)
                {
                    foreach (var dict in list)
                    {
                        pool.Post(dict);
                    }
                }
                RaiseException(this, string.Format("还有已经检测的条码没有保存到数据库,请重试!"));
            }
        }
        /// <summary>
        /// 结束作业
        /// </summary>
        public override void ExecEndWork()
        {
            pool.Stop();
            foreach (var sp in ComPorts)
            {
                var com = sp.Value as SerialPort;
                com.Close();
            }
            ComPorts.Clear();
            base.ExecEndWork();
        }
        /// <summary>
        /// 异常提醒方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="message"></param>
        /// <param name="args"></param>
        protected override void RaiseException(object sender, string message, params object[] args)
        {
            OnFeedInfo(sender, new Exception(message), message, MessageTipsLevel.Error);
            FlowFormService.ShowErrorAlertNotityForm(1000, 1888, message);
        }
    }
}

虽然解决了别人老程序崩溃引起产线停线的事情,但是领导并没有高看我。哎!老程序是个菜鸟写的,他反反复复改了好几版还是像个DEMO。以前正常用了好久,刚开始产线工人还说我这个麻烦些。

posted @ 2018-04-24 14:48  数据酷软件  阅读(538)  评论(3编辑  收藏