RealtimeProvider.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Data;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.RT.SCCore;
  9. using DocumentFormat.OpenXml.Drawing;
  10. using ExtendedGrid.Microsoft.Windows.Controls;
  11. using MECF.Framework.Common.DataCenter;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.Utilities;
  14. using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory;
  15. using MECF.Framework.UI.Client.ClientBase.Tree;
  16. using OpenSEMI.ClientBase.ServiceProvider;
  17. namespace MECF.Framework.UI.Client.CenterViews.Operations.RealTime
  18. {
  19. public class RealtimeProvider : IProvider
  20. {
  21. ObservableCollection<ParameterNode> _rootNode = new ObservableCollection<ParameterNode>();
  22. Dictionary<string, ParameterNode> _indexer = new Dictionary<string, ParameterNode>();
  23. public void Clear()
  24. {
  25. _indexer.Clear();
  26. _rootNode.Clear();
  27. }
  28. /// <summary>
  29. /// 使用字符串队列创建树结构的分支。
  30. /// </summary>
  31. /// <param name="branchString"></param>
  32. /// <param name="node"></param>
  33. private static TreeNode CreateTreeBranch(Queue<string> branchString, TreeNode node)
  34. {
  35. var rootNode = node;
  36. while (true)
  37. {
  38. if (branchString.Count <= 0)
  39. return rootNode;
  40. var name = branchString.Dequeue();
  41. if (node == null)
  42. {
  43. // 根节点
  44. node = new TreeNode(name);
  45. rootNode = node;
  46. }
  47. else
  48. {
  49. if (node.Name == name)
  50. continue;
  51. // 向ChildNode插入
  52. var subNode = node.ChildNodes.FirstOrDefault(x => x.Name == name);
  53. if (subNode == null)
  54. {
  55. subNode = new TreeNode(name);
  56. node.ChildNodes.Add(subNode);
  57. }
  58. node = subNode;
  59. }
  60. }
  61. }
  62. public void Create()
  63. {
  64. }
  65. public ObservableCollection<string> GetUserDefineParameters()
  66. {
  67. var typedContents = ((string)QueryDataClient.Instance.Service.GetTypedConfigContent("UserDefine", ""));
  68. ObservableCollection<string> dataList = new ObservableCollection<string>();
  69. if (typedContents != null)
  70. {
  71. var contentList = typedContents.Split(',').ToList();
  72. contentList.ForEach(x =>
  73. {
  74. if (!string.IsNullOrEmpty(x)) dataList.Add($"{x}");
  75. });
  76. }
  77. return dataList;
  78. }
  79. public Dictionary<string, string> GetSystemDeviceNameDict()
  80. {
  81. return new Dictionary<string, string>()
  82. {
  83. {ModuleName.CarrierRobot.ToString(),ModuleName.Robot.ToString() },
  84. {ModuleName.WaferRobot.ToString(),ModuleName.Robot.ToString() },
  85. {ModuleName.FIMS1.ToString(),ModuleName.FIMS1.ToString() },
  86. {ModuleName.FIMS2.ToString(),ModuleName.FIMS2.ToString() },
  87. {ModuleName.LP1.ToString(),ModuleName.LP1.ToString() },
  88. {ModuleName.LP2.ToString(),ModuleName.LP2.ToString() },
  89. {ModuleName.LP3.ToString(),ModuleName.LP3.ToString() },
  90. {ModuleName.LP4.ToString(),ModuleName.LP4.ToString() },
  91. {ModuleName.Stocker1.ToString(),ModuleName.Stocker1.ToString() },
  92. {ModuleName.Stocker2.ToString(),ModuleName.Stocker2.ToString() },
  93. {ModuleName.Stocker3.ToString(),ModuleName.Stocker3.ToString() },
  94. {ModuleName.Stocker4.ToString(),ModuleName.Stocker4.ToString() },
  95. {ModuleName.Stocker5.ToString(),ModuleName.Stocker5.ToString() },
  96. {ModuleName.Stocker6.ToString(),ModuleName.Stocker6.ToString() },
  97. {ModuleName.Stocker7.ToString(),ModuleName.Stocker7.ToString() },
  98. {ModuleName.Stocker8.ToString(),ModuleName.Stocker8.ToString() },
  99. {ModuleName.Stocker9.ToString(),ModuleName.Stocker9.ToString() },
  100. {ModuleName.Stocker10.ToString(),ModuleName.Stocker10.ToString() },
  101. {ModuleName.Stocker11.ToString(),ModuleName.Stocker11.ToString() },
  102. {ModuleName.Stocker12.ToString(),ModuleName.Stocker12.ToString() },
  103. {ModuleName.Stocker13.ToString(),ModuleName.Stocker13.ToString() },
  104. {ModuleName.Stocker14.ToString(),ModuleName.Stocker14.ToString() },
  105. {ModuleName.Stocker15.ToString(),ModuleName.Stocker15.ToString() },
  106. {ModuleName.Stocker16.ToString(),ModuleName.Stocker16.ToString() },
  107. {ModuleName.Stocker17.ToString(),ModuleName.Stocker17.ToString() },
  108. {ModuleName.Stocker18.ToString(),ModuleName.Stocker18.ToString() },
  109. };
  110. }
  111. /// <summary>
  112. /// 筛选数据库字段
  113. /// </summary>
  114. /// <param name="dataList"></param>
  115. /// <returns></returns>
  116. private Dictionary<string, string> FilterNumericDataList(List<string> dataList, Dictionary<string, string> displayXmlDict)
  117. {
  118. //这里包含了项目中注册到数据库中的所有字段,需要从中筛选出来有效字段并归类
  119. Dictionary<string, string> result = new Dictionary<string, string>();
  120. var effectiveDataList = dataList.Where(a => a.Split('.').Count() > 1);
  121. var pm1DataList = effectiveDataList.Where(a => a.StartsWith(ModuleName.PM1.ToString()) && !displayXmlDict.Keys.Contains(a)).ToDictionary(a => a, a => a);
  122. var systemDataList = effectiveDataList.Where(a => a.StartsWith(ModuleName.System.ToString()) && !displayXmlDict.Keys.Contains(a)).ToDictionary(a => a, a => a);
  123. result.AddRange(pm1DataList);
  124. result.AddRange(systemDataList);
  125. var systemDeviceNameDict = GetSystemDeviceNameDict();
  126. foreach (var item in systemDeviceNameDict)
  127. {
  128. var data = effectiveDataList.Where(a => (a.StartsWith(item.Key))).ToDictionary(a => a, a => $"{item.Value}.{a}");
  129. result.AddRange(data);
  130. }
  131. return result;
  132. }
  133. /// <summary>
  134. /// 获取指定日期数据库PM/System table 列
  135. /// </summary>
  136. /// <param name="dbTableName"></param>
  137. /// <returns></returns>
  138. public List<string> GetDBCol(string dbTableName)
  139. {
  140. var columnsql = $"select column_name from information_schema.columns where table_name = '{dbTableName}'";
  141. var columnTable = QueryDataClient.Instance.Service.QueryData(columnsql);
  142. return columnTable.Rows.Cast<DataRow>().Select(x => x.ItemArray[0].ToString()).ToList();
  143. }
  144. /// <summary>
  145. /// 获取DataHistory 左侧树字典(既包含配置文件字段,也包含PM/System表字段)
  146. /// </summary>
  147. /// <returns></returns>
  148. public Dictionary<string, string> GetTreeNameDict()
  149. {
  150. Dictionary<string, string> displayDic = QueryDataClient.Instance.Service.GetData("System.Display") as Dictionary<string, string>;
  151. List<string> dataList = (List<string>)QueryDataClient.Instance.Service.GetConfig("System.NumericDataList");
  152. var dataListDict = FilterNumericDataList(dataList, displayDic);
  153. displayDic.AddRange(dataListDict);
  154. return displayDic;
  155. }
  156. /// <summary>
  157. /// 获取ProcessHistory 左侧树结构(不包含PM/System,只根据配置文件字段生成)
  158. /// </summary>
  159. /// <param name="processDetailDisplayDic"></param>
  160. /// <param name="isSelected"></param>
  161. /// <returns></returns>
  162. public ObservableCollection<ParameterNode> GetParameters(out Dictionary<string, string> processDetailDisplayDic, bool isSelected = false)
  163. {
  164. processDetailDisplayDic = new Dictionary<string, string>();
  165. ObservableCollection<ParameterNode> rootNode = new ObservableCollection<ParameterNode>();
  166. try
  167. {
  168. Dictionary<string, string> displayDic = QueryDataClient.Instance.Service.GetData("System.ProcessDetailDisplay") as Dictionary<string, string>;
  169. if (displayDic == null)
  170. return rootNode;
  171. List<string> dataList = new List<string>();
  172. foreach (var itemDisplay in displayDic)
  173. {
  174. string[] keyItems = itemDisplay.Key.Split('.');
  175. string[] valueItems = itemDisplay.Value.Split('.');
  176. if (keyItems != null)
  177. {
  178. if (keyItems.Length == 2)
  179. {
  180. var key = $"{valueItems[1]}";
  181. var keyValue = itemDisplay.Value;
  182. if (!processDetailDisplayDic.ContainsKey(key))
  183. {
  184. processDetailDisplayDic.Add(key, keyValue);
  185. }
  186. }
  187. else if (keyItems.Length == 3)
  188. {
  189. var key = $"{valueItems[1]} {valueItems[2]}";
  190. var keyValue = itemDisplay.Value;
  191. if (!processDetailDisplayDic.ContainsKey(key))
  192. {
  193. processDetailDisplayDic.Add(key, keyValue);
  194. }
  195. }
  196. dataList.Add(itemDisplay.Value);
  197. }
  198. }
  199. Dictionary<string, ParameterNode> indexer = new Dictionary<string, ParameterNode>();
  200. foreach (string dataName in dataList)
  201. {
  202. string[] nodeName = dataName.Split('.');
  203. ParameterNode parentNode = null;
  204. string pathName = "";
  205. for (int i = 0; i < nodeName.Length; i++)
  206. {
  207. pathName = (i == 0 || i == 1) ? nodeName[i] : (pathName + " " + nodeName[i]);
  208. if (!indexer.ContainsKey(pathName))
  209. {
  210. indexer[pathName] = new ParameterNode() { Name = pathName, ChildNodes = new ObservableCollection<ParameterNode>(), ParentNode = parentNode };
  211. if (parentNode == null)
  212. {
  213. rootNode.Add(indexer[pathName]);
  214. }
  215. else
  216. {
  217. parentNode.ChildNodes.Add(indexer[pathName]);
  218. }
  219. }
  220. parentNode = indexer[pathName];
  221. }
  222. }
  223. SortParameterNode(rootNode,
  224. new Dictionary<string, int>() {
  225. { "Heater",0},
  226. { "MFC",1},
  227. { "APC",2},
  228. { "Boat",3},
  229. { "Valve",4} },
  230. isSelected);
  231. }
  232. catch (Exception ex)
  233. {
  234. LOG.Write(ex);
  235. }
  236. return rootNode;
  237. }
  238. public List<TreeNode> GetTreeNodeParameters()
  239. {
  240. var root = new List<TreeNode>();
  241. try
  242. {
  243. Dictionary<string, string> displayDic = QueryDataClient.Instance.Service.GetData("System.Display") as Dictionary<string, string>;
  244. List<string> dataList = (List<string>)QueryDataClient.Instance.Service.GetConfig("System.NumericDataList");
  245. List<SCConfigItem> setUplist = null;
  246. if (QueryDataClient.Instance.Service.GetConfigItemList().Where(x => x.Path == "System.SetUp") != null)
  247. setUplist = QueryDataClient.Instance.Service.GetConfigItemList()
  248. .Where(x => x.Path == "System.SetUp").ToList();
  249. var typedContents = ((string)QueryDataClient.Instance.Service.GetTypedConfigContent("UserDefine", ""));
  250. if (string.IsNullOrEmpty(typedContents))
  251. {
  252. dataList.Add($"UserDefine");
  253. }
  254. else
  255. {
  256. var contentList = typedContents.Split(',').ToList();
  257. contentList.ForEach(x =>
  258. {
  259. if (!string.IsNullOrEmpty(x)) dataList.Add($"UserDefine.{x}");
  260. });
  261. }
  262. dataList.Sort();
  263. foreach (var dataName in dataList)
  264. {
  265. var nodeName = new Queue<string>(dataName.Split('.'));
  266. if (nodeName.Count <= 0)
  267. continue;
  268. // 开始创建Tree分支
  269. var rootNode = root.FirstOrDefault(x => x.Name == nodeName.Peek());
  270. var node = CreateTreeBranch(nodeName, rootNode);
  271. if (rootNode == null)
  272. {
  273. root.Add(node);
  274. }
  275. }
  276. root.Sort(new NameComparer());
  277. if (displayDic != null)
  278. {
  279. foreach (TreeNode rootNodes in root)
  280. {
  281. foreach (var terminalNode in rootNodes.Flatten(true))
  282. {
  283. terminalNode.DisplayName = displayDic.ContainsKey($"{rootNodes.Name}.{terminalNode.FullName}") ? displayDic[$"{rootNodes.Name}.{terminalNode.FullName}"] : terminalNode.FullName;
  284. }
  285. }
  286. }
  287. foreach (var rootNodes in root)
  288. {
  289. var childNode = rootNodes.ChildNodes.ToList();
  290. childNode.Sort(new NameComparer());
  291. for (int i = 0; i < childNode.Count; i++)
  292. {
  293. rootNodes.ChildNodes.Move(rootNodes.ChildNodes.IndexOf(childNode[i]), i);
  294. }
  295. }
  296. }
  297. catch (Exception ex)
  298. {
  299. LOG.Write(ex);
  300. }
  301. return root;
  302. }
  303. /// <summary>
  304. /// 获取DataHistory 左侧树结构(既包含配置文件字段,也包含PM/System表字段)
  305. /// </summary>
  306. /// <returns></returns>
  307. public List<TreeNode> GetTreeNodeParameters1()
  308. {
  309. var root = new List<TreeNode>();
  310. try
  311. {
  312. var displayDic = GetTreeNameDict();
  313. foreach (var dataName in displayDic.Values)
  314. {
  315. var nodeName = new Queue<string>(dataName.Split('.'));
  316. if (nodeName.Count <= 0)
  317. continue;
  318. // 开始创建Tree分支
  319. var rootNode = root.FirstOrDefault(x => x.Name == nodeName.Peek());
  320. var node = CreateTreeBranch(nodeName, rootNode);
  321. if (rootNode == null)
  322. {
  323. root.Add(node);
  324. }
  325. }
  326. SortParameterNode(root, "PM1", 0);
  327. SortParameterNode(root, "System", 1);
  328. SortParameterNode(root, "Heater", 2);
  329. SortParameterNode(root, "MFC", 3);
  330. SortParameterNode(root, "APC", 4);
  331. SortParameterNode(root, "Boat", 5);
  332. SortParameterNode(root, "Valve", 6);
  333. }
  334. catch (Exception ex)
  335. {
  336. LOG.Write(ex);
  337. }
  338. return root;
  339. }
  340. #region Sort 排序
  341. void SortParameterNode(List<TreeNode> rootNode, string Name, int Index)
  342. {
  343. if (Index >= rootNode.Count)
  344. {
  345. return;
  346. }
  347. if (rootNode[Index].Name != Name)
  348. {
  349. for (int i = 0; i < rootNode.Count; i++)
  350. {
  351. if (rootNode[i].Name == Name)
  352. {
  353. TreeNode node = rootNode[i];
  354. rootNode.RemoveAt(i);
  355. rootNode.Insert(Index, node);
  356. }
  357. }
  358. }
  359. }
  360. void SortParameterNode(ObservableCollection<ParameterNode> rootNode, Dictionary<string, int> sortDict, bool isSelectd = false)
  361. {
  362. foreach (var item in sortDict)
  363. {
  364. SortParameterNode(rootNode, item.Key, item.Value, isSelectd);
  365. }
  366. }
  367. void SortParameterNode(ObservableCollection<ParameterNode> rootNode, string Name, int Index, bool isSelectd = false)
  368. {
  369. if (Index >= rootNode.Count)
  370. {
  371. return;
  372. }
  373. if (rootNode[Index].Name != Name)
  374. {
  375. for (int i = 0; i < rootNode.Count; i++)
  376. {
  377. rootNode[i].Selected = isSelectd;
  378. if (rootNode[i].Name == Name)
  379. {
  380. ParameterNode node = rootNode[i];
  381. rootNode.RemoveAt(i);
  382. rootNode.Insert(Index, node);
  383. }
  384. }
  385. }
  386. }
  387. #endregion
  388. public ObservableCollection<ParameterNode> GetParameterNodeParameters()
  389. {
  390. try
  391. {
  392. List<string> dataList =
  393. (List<string>)QueryDataClient.Instance.Service.GetConfig("System.NumericDataList");
  394. var typedContents = ((string)QueryDataClient.Instance.Service.GetTypedConfigContent("UserDefine", ""));
  395. for (int i = 0; i < dataList.Count; i++)
  396. {
  397. if (dataList[i].StartsWith("SMIF"))
  398. dataList[i] = $"SMIFs.{dataList[i]}";
  399. if (dataList[i].StartsWith("Stocker"))
  400. dataList[i] = $"Stockers.{dataList[i]}";
  401. if (dataList[i].StartsWith("Stage"))
  402. dataList[i] = $"Stages.{dataList[i]}";
  403. dataList[i] = dataList[i].Replace("PM1", "Tube");
  404. }
  405. if (string.IsNullOrEmpty(typedContents))
  406. {
  407. dataList.Add($"UserDefine");
  408. }
  409. else
  410. {
  411. var contentList = typedContents.Split(',').ToList();
  412. contentList.ForEach(x =>
  413. {
  414. if (!string.IsNullOrEmpty(x)) dataList.Add($"UserDefine.{x}");
  415. });
  416. }
  417. dataList.Sort();
  418. //List<string> removeList = _indexer.Keys.ToList();
  419. foreach (string dataName in dataList)
  420. {
  421. string[] nodeName = dataName.Split('.');
  422. ParameterNode parentNode = null;
  423. string pathName = "";
  424. for (int i = 0; i < nodeName.Length; i++)
  425. {
  426. pathName = (i == 0) ? nodeName[i] : (pathName + "." + nodeName[i]);
  427. //removeList.Remove(pathName);
  428. if (!_indexer.ContainsKey(pathName))
  429. {
  430. _indexer[pathName] = new ParameterNode()
  431. {
  432. Name = pathName.Replace("UserDefine.", "").Replace("SMIFs.", "").Replace("Stages.", "")
  433. .Replace("Stockers.", ""),
  434. ChildNodes = new ObservableCollection<ParameterNode>(),
  435. ParentNode = parentNode
  436. };
  437. if (parentNode == null)
  438. {
  439. _rootNode.Add(_indexer[pathName]);
  440. }
  441. else
  442. {
  443. parentNode.ChildNodes.Add(_indexer[pathName]);
  444. }
  445. }
  446. parentNode = _indexer[pathName];
  447. //removeList.Remove(pathName);
  448. }
  449. }
  450. //foreach (var key in removeList)
  451. //{
  452. // if (_indexer[key].ParentNode == null)
  453. // _rootNode.Remove(_indexer[key]);
  454. // else
  455. // {
  456. // _indexer[key].ParentNode.ChildNodes.Remove(_indexer[key]);
  457. // }
  458. //}
  459. return _rootNode;
  460. }
  461. catch (Exception ex)
  462. {
  463. LOG.Write(ex);
  464. }
  465. #region Test code
  466. ObservableCollection<ParameterNode> result = new ObservableCollection<ParameterNode>();
  467. ParameterNode node1 = new ParameterNode() { Name = "Para Node 1", Selected = false, ChildNodes = new ObservableCollection<ParameterNode>() };
  468. ParameterNode node2 = new ParameterNode() { Name = "Para Node 2", Selected = false, ChildNodes = new ObservableCollection<ParameterNode>() };
  469. ParameterNode node3 = new ParameterNode() { Name = "Para Node 3", Selected = false, ChildNodes = new ObservableCollection<ParameterNode>() };
  470. for (int i = 0; i < 5; i++)
  471. {
  472. ParameterNode node = new ParameterNode() { Name = node1.Name + "_" + i.ToString(), Selected = false, ChildNodes = new ObservableCollection<ParameterNode>() };
  473. node1.ChildNodes.Add(node);
  474. }
  475. for (int i = 0; i < 3; i++)
  476. {
  477. ParameterNode node = new ParameterNode() { Name = node2.Name + "_" + i.ToString(), Selected = false, ChildNodes = new ObservableCollection<ParameterNode>() };
  478. node2.ChildNodes.Add(node);
  479. }
  480. for (int i = 0; i < 4; i++)
  481. {
  482. ParameterNode node = new ParameterNode() { Name = node3.Name + "_" + i.ToString(), Selected = false, ChildNodes = new ObservableCollection<ParameterNode>() };
  483. node3.ChildNodes.Add(node);
  484. }
  485. result.Add(node1);
  486. result.Add(node2);
  487. result.Add(node3);
  488. return result;
  489. #endregion
  490. }
  491. }
  492. public class NameComparer : IComparer<TreeNode>
  493. {
  494. public int Compare(TreeNode x, TreeNode y)
  495. {
  496. if (x == null || y == null)
  497. throw new ArgumentException("Parameters can't be null");
  498. string fileA = x.DisplayName;
  499. string fileB = y.DisplayName;
  500. char[] arr1 = fileA.ToCharArray();
  501. char[] arr2 = fileB.ToCharArray();
  502. int i = 0, j = 0;
  503. while (i < arr1.Length && j < arr2.Length)
  504. {
  505. if (char.IsDigit(arr1[i]) && char.IsDigit(arr2[j]))
  506. {
  507. string s1 = "", s2 = "";
  508. while (i < arr1.Length && char.IsDigit(arr1[i]))
  509. {
  510. s1 += arr1[i];
  511. i++;
  512. }
  513. while (j < arr2.Length && char.IsDigit(arr2[j]))
  514. {
  515. s2 += arr2[j];
  516. j++;
  517. }
  518. if (int.Parse(s1) > int.Parse(s2))
  519. {
  520. return 1;
  521. }
  522. if (int.Parse(s1) < int.Parse(s2))
  523. {
  524. return -1;
  525. }
  526. }
  527. else
  528. {
  529. if (arr1[i] > arr2[j])
  530. {
  531. return 1;
  532. }
  533. if (arr1[i] < arr2[j])
  534. {
  535. return -1;
  536. }
  537. i++;
  538. j++;
  539. }
  540. }
  541. if (arr1.Length == arr2.Length)
  542. {
  543. return 0;
  544. }
  545. else
  546. {
  547. return arr1.Length > arr2.Length ? 1 : -1;
  548. }
  549. }
  550. }
  551. }