using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Xml; using Aitex.Common.Util; using Aitex.Core.RT.ConfigCenter; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; namespace MECF.Framework.Common.SCCore { public class SystemConfigManager : Singleton, ISCManager { private Dictionary _items = new Dictionary(); private object _itemLocker = new object(); private string _scConfigFile ; private string _scDataFile = PathManager.GetCfgDir() + "_sc.data"; private string _scDataBackupFile = PathManager.GetCfgDir() + "_sc.data.bak"; private string _scDataErrorFile = PathManager.GetCfgDir() + "_sc.data.err."; public void Initialize(string scConfigPathName) { _scConfigFile = scConfigPathName; BuildItems(_scConfigFile); BackupAndRecoverDataFile(); CustomData(); GenerateDataFile(); foreach (var item in _items) { CONFIG.Subscribe("", item.Key, ()=>item.Value.Value); } OP.Subscribe("System.SetConfig", InvokeSetConfig); SC.Manager = this; } private bool InvokeSetConfig(string cmd, object[] parameters) { string key = (string) parameters[0]; object old = GetConfigValueAsObject(key); if ((string)parameters[0] == "PMB.Chiller.ChillerSameWithPMA" && (string)parameters[1] == "true") { if (_items["PMA.Chiller.EnableChiller"].Value.ToString() == "False") return true; } if (InitializeItemValue(_items[(string)parameters[0]], (string)parameters[1])) { GenerateDataFile(); LOG.Write(eEvent.EV_SYSTEM_CONFIG, ModuleName.System, string.Format("SC {0} value changed from {1} to {2}", key, old, parameters[1])); } if ((string)parameters[0] == "PMA.Chiller.EnableChiller" && (string)parameters[1] == "false") { if (_items["PMB.Chiller.ChillerSameWithPMA"].Value.ToString() == "False") return true; if (InitializeItemValue(_items["PMB.Chiller.ChillerSameWithPMA"], "False")) { GenerateDataFile(); LOG.Write(eEvent.EV_SYSTEM_CONFIG, ModuleName.System, string.Format("SC {0} value changed from {1} to {2}", "PMB.Chiller.ChillerSameWithPMA", "true", "false")); } } if ((string)parameters[0] == "PMB.Chiller.EnableChiller" && (string)parameters[1] == "false") { if (_items["PMB.Chiller.ChillerSameWithPMA"].Value.ToString() == "False") return true; if (InitializeItemValue(_items["PMB.Chiller.EnableChiller"], "true")) { GenerateDataFile(); LOG.Write(eEvent.EV_SYSTEM_CONFIG, ModuleName.System, string.Format("SC {0} value changed from {1} to {2}", "PMB.Chiller.EnableChiller", "false", "true")); } } if ((string)parameters[0] == "PMB.Chiller.ChillerSameWithPMA" && (string)parameters[1] == "true") { if (_items["PMB.Chiller.EnableChiller"].Value.ToString() == "True") return true; if (InitializeItemValue(_items["PMB.Chiller.EnableChiller"], "true")) { GenerateDataFile(); LOG.Write(eEvent.EV_SYSTEM_CONFIG, ModuleName.System, string.Format("SC {0} value changed from {1} to {2}", "PMB.Chiller.EnableChiller", "false", "true")); } } return true; } public void Terminate() { } public string GetFileContent() { if (!File.Exists(_scConfigFile)) return ""; StringBuilder s = new StringBuilder(); try { using (StreamReader sr = new StreamReader(_scConfigFile)) { while (!sr.EndOfStream) { s.Append(sr.ReadLine()); } } } catch (Exception ex) { LOG.WriteExeption(ex); return ""; } return s.ToString(); } private void BuildItems(string xmlFile) { XmlDocument xml = new XmlDocument(); try { var _sc_stream = File.Open(xmlFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read); xml.Load(_sc_stream); XmlNodeList nodeConfigs = xml.SelectNodes("root/configs"); foreach (XmlElement nodeConfig in nodeConfigs) { BuildPathConfigs(nodeConfig.GetAttribute("name"), nodeConfig as XmlElement); } } catch (Exception ex) { LOG.WriteExeption(ex); } } private void BuildPathConfigs(string parentPath, XmlElement configElement) { XmlNodeList nodeConfigsList = configElement.SelectNodes("configs"); foreach (XmlElement nodeConfig in nodeConfigsList) { if (string.IsNullOrEmpty(parentPath)) { BuildPathConfigs(nodeConfig.GetAttribute("name"), nodeConfig as XmlElement); } else { BuildPathConfigs(parentPath + "." + nodeConfig.GetAttribute("name"), nodeConfig as XmlElement); } } XmlNodeList nodeConfigs = configElement.SelectNodes("config"); foreach (XmlElement nodeConfig in nodeConfigs) { SCConfigItem item = new SCConfigItem() { Default = nodeConfig.GetAttribute("default"), Name = nodeConfig.GetAttribute("name"), Description = nodeConfig.GetAttribute("description"), Max = nodeConfig.GetAttribute("max"), Min = nodeConfig.GetAttribute("min"), Parameter = nodeConfig.GetAttribute("paramter"), Path = parentPath, Tag = nodeConfig.GetAttribute("tag"), Type = nodeConfig.GetAttribute("type"), Unit = nodeConfig.GetAttribute("unit"), }; InitializeItemValue(item, item.Default); if (_items.ContainsKey(item.PathName)) { //LOG.Error("Duplicated SC item, "+ item.PathName); } _items[item.PathName] = item; } } private void BackupAndRecoverDataFile() { try { if (File.Exists(_scDataFile) && IsXmlFileLoadable(_scDataFile)) { File.Copy(_scDataFile, _scDataBackupFile, true); } else if (File.Exists(_scDataBackupFile) && IsXmlFileLoadable(_scDataBackupFile)) { if (File.Exists(_scDataFile)) { File.Copy(_scDataFile, _scDataErrorFile + DateTime.Now.ToString("yyyyMMdd_HHmmss"), true); } File.Copy(_scDataBackupFile, _scDataFile, true); } } catch (Exception ex) { LOG.WriteExeption(ex); } } private void CustomData() { Dictionary values = new Dictionary(); try { if (File.Exists(_scDataFile)) { XmlDocument xmlData = new XmlDocument(); var _sc_stream = File.Open(_scDataFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read); xmlData.Load(_sc_stream); XmlNodeList scdatas = xmlData.SelectNodes("root/scdata"); foreach (XmlElement nodedata in scdatas) { string name = nodedata.GetAttribute("name"); if (_items.ContainsKey(name)) { InitializeItemValue(_items[name], nodedata.GetAttribute("value")); } } _sc_stream.Close(); } } catch (Exception ex) { LOG.WriteExeption(ex); } } private void GenerateDataFile() { try { XmlDocument xml = new XmlDocument(); xml.LoadXml(""); XmlElement nodeRoot = xml.SelectSingleNode("root") as XmlElement; foreach (var scConfigItem in _items) { XmlElement node = xml.CreateElement("scdata"); node.SetAttribute("name", scConfigItem.Key); node.SetAttribute("value", scConfigItem.Value.Value.ToString()); nodeRoot.AppendChild(node); } if (File.Exists(_scDataFile) && IsXmlFileLoadable(_scDataFile)) { File.Copy(_scDataFile, _scDataBackupFile, true); //File.Delete(_scDataFile); } using (FileStream fsFileStream = new FileStream(_scDataFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 1024, FileOptions.WriteThrough)) { fsFileStream.SetLength(0); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.OmitXmlDeclaration = false; using (XmlWriter xmlWrite = XmlWriter.Create(fsFileStream, settings)) { xml.Save(xmlWrite); } } } catch (Exception ex) { LOG.WriteExeption(ex); } } private bool IsXmlFileLoadable(string file) { try { XmlDocument xml = new XmlDocument(); xml.Load(file); } catch (Exception ex) { LOG.WriteExeption(ex); return false; } return true; } public SCConfigItem GetConfigItem(string name) { //Debug.Assert(_items.ContainsKey(name), "can not find sc name, "+name); if (!_items.ContainsKey(name)) { return null; } return _items[name]; } public bool ContainsItem(string name) { return _items.ContainsKey(name); } public object GetConfigValueAsObject(string name) { SCConfigItem item = GetConfigItem(name); if(item == null) { return null; } switch (item.Type) { case "Bool": return item.BoolValue; case "Integer": return item.IntValue; case "Double": return item.DoubleValue; case "String": return item.StringValue; } return null; } public T GetValue(string name) where T : struct { try { if (typeof(T) == typeof(bool)) return (T)(object)_items[name].BoolValue; if (typeof(T) == typeof(int)) return (T)(object)_items[name].IntValue; if (typeof(T) == typeof(double)) return (T)(object)_items[name].DoubleValue; } catch (KeyNotFoundException) { MessageBox.Show($"Can not find system config item {name}"); return default(T); } catch (Exception) { MessageBox.Show($"Can not get valid system config item value {name}"); return default(T); } Debug.Assert(false, "unsupported type"); return default(T); } public string GetStringValue(string name) { if (!_items.ContainsKey(name)) return null; return _items[name].StringValue; } public List GetItemList() { return _items.Values.ToList(); } public void SetItemValueFromString(string name, string value) { if (InitializeItemValue(_items[name], value)) { GenerateDataFile(); } } private bool InitializeItemValue(SCConfigItem item, string value) { bool changed = false; switch (item.Type) { case "Bool": bool boolValue; if (bool.TryParse(value, out boolValue) && boolValue != item.BoolValue) { item.BoolValue = boolValue; changed = true; } break; case "Integer": int intValue; if (int.TryParse(value, out intValue) && intValue != item.IntValue) { int.TryParse(item.Min, out int min); int.TryParse(item.Max, out int max); if (intValue max) { LOG.Write(eEvent.WARN_SYSTEM_CONFIG, ModuleName.System, $"SC {item.PathName} value {intValue} out of setting range ({item.Min}, {item.Max})"); break; } item.IntValue = intValue; changed = true; } break; case "Double": double doubleValue; if (double.TryParse(value, out doubleValue) && Math.Abs(doubleValue - item.DoubleValue) > 0.0001) { double.TryParse(item.Min, out double min); double.TryParse(item.Max, out double max); if (doubleValue < min || doubleValue > max) { LOG.Write(eEvent.WARN_SYSTEM_CONFIG, ModuleName.System, $"SC {item.PathName} value {doubleValue} out of setting range ({item.Min}, {item.Max})"); break; } item.DoubleValue = doubleValue; changed = true; } break; case "String": if (value != item.StringValue) { item.StringValue = value; changed = true; } break; } return changed; } public void SetItemValue(string name, object value) { Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name); if (!_items.ContainsKey(name)) { return; } bool changed = false; switch (_items[name].Type) { case "Bool": bool boolValue = (bool)value; if (boolValue != _items[name].BoolValue) { _items[name].BoolValue = boolValue; changed = true; } break; case "Integer": int intValue = (int)value; if (intValue != _items[name].IntValue) { _items[name].IntValue = intValue; changed = true; } break; case "Double": double doubleValue = (double)value; if (Math.Abs(doubleValue - _items[name].DoubleValue) > 0.0001) { _items[name].DoubleValue = doubleValue; changed = true; } break; case "String": string stringValue = (string)value; if (stringValue != _items[name].StringValue) { _items[name].StringValue = stringValue; changed = true; } break; } if (changed) { GenerateDataFile(); } } public void SetItemValueStringFormat(string name, string value) { Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name); if (!_items.ContainsKey(name)) { return; } bool changed = false; switch (_items[name].Type) { case "Bool": bool boolValue = Convert.ToBoolean(value); if (boolValue != _items[name].BoolValue) { _items[name].BoolValue = boolValue; changed = true; } break; case "Integer": int intValue = Convert.ToInt32(value); if (intValue != _items[name].IntValue) { _items[name].IntValue = intValue; changed = true; } break; case "Double": double doubleValue = Convert.ToDouble(value); if (Math.Abs(doubleValue - _items[name].DoubleValue) > 0.0001) { _items[name].DoubleValue = doubleValue; changed = true; } break; case "String": string stringValue = (string)value; if (stringValue != _items[name].StringValue) { _items[name].StringValue = stringValue; changed = true; } break; } if (changed) { GenerateDataFile(); } } public void SetItemValue(string name, bool value) { Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name); Debug.Assert(_items[name].Type=="Bool", "sc type not bool, defined as" + _items[name].Type); if (value != _items[name].BoolValue) { _items[name].BoolValue = value; GenerateDataFile(); } } public void SetItemValue(string name, int value) { Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name); Debug.Assert(_items[name].Type == "Integer", "sc type not bool, defined as" + _items[name].Type); if (value != _items[name].IntValue) { _items[name].IntValue = value; GenerateDataFile(); } } public void SetItemValue(string name, double value) { Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name); Debug.Assert(_items[name].Type == "Double", "sc type not bool, defined as" + _items[name].Type); if (Math.Abs(value - _items[name].DoubleValue) > 0.0001) { _items[name].DoubleValue = value; GenerateDataFile(); } } public void SetItemValue(string name, string value) { Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name); if (value != _items[name].StringValue) { _items[name].StringValue = value; GenerateDataFile(); } } /// /// 获取配置前置 /// /// public string GetConfigPreContent(string cellName) { if (cellName.StartsWith("Buffer")) { return $"Buffer"; } else if (cellName.StartsWith("Loader")) { return "Loader1"; } else if (cellName.StartsWith("Rinse")) { return $"QDR"; } else if (cellName.StartsWith("Metal")) { return $"Metal"; } else if (cellName.StartsWith("Prewet")) { return "Prewet"; } else if (cellName.StartsWith("Dryer")) { return "Dryer"; } else { return ""; } } } }