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


    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(@"^Cd{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。以前正常用了好久,刚开始产线工人还说我这个麻烦些。

  • 相关阅读:
    Sql优化思路
    「网络流随想随记」
    「ZJOI 的部分题解整理」
    「循环矩阵相关的一些东西」
    知识蒸馏
    3D Human Pose Estimation with 2D Marginal Heatmaps
    模型剪枝
    目标检测小网络
    selenium---解决clear方法失效
    selenium---快速跳转到指定元素
  • 原文地址:https://www.cnblogs.com/datacool/p/datacool2018042403.html
Copyright © 2020-2023  润新知