| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 | using System;using System.Collections.Generic;using System.Xml;using Aitex.Common.Util;using Aitex.Core.RT.Log;namespace Virgo_DRT.Modules{    /// <summary>    /// Recipe head    /// </summary>    public class RecipeHead    {        public string RecipeVariation  { get; set; }        public string CreationTime     { get; set; }        public string LastRevisionTime { get; set; }        public string CreatedBy        { get; set; }        public string LastModifiedBy   { get; set; }        public string PressureMode     { get; set; }        public string Description      { get; set; }        public string Barcode          { get; set; }        public string BasePressure     { get; set; }        public string PumpDownLimit    { get; set; }        //public string ElectrodeTemp    { get; set; }        //public string HeaterTemp       { get; set; }        public string PurgeActive      { get; set; }        public string MatchPositionC1  { get; set; }        public string MatchPositionC2  { get; set; }        public string SubstrateTemp    { get; set; }        public string PumpingPinState { get; set; }        public string PinStateAfterVent { get; set; }        public string PinDownPressure { get; set; }    }    public class RecipeStep    {        public string StepName;        public double StepTime;        public bool IsJumpStep;        public bool IsLoopStartStep;        public bool IsLoopEndStep;        public int LoopCount;        public string EndBy;        //public double EndByValue;        public Dictionary<string, string> RecipeCommands = new Dictionary<string, string>();    }    public class Recipe    {        /// <summary>        /// 当前Recipe Run 记录对应的Guid        /// 每个Recipe Run 都对应有一个唯一的Guid        /// </summary>        public static Guid CurrentRecipeRunGuid;        /// <summary>        /// 解析工艺程序文件        /// </summary>        /// <param name="recipeName">工艺程序名</param>        /// <param name="xmlRecipeData">xml格式的工艺数据内容</param>        /// <param name="recipeData">返回解析的工艺数据变量</param>        /// <returns>True:解析成功 | False:解析失败</returns>        public static bool Parse(string recipe, out RecipeHead recipeHead, out List<RecipeStep> recipeData)        {            recipeHead = new RecipeHead();            recipeData = new List<RecipeStep>();            try            {                //获取工艺程序文件中允许的命令字符串列表                //目的:如果工艺程序文件中含有规定之外的命令,则被禁止执行                HashSet<string> recipeAllowedCommands = new HashSet<string>();                XmlDocument rcpFormatDoc = new XmlDocument();                string recipeSchema = PathManager.GetCfgDir() + "RecipeFormat.xml";                rcpFormatDoc.Load(recipeSchema);                XmlNodeList rcpItemNodeList = rcpFormatDoc.SelectNodes("/Aitex/TableRecipeFormat/Catalog/Group/Step");                foreach (XmlElement item in rcpItemNodeList)                    recipeAllowedCommands.Add(item.Attributes["ControlName"].Value);                //获取工艺程序文件中所有步的内容                XmlDocument rcpDataDoc = new XmlDocument();                rcpDataDoc.LoadXml(recipe);                recipeHead.PressureMode = rcpDataDoc.DocumentElement.HasAttribute("PressureMode") ? rcpDataDoc.DocumentElement.Attributes["PressureMode"].Value : "";                recipeHead.BasePressure = rcpDataDoc.DocumentElement.HasAttribute("BasePressure") ? rcpDataDoc.DocumentElement.Attributes["BasePressure"].Value : "";                recipeHead.PumpDownLimit = rcpDataDoc.DocumentElement.HasAttribute("PumpDownLimit") ? rcpDataDoc.DocumentElement.Attributes["PumpDownLimit"].Value : "";                recipeHead.PurgeActive = rcpDataDoc.DocumentElement.HasAttribute("PurgeActive") ? rcpDataDoc.DocumentElement.Attributes["PurgeActive"].Value : "";                recipeHead.MatchPositionC1 = rcpDataDoc.DocumentElement.HasAttribute("MatchPositionC1") ? rcpDataDoc.DocumentElement.Attributes["MatchPositionC1"].Value : "";                recipeHead.MatchPositionC2 = rcpDataDoc.DocumentElement.HasAttribute("MatchPositionC2") ? rcpDataDoc.DocumentElement.Attributes["MatchPositionC2"].Value : "";                recipeHead.Barcode = rcpDataDoc.DocumentElement.HasAttribute("Barcode") ? rcpDataDoc.DocumentElement.Attributes["Barcode"].Value : "";                recipeHead.SubstrateTemp = rcpDataDoc.DocumentElement.HasAttribute("SubstrateTemp") ? rcpDataDoc.DocumentElement.Attributes["SubstrateTemp"].Value : "";                recipeHead.PinStateAfterVent = rcpDataDoc.DocumentElement.HasAttribute("PinStateAfterVent") ? rcpDataDoc.DocumentElement.Attributes["PinStateAfterVent"].Value : "";                recipeHead.PumpingPinState = rcpDataDoc.DocumentElement.HasAttribute("PumpingPinState") ? rcpDataDoc.DocumentElement.Attributes["PumpingPinState"].Value : "";                recipeHead.PinDownPressure = rcpDataDoc.DocumentElement.HasAttribute("PinDownPressure") ? rcpDataDoc.DocumentElement.Attributes["PinDownPressure"].Value : "1000";                XmlNodeList stepNodeList = rcpDataDoc.SelectNodes("/TableRecipeData/Step");                for (int i = 0; i < stepNodeList.Count; i++)                {                    var recipeStep = new RecipeStep();                    recipeData.Add(recipeStep);                    XmlElement stepNode = stepNodeList[i] as XmlElement;                    Dictionary<string, string> dic = new Dictionary<string, string>();                    //遍历Step节点                    foreach (XmlAttribute att in stepNode.Attributes)                    {                        if (recipeAllowedCommands.Contains(att.Name))                        {                            dic.Add(att.Name, att.Value);                        }                    }                    //遍历Step子节点中所有的attribute属性节点                    foreach (XmlElement subStepNode in stepNode.ChildNodes)                    {                        foreach (XmlAttribute att in subStepNode.Attributes)                        {                            if (recipeAllowedCommands.Contains(att.Name))                            {                                dic.Add(att.Name, att.Value);                            }                        }                        //遍历Step子节点的子节点中所有的attribute属性节点                        foreach (XmlElement subsubStepNode in subStepNode.ChildNodes)                        {                            foreach (XmlAttribute att in subsubStepNode.Attributes)                            {                                if (recipeAllowedCommands.Contains(att.Name))                                {                                    dic.Add(att.Name, att.Value);                                }                            }                        }                    }                    recipeStep.IsJumpStep = true;//!Convert.ToBoolean(dic["Ramp"]);                    recipeStep.StepName = dic["Name"];                    recipeStep.StepTime = TimeSpan.Parse(dic["Time"]).TotalSeconds;                    string loopStr = dic["Loop"];                    recipeStep.IsLoopStartStep = System.Text.RegularExpressions.Regex.Match(loopStr, @"Loop\x20\d+\s*$").Success;                    recipeStep.IsLoopEndStep = System.Text.RegularExpressions.Regex.Match(loopStr, @"Loop End$").Success;                    if (recipeStep.IsLoopStartStep)                        recipeStep.LoopCount = Convert.ToInt32(loopStr.Replace("Loop", string.Empty));                    else                        recipeStep.LoopCount = 0;                    //recipeStep.EndByValue = Convert.ToDouble(dic["EndValue"]);                    recipeStep.EndBy = dic["EndBy"];                    if (recipeStep.EndBy == "EndByRfTime")                    {                        recipeStep.StepTime = TimeSpan.Parse(dic["Rf.SetPowerOnTime"]).TotalSeconds;                        if (recipeStep.StepTime <= 0)                        {                            LOG.Error("recipe 没有定义RF Power on的时间");                            return false;                        }                    }                    int rfPower = (int)Convert.ToDouble(dic["Rf.SetPower"]);                    dic.Add("Rf.SetPowerOnOff", rfPower > 0 ? "true" : "false");                    //dic.Remove("Ramp");                    dic.Remove("StepNo");                    dic.Remove("Name");                    dic.Remove("Loop");                    dic.Remove("Time");                    dic.Remove("EndBy");                    //dic.Remove("EndValue");                    dic.Remove("Rf.SetPowerOnTime");                    foreach (string key in dic.Keys)                        recipeStep.RecipeCommands.Add(key, dic[key]);                }            }            catch (Exception ex)            {                LOG.Write(ex);                return false;            }            return true;        }    }}
 |