SystemConfigManager.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Windows;
  9. using System.Xml;
  10. using Aitex.Common.Util;
  11. using Aitex.Core.RT.ConfigCenter;
  12. using Aitex.Core.RT.DataCenter;
  13. using Aitex.Core.RT.DBCore;
  14. using Aitex.Core.RT.Event;
  15. using Aitex.Core.RT.Log;
  16. using Aitex.Core.RT.OperationCenter;
  17. using Aitex.Core.RT.SCCore;
  18. using Aitex.Core.Util;
  19. using MECF.Framework.Common.Equipment;
  20. using MECF.Framework.Common.FAServices;
  21. namespace MECF.Framework.Common.SCCore
  22. {
  23. public class SystemConfigManager : Singleton<SystemConfigManager>, ISCManager
  24. {
  25. private Dictionary<string, SCConfigItem> _items = new Dictionary<string, SCConfigItem>(StringComparer.OrdinalIgnoreCase);
  26. private object _itemLocker = new object();
  27. private Dictionary<string, string> _scConfigFile = new Dictionary<string, string>();
  28. XmlDocument _xmlConfigContent;
  29. private string _scDataFile = PathManager.GetCfgDir() + "_sc.data";
  30. private string _scDataBackupFile = PathManager.GetCfgDir() + "_sc.data.bak";
  31. private string _scDataErrorFile = PathManager.GetCfgDir() + "_sc.data.err.";
  32. public List<VIDItem> VidConfigList
  33. {
  34. get
  35. {
  36. List<VIDItem> result = new List<VIDItem>();
  37. foreach (var dataItem in _items)
  38. {
  39. result.Add(new VIDItem()
  40. {
  41. DataType = "",
  42. Description = dataItem.Value.Description,
  43. Index = 0,
  44. Name = dataItem.Key,
  45. Unit = "",
  46. });
  47. }
  48. return result;
  49. }
  50. }
  51. public void Initialize(string scConfigPathName)
  52. {
  53. Initialize(scConfigPathName, "System", null);
  54. }
  55. /// <summary>
  56. /// 模块化配置
  57. /// </summary>
  58. /// <param name="scConfigPathName"></param>
  59. /// <param name="module"></param>
  60. /// <param name="moduleNamePlaceHolder"></param>
  61. public void Initialize(string scConfigPathName, string module, string moduleNamePlaceHolder)
  62. {
  63. if (_xmlConfigContent == null)
  64. {
  65. _xmlConfigContent = new XmlDocument();
  66. _xmlConfigContent.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><root></root>");
  67. BackupAndRecoverDataFile();
  68. OP.Subscribe("System.SetConfig", InvokeSetConfig);
  69. SC.Manager = this;
  70. }
  71. if (string.IsNullOrEmpty(module))
  72. module = "System";
  73. _scConfigFile[module] = scConfigPathName;
  74. Dictionary<string, SCConfigItem> newItem = BuildItems(scConfigPathName, module, moduleNamePlaceHolder);
  75. CustomData(newItem);
  76. GenerateDataFile();
  77. foreach (var item in _items)
  78. {
  79. if (newItem.ContainsKey(item.Key))
  80. {
  81. CONFIG.Subscribe("", item.Key, () => item.Value.Value);
  82. }
  83. }
  84. }
  85. private bool InvokeSetConfig(string cmd, object[] parameters)
  86. {
  87. string key = (string)parameters[0];
  88. if (!ContainsItem(key))
  89. {
  90. EV.PostWarningLog("System", string.Format("Not find SC with name {0}", key));
  91. return false;
  92. }
  93. object old = GetConfigValueAsObject(key);
  94. if (InitializeItemValue(_items[(string)parameters[0]], parameters[1].ToString()))
  95. {
  96. GenerateDataFile();
  97. EV.PostInfoLog("System", string.Format("SC {0} value changed from {1} to {2}", key, old, parameters[1]));
  98. }
  99. return true;
  100. }
  101. public void Terminate()
  102. {
  103. }
  104. public string GetFileContent()
  105. {
  106. if (_xmlConfigContent == null)
  107. return "";
  108. return _xmlConfigContent.InnerXml;// GetFileContent("System");
  109. }
  110. public string GetFileContent(string module)
  111. {
  112. if (string.IsNullOrEmpty(module))
  113. module = "System";
  114. if (!File.Exists(_scConfigFile[module]))
  115. return "";
  116. StringBuilder s = new StringBuilder();
  117. try
  118. {
  119. using (StreamReader sr = new StreamReader(_scConfigFile[module]))
  120. {
  121. while (!sr.EndOfStream)
  122. {
  123. s.Append(sr.ReadLine());
  124. }
  125. }
  126. }
  127. catch (Exception ex)
  128. {
  129. LOG.Write(ex);
  130. return "";
  131. }
  132. return s.ToString();
  133. }
  134. private Dictionary<string, SCConfigItem> BuildItems(string xmlFile, string module, string moduleNamePlaceHolder)
  135. {
  136. XmlDocument xml = new XmlDocument();
  137. Dictionary<string, SCConfigItem> newItem = new Dictionary<string, SCConfigItem>();
  138. try
  139. {
  140. xml.Load(xmlFile);
  141. XmlNodeList nodeConfigs = xml.SelectNodes("root/configs");
  142. XmlNode content = _xmlConfigContent.SelectSingleNode("root");
  143. foreach (XmlElement nodeConfig in nodeConfigs)
  144. {
  145. string nodeName = nodeConfig.GetAttribute("name");
  146. if (!string.IsNullOrEmpty(moduleNamePlaceHolder) && nodeName == moduleNamePlaceHolder)
  147. {
  148. string display = nodeConfig.GetAttribute("display");
  149. display = $"{module}-{display}";
  150. nodeConfig.SetAttribute("display", display);
  151. nodeName = module;
  152. }
  153. nodeConfig.SetAttribute("name", nodeName);
  154. content.AppendChild(_xmlConfigContent.ImportNode(nodeConfig, true));
  155. BuildPathConfigs(nodeName, nodeConfig as XmlElement, ref newItem);
  156. }
  157. }
  158. catch (Exception ex)
  159. {
  160. LOG.Write(ex);
  161. }
  162. return newItem;
  163. }
  164. private void BuildPathConfigs(string parentPath, XmlElement configElement, ref Dictionary<string, SCConfigItem> newItem)
  165. {
  166. XmlNodeList nodeConfigsList = configElement.SelectNodes("configs");
  167. foreach (XmlElement nodeConfig in nodeConfigsList)
  168. {
  169. if (string.IsNullOrEmpty(parentPath))
  170. {
  171. BuildPathConfigs(nodeConfig.GetAttribute("name"), nodeConfig as XmlElement, ref newItem);
  172. }
  173. else
  174. {
  175. BuildPathConfigs(parentPath + "." + nodeConfig.GetAttribute("name"), nodeConfig as XmlElement, ref newItem);
  176. }
  177. }
  178. XmlNodeList nodeConfigs = configElement.SelectNodes("config");
  179. foreach (XmlElement nodeConfig in nodeConfigs)
  180. {
  181. SCConfigItem item = new SCConfigItem()
  182. {
  183. Default = nodeConfig.GetAttribute("default"),
  184. Name = nodeConfig.GetAttribute("name"),
  185. Description = nodeConfig.GetAttribute("description"),
  186. Max = nodeConfig.GetAttribute("max"),
  187. Min = nodeConfig.GetAttribute("min"),
  188. Parameter = nodeConfig.GetAttribute("paramter"),
  189. Path = parentPath,
  190. Tag = nodeConfig.GetAttribute("tag"),
  191. Type = nodeConfig.GetAttribute("type"),
  192. Unit = nodeConfig.GetAttribute("unit"),
  193. };
  194. InitializeItemValue(item, item.Default);
  195. if (_items.ContainsKey(item.PathName))
  196. {
  197. LOG.Error("Duplicated SC item, " + item.PathName);
  198. }
  199. _items[item.PathName] = item;
  200. newItem[item.PathName] = item;
  201. }
  202. }
  203. private void BackupAndRecoverDataFile()
  204. {
  205. try
  206. {
  207. if (File.Exists(_scDataFile) && IsXmlFileLoadable(_scDataFile))
  208. {
  209. File.Copy(_scDataFile, _scDataBackupFile, true);
  210. }
  211. else if (File.Exists(_scDataBackupFile) && IsXmlFileLoadable(_scDataBackupFile))
  212. {
  213. if (File.Exists(_scDataFile))
  214. {
  215. File.Copy(_scDataFile, _scDataErrorFile + DateTime.Now.ToString("yyyyMMdd_HHmmss"), true);
  216. }
  217. File.Copy(_scDataBackupFile, _scDataFile, true);
  218. }
  219. }
  220. catch (Exception ex)
  221. {
  222. LOG.Write(ex);
  223. }
  224. }
  225. private void CustomData(Dictionary<string, SCConfigItem> item)
  226. {
  227. Dictionary<string, string> values = new Dictionary<string, string>();
  228. try
  229. {
  230. if (File.Exists(_scDataFile))
  231. {
  232. XmlDocument xmlData = new XmlDocument();
  233. xmlData.Load(_scDataFile);
  234. XmlNodeList scdatas = xmlData.SelectNodes("root/scdata");
  235. foreach (XmlElement nodedata in scdatas)
  236. {
  237. string name = nodedata.GetAttribute("name");
  238. if (_items.ContainsKey(name) && item.ContainsKey(name))
  239. {
  240. InitializeItemValue(_items[name], nodedata.GetAttribute("value"));
  241. InitializeItemValue(item[name], nodedata.GetAttribute("value"));
  242. }
  243. }
  244. }
  245. }
  246. catch (Exception ex)
  247. {
  248. LOG.Write(ex);
  249. }
  250. }
  251. private void GenerateDataFile()
  252. {
  253. try
  254. {
  255. Dictionary<string, string> oldData = new Dictionary<string, string>();
  256. if (File.Exists(_scDataFile))
  257. {
  258. try
  259. {
  260. XmlDocument xmlOld = new XmlDocument();
  261. xmlOld.Load(_scDataFile);
  262. XmlElement nodeRootOld = xmlOld.SelectSingleNode("root") as XmlElement;
  263. foreach (var node in nodeRootOld.ChildNodes)
  264. {
  265. XmlElement nodeData = node as XmlElement;
  266. oldData[nodeData.GetAttribute("name")] = nodeData.GetAttribute("value");
  267. }
  268. }
  269. catch (Exception ex)
  270. {
  271. LOG.Write(ex);
  272. }
  273. File.Copy(_scDataFile, _scDataBackupFile, true);
  274. }
  275. XmlDocument xml = new XmlDocument();
  276. xml.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><root></root>");
  277. XmlElement nodeRoot = xml.SelectSingleNode("root") as XmlElement;
  278. foreach (var scConfigItem in _items)
  279. {
  280. XmlElement node = xml.CreateElement("scdata");
  281. node.SetAttribute("name", scConfigItem.Key);
  282. node.SetAttribute("value", scConfigItem.Value.Value.ToString());
  283. nodeRoot.AppendChild(node);
  284. oldData.Remove(scConfigItem.Key);
  285. }
  286. foreach (var data in oldData)
  287. {
  288. XmlElement node = xml.CreateElement("scdata");
  289. node.SetAttribute("name", data.Key);
  290. node.SetAttribute("value", data.Value);
  291. nodeRoot.AppendChild(node);
  292. }
  293. using (FileStream fsFileStream = new FileStream(_scDataFile,
  294. FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 1024, FileOptions.WriteThrough))
  295. {
  296. fsFileStream.SetLength(0);
  297. XmlWriterSettings settings = new XmlWriterSettings();
  298. settings.Indent = true;
  299. settings.OmitXmlDeclaration = false;
  300. using (XmlWriter xmlWrite = XmlWriter.Create(fsFileStream, settings))
  301. {
  302. xml.Save(xmlWrite);
  303. }
  304. }
  305. }
  306. catch (Exception ex)
  307. {
  308. LOG.Write(ex);
  309. }
  310. }
  311. private bool IsXmlFileLoadable(string file)
  312. {
  313. try
  314. {
  315. XmlDocument xml = new XmlDocument();
  316. xml.Load(file);
  317. }
  318. catch (Exception ex)
  319. {
  320. LOG.Write(ex);
  321. return false;
  322. }
  323. return true;
  324. }
  325. public SCConfigItem GetConfigItem(string name)
  326. {
  327. //Debug.Assert(_items.ContainsKey(name), "can not find sc name, "+name);
  328. if (!_items.ContainsKey(name))
  329. {
  330. return null;
  331. }
  332. return _items[name];
  333. }
  334. public bool ContainsItem(string name)
  335. {
  336. return _items.ContainsKey(name);
  337. }
  338. public object GetConfigValueAsObject(string name)
  339. {
  340. SCConfigItem item = GetConfigItem(name);
  341. switch (item.Type)
  342. {
  343. case "Bool": return item.BoolValue;
  344. case "Integer": return item.IntValue;
  345. case "Double": return item.DoubleValue;
  346. case "String": return item.StringValue;
  347. }
  348. return null;
  349. }
  350. public T GetValue<T>(string name) where T : struct
  351. {
  352. try
  353. {
  354. if (typeof(T) == typeof(bool))
  355. return (T)(object)_items[name].BoolValue;
  356. if (typeof(T) == typeof(int))
  357. return (T)(object)_items[name].IntValue;
  358. if (typeof(T) == typeof(double))
  359. return (T)(object)_items[name].DoubleValue;
  360. }
  361. catch (KeyNotFoundException)
  362. {
  363. EV.PostAlarmLog("System", $"Can not find system config item {name}");
  364. return default(T);
  365. }
  366. catch (Exception)
  367. {
  368. EV.PostAlarmLog("System", $"Can not get valid system config item value {name}");
  369. return default(T);
  370. }
  371. Debug.Assert(false, "unsupported type");
  372. return default(T);
  373. }
  374. public string GetStringValue(string name)
  375. {
  376. if (!_items.ContainsKey(name))
  377. return null;
  378. return _items[name].StringValue;
  379. }
  380. public T SafeGetValue<T>(string name, T defaultValue) where T : struct
  381. {
  382. try
  383. {
  384. if (typeof(T) == typeof(bool))
  385. return (T)(object)_items[name].BoolValue;
  386. if (typeof(T) == typeof(int))
  387. return (T)(object)_items[name].IntValue;
  388. if (typeof(T) == typeof(double))
  389. return (T)(object)_items[name].DoubleValue;
  390. }
  391. catch (KeyNotFoundException)
  392. {
  393. return defaultValue;
  394. }
  395. catch (Exception)
  396. {
  397. return defaultValue;
  398. }
  399. Debug.Assert(false, "unsupported type");
  400. return defaultValue;
  401. }
  402. public string SafeGetStringValue(string name, string defaultValue)
  403. {
  404. if (!_items.ContainsKey(name))
  405. return defaultValue;
  406. return _items[name].StringValue;
  407. }
  408. public List<SCConfigItem> GetItemList()
  409. {
  410. return _items.Values.ToList();
  411. }
  412. public void SetItemValueFromString(string name, string value)
  413. {
  414. if (InitializeItemValue(_items[name], value))
  415. {
  416. GenerateDataFile();
  417. }
  418. }
  419. private bool InitializeItemValue(SCConfigItem item, string value)
  420. {
  421. bool changed = false;
  422. switch (item.Type)
  423. {
  424. case "Bool":
  425. bool boolValue;
  426. if (bool.TryParse(value, out boolValue) && boolValue != item.BoolValue)
  427. {
  428. item.BoolValue = boolValue;
  429. changed = true;
  430. }
  431. break;
  432. case "Integer":
  433. int intValue;
  434. if (int.TryParse(value, out intValue) && intValue != item.IntValue)
  435. {
  436. int.TryParse(item.Min, out int min);
  437. int.TryParse(item.Max, out int max);
  438. if (intValue < min || intValue > max)
  439. {
  440. EV.PostWarningLog(ModuleNameString.System, $"SC {item.PathName} value {intValue} out of setting range ({item.Min}, {item.Max})");
  441. break;
  442. }
  443. item.IntValue = intValue;
  444. changed = true;
  445. }
  446. break;
  447. case "Double":
  448. double doubleValue;
  449. if (double.TryParse(value, out doubleValue) && Math.Abs(doubleValue - item.DoubleValue) > 0.0001)
  450. {
  451. double.TryParse(item.Min, out double min);
  452. double.TryParse(item.Max, out double max);
  453. if (doubleValue < min || doubleValue > max)
  454. {
  455. EV.PostWarningLog(ModuleNameString.System, $"SC {item.PathName} value {doubleValue} out of setting range ({item.Min}, {item.Max})");
  456. break;
  457. }
  458. item.DoubleValue = doubleValue;
  459. changed = true;
  460. }
  461. break;
  462. case "String":
  463. if (value != item.StringValue)
  464. {
  465. item.StringValue = value;
  466. changed = true;
  467. }
  468. break;
  469. }
  470. return changed;
  471. }
  472. public void SetItemValue(string name, object value)
  473. {
  474. Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name);
  475. if (!_items.ContainsKey(name))
  476. {
  477. return;
  478. }
  479. bool changed = false;
  480. switch (_items[name].Type)
  481. {
  482. case "Bool":
  483. bool boolValue = (bool)value;
  484. if (boolValue != _items[name].BoolValue)
  485. {
  486. _items[name].BoolValue = boolValue;
  487. changed = true;
  488. }
  489. break;
  490. case "Integer":
  491. int intValue = (int)value;
  492. if (intValue != _items[name].IntValue)
  493. {
  494. _items[name].IntValue = intValue;
  495. changed = true;
  496. }
  497. break;
  498. case "Double":
  499. double doubleValue = (double)value;
  500. if (Math.Abs(doubleValue - _items[name].DoubleValue) > 0.0001)
  501. {
  502. _items[name].DoubleValue = doubleValue;
  503. changed = true;
  504. }
  505. break;
  506. case "String":
  507. string stringValue = (string)value;
  508. if (stringValue != _items[name].StringValue)
  509. {
  510. _items[name].StringValue = stringValue;
  511. changed = true;
  512. }
  513. break;
  514. }
  515. if (changed)
  516. {
  517. GenerateDataFile();
  518. }
  519. }
  520. public void SetItemValueStringFormat(string name, string value)
  521. {
  522. Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name);
  523. if (!_items.ContainsKey(name))
  524. {
  525. return;
  526. }
  527. bool changed = false;
  528. switch (_items[name].Type)
  529. {
  530. case "Bool":
  531. bool boolValue = Convert.ToBoolean(value);
  532. if (boolValue != _items[name].BoolValue)
  533. {
  534. _items[name].BoolValue = boolValue;
  535. changed = true;
  536. }
  537. break;
  538. case "Integer":
  539. int intValue = Convert.ToInt32(value);
  540. if (intValue != _items[name].IntValue)
  541. {
  542. _items[name].IntValue = intValue;
  543. changed = true;
  544. }
  545. break;
  546. case "Double":
  547. double doubleValue = Convert.ToDouble(value);
  548. if (Math.Abs(doubleValue - _items[name].DoubleValue) > 0.0001)
  549. {
  550. _items[name].DoubleValue = doubleValue;
  551. changed = true;
  552. }
  553. break;
  554. case "String":
  555. string stringValue = (string)value;
  556. if (stringValue != _items[name].StringValue)
  557. {
  558. _items[name].StringValue = stringValue;
  559. changed = true;
  560. }
  561. break;
  562. }
  563. if (changed)
  564. {
  565. GenerateDataFile();
  566. }
  567. }
  568. public void SetItemValue(string name, bool value)
  569. {
  570. Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name);
  571. Debug.Assert(_items[name].Type == "Bool", "sc type not bool, defined as" + _items[name].Type);
  572. if (value != _items[name].BoolValue)
  573. {
  574. _items[name].BoolValue = value;
  575. GenerateDataFile();
  576. }
  577. }
  578. public void SetItemValue(string name, int value)
  579. {
  580. Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name);
  581. Debug.Assert(_items[name].Type == "Integer", "sc type not bool, defined as" + _items[name].Type);
  582. if (value != _items[name].IntValue)
  583. {
  584. _items[name].IntValue = value;
  585. GenerateDataFile();
  586. }
  587. }
  588. public void SetItemValue(string name, double value)
  589. {
  590. Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name);
  591. Debug.Assert(_items[name].Type == "Double", "sc type not bool, defined as" + _items[name].Type);
  592. if (Math.Abs(value - _items[name].DoubleValue) > 0.0001)
  593. {
  594. _items[name].DoubleValue = value;
  595. GenerateDataFile();
  596. }
  597. }
  598. public void SetItemValue(string name, string value)
  599. {
  600. Debug.Assert(_items.ContainsKey(name), "can not find sc name, " + name);
  601. if (value != _items[name].StringValue)
  602. {
  603. _items[name].StringValue = value;
  604. GenerateDataFile();
  605. }
  606. }
  607. }
  608. }