123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Windows.Forms;
- using System.Xml;
- using Aitex.Common.Util;
- using Aitex.Core.Properties;
- using Aitex.Core.RT.ConfigCenter;
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Log;
- using Aitex.Core.Util;
- namespace Aitex.Core.RT.SCCore
- {
- public class SCManager :ISCManager
- {
- private SCData _scData;
- private static object itemLocker = new object();
- private Dictionary<string, object> _items;
-
- public string ChamberName
- {
- get;
- set;
- }
- /// <summary>
- /// Get Variation name
- /// </summary>
- public string Path
- {
- get;
- set;
- }
-
- /// <summary>
- /// 反应腔系统参数配置类
- /// </summary>
- public SCManager()
- {
- SC.Manager = this;
- }
- public bool Initialize()
- {
- _items = new Dictionary<string, object>();
- Path = PathManager.GetCfgDir();
- //初始化系统配置
- var cfgFInfo = new FileInfo(Path + "PmConfig.xml");
- var cfgbakFInfo = new FileInfo(Path + "PmConfig.xml.bak");
- try
- {
- if (!cfgFInfo.Exists && !cfgbakFInfo.Exists)/*如果PmConfig.xml文件不存在,则创建默认的配置文件*/
- File.Copy(Path + "SCDefaultConfig.xml", Path + "PmConfig.xml");
- if (!DoPmConfigFileMerge(Path + "SCDefaultConfig.xml", Path + "PmConfig.xml"))
- {
- if (!DoPmConfigFileMerge(Path + "SCDefaultConfig.xml", Path + "PmConfig.xml.bak"))
- {
- throw new Exception("合并反应腔参数配置文件Config\\PmConfig.xml发生异常");
- }
- else
- {
- //对合并后的参数配置文件进行反序列化
- _scData = DeserialFromXml<SCData>(Path + "PmConfig.xml.bak");
- }
- }
- else
- {
- _scData = DeserialFromXml<SCData>(Path + "PmConfig.xml");
- }
-
- //对合并后的参数配置文件进行反序列化
- if (_scData == null)
- throw new Exception("反序列化配置文件Config\\PmConfig.xml(.bak)发生异常");
- //调用Config对象的初始化方法
- Init();
- _items = GetItems();
- foreach (var item in _items)
- {
- string sc = item.Key;
- CONFIG.Subscribe("", sc, () => { return GetItemValue(sc); });
- }
- return true;
- }
- catch (Exception ex)
- {
- var errMsg = "读取系统配置文件发生错误";
- LOG.Write(ex, errMsg);
- MessageBox.Show(ex.Message, errMsg, MessageBoxButtons.OK, MessageBoxIcon.Error);
- Environment.Exit(0);
- }
- return false;
- }
- public void Terminate()
- {
- _bAlive = false;
- }
- public T GetItem<T>(string name) where T :class
- {
- T item = null;
- lock (itemLocker)
- {
- if (_items.ContainsKey(name))
- {
- item = _items[name] as T;
- }
- }
- if (item == null)
- {
- LOG.Warning(String.Format("SC find item is null, name is {0}\"", name));
- }
- return item;
- }
- public SCString GetStringItem(string name)
- {
- SCString item = null;
- lock (itemLocker)
- {
- if (_items.ContainsKey(name))
- {
- item = _items[name] as SCString;
- }
- }
- if (item == null)
- {
- LOG.Warning(String.Format("SC find item is null, name is {0}\"", name));
- }
- return item;
- }
- public object GetItemValue(string name)
- {
- SCItem data = GetItem<SCItem>(name);
- if (data is SCItem<double>)
- {
- return ((SCItem<double>)(data)).Value;
- }
- else if (data is SCItem<bool>)
- {
- return ((SCItem<bool>)(data)).Value;
- }
- else if (data is SCItem<int>)
- {
- return ((SCItem<int>)(data)).Value;
- }
- else if (data is SCString)
- {
- return ((SCString)(data)).Value;
- }
- return null;
- }
- public void SetItemValue(string name, object value)
- {
- SCItem data = GetItem<SCItem>(name);
- if (data is SCItem<double>)
- {
- double setpoint = Convert.ToDouble(value.ToString());
- double min = ((SCItem<double>) (data)).RangeLowLimit;
- double max = ((SCItem<double>)(data)).RangeUpLimit;
- if ( (setpoint < min) || (setpoint > max))
- {
- EV.PostMessage("System", EventEnum.DefaultWarning, string.Format(Resources.SCManager_SetItemValue_0SetpointShouldBeIn1And2SettingValue3IsNotValid, data.Description, min, max, setpoint));
- return;
- }
- setpoint = Math.Min(setpoint, ((SCItem<double>) (data)).RangeUpLimit);
- setpoint = Math.Max(setpoint, ((SCItem<double>) (data)).RangeLowLimit);
- ((SCItem<double>)(data)).Value = setpoint;
- }
- else if (data is SCItem<bool>)
- {
- ((SCItem<bool>)(data)).Value = Convert.ToBoolean(value.ToString());
- }
- else if (data is SCItem<int>)
- {
- int setpoint = Convert.ToInt32(value.ToString());
- setpoint = Math.Min(setpoint, ((SCItem<int>)(data)).RangeUpLimit);
- setpoint = Math.Max(setpoint, ((SCItem<int>)(data)).RangeLowLimit);
- ((SCItem<int>)(data)).Value = setpoint;
- }
- else if (data is SCString)
- {
- ((SCString)(data)).Value = (string)value;
- }
- }
- /// <summary>
- /// 启动参数保存线程
- /// 保存的参数包括2类:
- /// 1. 静态参数,用户在界面直接设定后不会再次改变;
- /// 2. 动态参数,MO源使用量等,随着工艺程序运行,程序会自动改变其设定值
- /// </summary>
- private void Init()
- {
- _cfgThread = new System.Threading.Thread(new System.Threading.ThreadStart(Pm_Config_Thread));
- _cfgThread.IsBackground = true;
- _cfgThread.Priority = System.Threading.ThreadPriority.BelowNormal;
- // _cfgThread.Name = string.Format("{0} 参数保存线程", Reactor.PmName);
- _cfgThread.Name = string.Format("{0} 参数保存线程", "PM");
-
- _cfgThread.Start();
-
- // ActionLink.Attach(ActionType.AppQuit, (o1, o2, o3, o4) => _bAlive = false); //注册程序退出事件
- // DataCenter.Subscribe(PmKeySet.Pm_Variation, () => Variation);
- }
- R_TRIG _autoSaveCfg = new R_TRIG();
- DateTime _lastSaveCfgDt = DateTime.MinValue;
- bool _saveBackupFile = true; //指名当前保存哪个参数配置文件
- System.Threading.Thread _cfgThread; //参数配置维护线程,用于定时存储当前配置参数到磁盘
- bool _bAlive = true;
- /// <summary>
- /// PM参数保存线程
- /// </summary>
- void Pm_Config_Thread()
- {
- while (_bAlive)
- {
- TaskRun();
- System.Threading.Thread.Sleep(5000);
- }
- }
- /// <summary>
- /// 参数保存的任务线程实现
- /// </summary>
- private void TaskRun()
- {
- try
- {
- //保存配置文件到备份文件
- if (_saveBackupFile)
- {
- //System.Diagnostics.Debug.WriteLine("序列化 To Bak File");
- if (ObjectSerializer.SerializeObjectToXmlFile(Path + "PmConfig.xml.bak", this._scData))
- {
- _saveBackupFile = false;
- //System.Diagnostics.Debug.WriteLine("序列化 To Bak File - OK");
- }
- }
- else
- {
- //System.Diagnostics.Debug.WriteLine("序列化 To Config File");
- //延迟5秒钟后保存到备份文件,之所以不同时保存备份文件的原因是:计算机如果突然掉电,也可能导致2个配置文件同时损坏
- System.IO.File.Copy(Path + "PmConfig.xml.bak", Path + "PmConfig.xml", true);
- _saveBackupFile = true;
- //System.Diagnostics.Debug.WriteLine("序列化 To Config File - OK");
- }
- //每天自动保存PM的配置文件。每次PM程序启动自动保存当前配置文件
- _autoSaveCfg.CLK = DateTime.Today != _lastSaveCfgDt;
- if (_autoSaveCfg.Q)
- {
- var autoSaveCfgPath = Path + "Bak\\";
- System.IO.DirectoryInfo di = new DirectoryInfo(autoSaveCfgPath);
- if (!di.Exists)
- {
- di.Create();
- }
- di.Attributes = FileAttributes.Hidden;
- System.IO.File.Copy(Path + "PmConfig.xml.bak",
- string.Format("{0}{1}.{2}", autoSaveCfgPath, DateTime.Now.ToString("yyyyMMdd_HHmmss"), "PmConfig.xml"), true);
- _lastSaveCfgDt = DateTime.Today;
- }
- }
- catch (Exception ex)
- {
- LOG.Write(ex, "参数保存出错");
- }
- }
- string entryString = @" <Entry Name=""{0}"" Description=""{1}"" Type=""{2}"" Unit=""{3}"" Value=""{4}"" Default=""{5}"" RangeLowLimit=""{6}"" RangeUpLimit=""{7}"" />";
- // string sectionString = @" <Section Name=""{0}"" Description=""{1}"">";
- /// <summary>
- /// 以xml形式返回PM的配置数据
- /// </summary>
- /// <returns></returns>
- public string GetXmlConfig(string path)
- {
- try
- {
- FieldInfo[] datas = typeof(SCData).GetFields();
- StringBuilder sb = new StringBuilder();
- sb.Append("<?xml version=\"1.0\"?><SCData xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
- string headersb = "";
- StringBuilder contentSb = new StringBuilder();
- foreach (FieldInfo fi in datas)
- {
- FieldInfo[] FIfields = fi.FieldType.GetFields();
- object fiValue = fi.GetValue(_scData);
- contentSb.Clear();
- foreach (FieldInfo innerFI in FIfields)
- {
- ///确保类的格式和最开始定义的一致,只有一个string类型的为描述字段
- if (innerFI.FieldType.Name == "String")
- headersb = (string.Format(@" <Section Name=""{0}"" Description=""{1}"">", fi.Name, innerFI.GetValue(fiValue)));
- else
- contentSb.Append(getXMLString(innerFI.GetValue(fiValue), innerFI.Name));
- }
- sb.Append(headersb);
- sb.Append(contentSb.ToString());
- sb.Append(" </Section>");
- }
- sb.Append("</SCData>");
- return sb.ToString();
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- return "";
- }
- }
- string getXMLString<T>(T data, string fieldName)
- {
- if (data is SCItem<double>)
- {
- return string.Format(entryString, fieldName, typeof(SCItem<double>).GetField("Description").GetValue(data), "Double", typeof(SCItem<double>).GetField("Unit").GetValue(data), typeof(SCItem<double>).GetField("Value").GetValue(data), typeof(SCItem<double>).GetField("Default").GetValue(data), typeof(SCItem<double>).GetField("RangeLowLimit").GetValue(data), typeof(SCItem<double>).GetField("RangeUpLimit").GetValue(data));
- }
- else if (data is SCItem<bool>)
- {
- return string.Format(entryString, fieldName, typeof(SCItem<bool>).GetField("Description").GetValue(data), "Int32", "", (bool)typeof(SCItem<bool>).GetField("Value").GetValue(data) ? 1 : 0, (bool)typeof(SCItem<bool>).GetField("Default").GetValue(data) ? 1 : 0, 0, 1);
- }
- else if (data is SCItem<int>)
- {
- return string.Format(entryString, fieldName, typeof(SCItem<int>).GetField("Description").GetValue(data), "Int32", typeof(SCItem<int>).GetField("Unit").GetValue(data), typeof(SCItem<int>).GetField("Value").GetValue(data), typeof(SCItem<int>).GetField("Default").GetValue(data), typeof(SCItem<int>).GetField("RangeLowLimit").GetValue(data), typeof(SCItem<int>).GetField("RangeUpLimit").GetValue(data));
- }
- else if (data is SCString)
- {
- return string.Format(entryString, fieldName, typeof(SCString).GetField("Description").GetValue(data), "String", typeof(SCString).GetField("Unit").GetValue(data), typeof(SCString).GetField("Value").GetValue(data), typeof(SCString).GetField("Default").GetValue(data), "", "");
- }
- else if (data is SCItem<double>[])
- {
- SCItem<double>[] cfgList = data as SCItem<double>[];
- if (cfgList != null)
- {
- StringBuilder sb = new StringBuilder();
- int i = 1;
- foreach (SCItem<double> cDouble in cfgList)
- {
- sb.Append(string.Format(entryString, fieldName + (i++), typeof(SCItem<double>).GetField("Description").GetValue(cDouble), "Double", typeof(SCItem<double>).GetField("Unit").GetValue(cDouble), typeof(SCItem<double>).GetField("Value").GetValue(cDouble), typeof(SCItem<double>).GetField("Default").GetValue(cDouble), typeof(SCItem<double>).GetField("RangeLowLimit").GetValue(cDouble), typeof(SCItem<double>).GetField("RangeUpLimit").GetValue(cDouble)));
- }
- return sb.ToString();
- }
- }
- return "";
- }
- public bool UpdateConfiguration(string groupName, List<ConfigEntry> lstEntry)
- {
- bool ret = true;
-
- try
- {
- foreach (ConfigEntry entry in lstEntry)
- {
- string error;
- if (!SaveConfig(groupName, entry.EntryName, entry.Value, out error))
- {
- LOG.Error(string.Format("保存SC失败{0}.{1}, {2}", groupName, entry.EntryName, error));
- ret =false;
- }
- }
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- return false;
- }
- return ret;
- }
- /// <summary>
- /// 修改反应腔参数
- /// </summary>
- /// <param name="groupName">参数组名</param>
- /// <param name="elementName">参数元素名</param>
- /// <param name="cfgValue">参数值</param>
- /// <param name="failReason">如果操作失败,返回的失败原因</param>
- /// <returns>True:操作成功 | False:操作失败</returns>
- public bool SaveConfig(string groupName, string elementName, string cfgValue, out string failReason)
- {
- try
- {
- XmlDocument xmlDom = new XmlDocument();
- foreach (FieldInfo fi in typeof(SCData).GetFields())
- {
- if (fi.Name == groupName)
- {
- object obj = fi.GetValue(_scData);
- foreach (FieldInfo infi in obj.GetType().GetFields())
- {
- if (infi.Name == elementName)
- {
- object valueobj = infi.GetValue(obj);
- foreach (FieldInfo valueField in valueobj.GetType().GetFields())
- {
- if (valueField.Name == "Value")
- {
- Type curType = valueField.FieldType;
- if (curType.Name.ToLower() == "boolean")
- {
- cfgValue = cfgValue == "0" ? "false" : "true";
- }
- var convertedValue = Convert.ChangeType(cfgValue, curType);
- object oldvalue = valueField.GetValue(valueobj);
- if (oldvalue + "" != convertedValue + "")
- {
- valueField.SetValue(valueobj, convertedValue);
-
- //@AAA ActionLink.Notify(ActionType.ConfigurationChanged, Aitex.FlyWheel.Reactor.ChamId, groupName, elementName, convertedValue);
- }
- break;
- }
- }
- break;
- }
- }
- break;
- }
- }
- failReason = "";
- return true;
- }
- catch (Exception ex)
- {
- failReason = string.Format("保存失败:{0}", ex.Message);
- return false;
- }
- }
- private Dictionary<string, object> GetItems()
- {
- try
- {
- Dictionary<string, object> items = new Dictionary<string, object>();
- FieldInfo[] datas = typeof(SCData).GetFields();
-
- foreach (FieldInfo fiGroup in datas)
- {
- object objGroup = fiGroup.GetValue(_scData);
- foreach (FieldInfo fiItem in objGroup.GetType().GetFields())
- {
- object item = fiItem.GetValue(objGroup);
- if (item is SCItem)
- {
- string name = String.Format("{0}_{1}", fiGroup.Name, fiItem.Name);
-
- if (items.ContainsKey(name))
- {
- LOG.Warning("Find Confilct SC name {0}",name);
- continue;
- }
-
- items.Add(name, item);
- }
- }
-
- }
- return items;
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- throw(ex);
- }
- }
-
- /// <summary>
- /// 合并PM的配置文件
- /// </summary>
- /// <param name="referenceConfigFile">标准的参数配置引用文件</param>
- /// <param name="currentConfigFile">当前设备使用的参数配置文件</param>
- /// <returns></returns>
- private bool DoPmConfigFileMerge(string referenceConfigFile, string currentConfigFile)
- {
- try
- {
- XmlDocument doc1 = new XmlDocument();
- XmlDocument doc2 = new XmlDocument();
- doc1.Load(currentConfigFile);
- doc2.Load(referenceConfigFile);
- foreach (XmlElement groupNode in doc2.DocumentElement.ChildNodes)
- {
- string groupName = groupNode.Name;
- foreach (XmlNode elementNode in groupNode.ChildNodes)
- {
- if (elementNode.NodeType != XmlNodeType.Element) continue;
- string elementName = elementNode.Name;
- string xpath = string.Format("/SCData/{0}/{1}/Value", groupName, elementName);
- var localValueNode = doc1.SelectSingleNode(xpath) as XmlElement;
- if (localValueNode == null || string.IsNullOrEmpty(localValueNode.InnerText))
- continue;
- elementNode.SelectSingleNode("Value").InnerText = localValueNode.InnerText;
- }
- }
- doc2.Save(currentConfigFile);
- }
- catch (Exception ex)
- {
- LOG.Write(ex, string.Format("合并{0},{1}发生错误", referenceConfigFile, currentConfigFile));
- return false;
- }
- return true;
- }
- /// <summary>
- /// 从XML文件反序列化重建设备模块
- /// 1. 如果XML序列化文件不存在,则新生成XML序列化文件
- /// 2. 如果反序列化文件失败,则自动反序列化该文件默认的备份文件
- /// </summary>
- /// <typeparam name="T">对象类型</typeparam>
- /// <param name="filePath">对象序列化文件路径</param>
- /// <returns>反序列化后的对象</returns>
- public T DeserialFromXml<T>(string filePath)
- {
- FileInfo fi = new FileInfo(filePath);
- FileInfo fiBakup = new FileInfo(filePath + ".bak");
- T obj = default(T);
- if (!fi.Exists && !fiBakup.Exists)
- return default(T);
- try
- {
- obj = (T)ObjectSerializer.DeserializeObjectFromXmlFile<T>(filePath);
- }
- catch (Exception ex)
- {
- LOG.Write(ex, string.Format("反序列化{0}出错", filePath));
- try
- {
- obj = (T)ObjectSerializer.DeserializeObjectFromXmlFile<T>(filePath + ".bak");
- }
- catch (Exception ex2)
- {
- LOG.Write(ex2, string.Format("反序列化{0}出错", filePath + ".bak"));
- return default(T);
- }
- }
- return obj;
- }
- //help function
- public void GenerateEnumName()
- {
- string file = Path + @"_SCName.cs";
- StringBuilder sb = new StringBuilder();
- sb.AppendLine(string.Format("//文件根据{0}生成", "SCData.cs"));
- sb.AppendLine(string.Format("//生成时间:{0}", DateTime.Now.ToString()));
- sb.AppendLine();
- sb.AppendLine(@"
- namespace Aitex.Common.Core
- {
- public class SCName
- {");
- foreach (string name in _items.Keys)
- {
- sb.AppendLine(String.Format("\t\t\t public const string {0} = \"{0}\";", name.Replace('.','_'), name));
- sb.AppendLine();
- }
- sb.AppendLine(@"
- }
- }");
- using (StreamWriter sw = new StreamWriter(file, false))
- {
- sw.Write(sb.ToString());
- sw.Close();
- }
- }
- }
- }
|