PMCounterViewModel.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. using Aitex.Core.UI.MVVM;
  2. using CyberX8_Core;
  3. using MECF.Framework.Common.CommonData.Reservoir;
  4. using MECF.Framework.Common.DataCenter;
  5. using MECF.Framework.Common.OperationCenter;
  6. using MECF.Framework.Common.Persistent.Reservoirs;
  7. using MECF.Framework.Common.ProcessCell;
  8. using MECF.Framework.Common.RecipeCenter;
  9. using MECF.Framework.Common.ToolLayout;
  10. using MECF.Framework.Common.Utilities;
  11. using Prism.Mvvm;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Collections.ObjectModel;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using System.Windows;
  19. using System.Windows.Input;
  20. using System.Windows.Threading;
  21. namespace CyberX8_MainPages.ViewModels
  22. {
  23. public class PMCounterViewModel : BindableBase
  24. {
  25. #region 常量
  26. private const string RESERVOIRS_DATA = "ReservoirsData";
  27. private const string PERSISTENT_VALUE = "PersistentValue";
  28. #endregion
  29. #region 内部变量
  30. private string _module;
  31. private string _recipeContent;
  32. private string _state;
  33. private List<string> _rtDataKeys = new List<string>();
  34. DispatcherTimer _timer;
  35. private Dictionary<string, object> _rtDataValueDic = new Dictionary<string, object>();
  36. private ObservableCollection<RecipeNode> _recipeNodes;
  37. private string _currentRecipeFileName;
  38. private string _recipeType;
  39. private ResRecipe _currentRecipe;
  40. /// <summary>
  41. /// Persistent
  42. /// </summary>
  43. private ReservoirsPersistentValue _reservoirsPersistent;
  44. /// <summary>
  45. /// Reservoir数据
  46. /// </summary>
  47. private CompactMembranReservoirData _reservoirData;
  48. /// <summary>
  49. /// CellModuleName集合
  50. /// </summary>
  51. private ObservableCollection<string> _cellModuleNameCollection = new ObservableCollection<string>();
  52. /// <summary>
  53. /// PM Counter元素集合
  54. /// </summary>
  55. private ObservableCollection<PMCounterNode> _componentNodes = new ObservableCollection<PMCounterNode>();
  56. /// <summary>
  57. /// Reservoir在PM counter页面的数据项
  58. /// </summary>
  59. private PMCounterNode _reservoirPMCounterNode = new PMCounterNode();
  60. /// <summary>
  61. /// 页面功能启用
  62. /// </summary>
  63. private bool _isEnabled;
  64. /// <summary>
  65. /// AutoMode页面功能启用
  66. /// </summary>
  67. private bool _isAutoEnabled;
  68. #endregion
  69. #region 属性
  70. public string CurrentRecipeFileName
  71. {
  72. get { return _currentRecipeFileName; }
  73. set { SetProperty(ref _currentRecipeFileName, value); }
  74. }
  75. public ObservableCollection<RecipeNode> RecipeNodes
  76. {
  77. get { return _recipeNodes; }
  78. set { SetProperty(ref _recipeNodes, value); }
  79. }
  80. public string Module { get { return _module; } set { SetProperty(ref _module, value); } }
  81. public string ReservoirRecipeContent
  82. {
  83. get { return _recipeContent; }
  84. set { SetProperty(ref _recipeContent, value); }
  85. }
  86. public string State
  87. {
  88. get { return _state; }
  89. set { SetProperty(ref _state, value); }
  90. }
  91. public ResRecipe CurrentRecipe
  92. {
  93. get { return _currentRecipe; }
  94. set { SetProperty(ref _currentRecipe, value); }
  95. }
  96. public string RecipeType
  97. {
  98. get { return _recipeType; }
  99. set { SetProperty(ref _recipeType, value); }
  100. }
  101. /// <summary>
  102. /// Threshold
  103. /// </summary>
  104. public ReservoirsPersistentValue ReservoirsPersistent
  105. {
  106. get { return _reservoirsPersistent; }
  107. set { SetProperty(ref _reservoirsPersistent, value); }
  108. }
  109. /// <summary>
  110. /// CellModuleName集合
  111. /// </summary>
  112. public ObservableCollection<string> CellModuleNameCollection
  113. {
  114. get { return _cellModuleNameCollection; }
  115. set { SetProperty(ref _cellModuleNameCollection, value); }
  116. }
  117. /// <summary>
  118. /// PM Counter元素集合
  119. /// </summary>
  120. public ObservableCollection<PMCounterNode> ComponentNodes
  121. {
  122. get { return _componentNodes; }
  123. set { SetProperty(ref _componentNodes, value); }
  124. }
  125. /// <summary>
  126. /// Reservoir在PM Counter页面的数据项
  127. /// </summary>
  128. public PMCounterNode ReservoirPMCounterNode
  129. {
  130. get { return _reservoirPMCounterNode; }
  131. set { SetProperty(ref _reservoirPMCounterNode, value); }
  132. }
  133. /// <summary>
  134. /// Reservoir 数据
  135. /// </summary>
  136. public CompactMembranReservoirData ReservoirData
  137. {
  138. get { return _reservoirData; }
  139. set { SetProperty(ref _reservoirData, value); }
  140. }
  141. /// <summary>
  142. /// 页面功能启用
  143. /// </summary>
  144. public bool IsEnabled
  145. {
  146. get { return _isEnabled; }
  147. set { SetProperty(ref _isEnabled, value); }
  148. }
  149. /// <summary>
  150. /// AutoMode页面功能启用
  151. /// </summary>
  152. public bool IsAutoEnabled
  153. {
  154. get { return _isAutoEnabled; }
  155. set { SetProperty(ref _isAutoEnabled, value); }
  156. }
  157. #endregion
  158. #region 命令
  159. public ICommand BackCommand { get; set; }
  160. public ICommand KeyDownCommand { get; set; }
  161. #endregion
  162. /// <summary>
  163. /// 构造器
  164. /// </summary>
  165. public PMCounterViewModel()
  166. {
  167. BackCommand = new DelegateCommand<object>(BackAction);
  168. KeyDownCommand = new DelegateCommand<object>(KeyDownAction);
  169. }
  170. public void LoadData(string systemName)
  171. {
  172. Module = systemName;
  173. ReservoirPMCounterNode.Name = systemName;
  174. ReservoirPMCounterNode.Children = new ObservableCollection<PMCounterCommonData>();
  175. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = "ComponentName", CounterName = "Counter Name", Value = "Value", FaultLimit = "FaultLimit", WarningLimit = "WarningLimit" });
  176. _rtDataKeys.Clear();
  177. _rtDataKeys.Add($"{Module}.ReservoirUsage");
  178. _rtDataKeys.Add($"{Module}.IsCMMInstalled");
  179. Dictionary<string, object> reservoirUsageDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys);
  180. if (reservoirUsageDic != null)
  181. {
  182. ReservoirUsage reservoirUsage = CommonFunction.GetValue<ReservoirUsage>(reservoirUsageDic, $"{Module}.ReservoirUsage");
  183. bool isCMMInstalled = CommonFunction.GetValue<bool>(reservoirUsageDic, $"{Module}.IsCMMInstalled");
  184. if (reservoirUsage != null)
  185. {
  186. double ReservoirTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalAmpHoursWarningLimit"));
  187. double ReservoirTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalAmpHoursFaultLimit"));
  188. double BathTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalAmpHoursWarningLimit"));
  189. double BathTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalAmpHoursFaultLimit"));
  190. double ANBathTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ANBathTotalAmpHoursWarningLimit"));
  191. double ANBathTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ANBathTotalAmpHoursFaultLimit"));
  192. int BathTotalDaysWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalDaysWarningLimit"));
  193. int BathTotalDaysFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.BathTotalDaysFaultLimit"));
  194. double MembraneTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.MembraneTotalAmpHoursWarningLimit"));
  195. double MembraneTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.MembraneTotalAmpHoursFaultLimit"));
  196. int ReservoirTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalWafersWarningLimit"));
  197. int ReservoirTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.ReservoirTotalWafersFaultLimit"));
  198. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Total Usage(AHr)", Value = $"{reservoirUsage.TotalUsage}", FaultLimit = $"{ReservoirTotalAmpHoursFaultLimit}", WarningLimit = $"{ReservoirTotalAmpHoursWarningLimit}" });
  199. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Bath Usage(AHr)", Value = $"{reservoirUsage.BathUsage}", FaultLimit = $"{BathTotalAmpHoursFaultLimit}", WarningLimit = $"{BathTotalAmpHoursWarningLimit}" });
  200. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Anolyte Bath Usage(AHr)", Value = $"{reservoirUsage.AnodeUsage}", FaultLimit = $"{ANBathTotalAmpHoursFaultLimit}", WarningLimit = $"{ANBathTotalAmpHoursWarningLimit}" });
  201. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Bath Usage(Days)", Value = $"{reservoirUsage.BathUsageDays}", FaultLimit = $"{BathTotalDaysFaultLimit}", WarningLimit = $"{BathTotalDaysWarningLimit}" });
  202. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Membrance Usage(AHr)", Value = $"{reservoirUsage.MembranceUsage}", FaultLimit = $"{MembraneTotalAmpHoursFaultLimit}", WarningLimit = $"{MembraneTotalAmpHoursWarningLimit}" });
  203. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "Total Wafers", Value = $"{reservoirUsage.TotalWafers}", FaultLimit = $"{ReservoirTotalWafersFaultLimit}", WarningLimit = $"{ReservoirTotalWafersWarningLimit}" });
  204. if (isCMMInstalled)
  205. {
  206. double CMMAnodeTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.CMM.CMMAnodeTotalAmpHoursWarningLimit"));
  207. double CMMAnodeTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.CMM.CMMAnodeTotalAmpHoursFaultLimit"));
  208. double CMMCathodeTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.CMM.CMMCathodeTotalAmpHoursWarningLimit"));
  209. double CMMCathodeTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Reservoir.CMM.CMMCathodeTotalAmpHoursFaultLimit"));
  210. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "CMM Anode Usage(AHr)", Value = $"{reservoirUsage.CMMAnodeUsage}", FaultLimit = $"{CMMAnodeTotalAmpHoursFaultLimit}", WarningLimit = $"{CMMAnodeTotalAmpHoursWarningLimit}" });
  211. ReservoirPMCounterNode.Children.Add(new PMCounterCommonData { ComponentName = $"{Module}", CounterName = "CMM Cathode Usage(AHr)", Value = $"{reservoirUsage.CMMMembranceUsage}", FaultLimit = $"{CMMCathodeTotalAmpHoursFaultLimit}", WarningLimit = $"{CMMCathodeTotalAmpHoursWarningLimit}" });
  212. }
  213. }
  214. }
  215. _rtDataKeys.Clear();
  216. _rtDataKeys.Add($"{Module}.Metals");
  217. Dictionary<string, object> tmpMetals = QueryDataClient.Instance.Service.PollData(_rtDataKeys);
  218. if (tmpMetals != null)
  219. {
  220. List<string> strMetals = CommonFunction.GetValue<List<string>>(tmpMetals, $"{Module}.Metals");
  221. int cellsCount = strMetals.Count;
  222. if (strMetals != null)
  223. {
  224. CellModuleNameCollection.Clear();
  225. ComponentNodes.Clear();
  226. for (int i = 0; i < cellsCount; i++)
  227. {
  228. CellModuleNameCollection.Add(strMetals[i]);
  229. ComponentNodes.Add(new PMCounterNode { Name = $"{strMetals[i]}", Children = new ObservableCollection<PMCounterCommonData>() });
  230. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = "ComponentName", CounterName = "Counter Name", Value = "Value", FaultLimit = "FaultLimit", WarningLimit = "WarningLimit" });
  231. _rtDataKeys.Clear();
  232. _rtDataKeys.Add($"{strMetals[i]}.MetalUsage");
  233. Dictionary<string, object> tmpMetalUsage = QueryDataClient.Instance.Service.PollData(_rtDataKeys);
  234. if(tmpMetalUsage != null)
  235. {
  236. MetalUsage metalUsage = CommonFunction.GetValue<MetalUsage>(tmpMetalUsage, $"{strMetals[i]}.MetalUsage");
  237. if (metalUsage != null)
  238. {
  239. double metalTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalAmpHoursWarningLimit"));
  240. double metalTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalAmpHoursFaultLimit"));
  241. double anodeATotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalAmpHoursWarningLimit"));
  242. double anodeATotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalAmpHoursFaultLimit"));
  243. double anodeBTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalAmpHoursWarningLimit"));
  244. double anodeBTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalAmpHoursFaultLimit"));
  245. double membraneATotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneATotalAmpHoursWarningLimit"));
  246. double membraneATotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneATotalAmpHoursFaultLimit"));
  247. double membraneBTotalAmpHoursWarningLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneBTotalAmpHoursWarningLimit"));
  248. double membraneBTotalAmpHoursFaultLimit = (double)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MembraneBTotalAmpHoursFaultLimit"));
  249. int metalTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalWafersWarningLimit"));
  250. int metalTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.MetalTotalWafersFaultLimit"));
  251. int anodeATotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalWafersWarningLimit"));
  252. int anodeATotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeATotalWafersFaultLimit"));
  253. int anodeBTotalWafersWarningLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalWafersWarningLimit"));
  254. int anodeBTotalWafersFaultLimit = (int)Convert.ToDouble(QueryDataClient.Instance.Service.GetConfig("Metal.AnodeBTotalWafersFaultLimit"));
  255. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Total Usage(AHr)", Value = $"{metalUsage.TotalUsage}", FaultLimit = $"{metalTotalAmpHoursFaultLimit}", WarningLimit = $"{metalTotalAmpHoursWarningLimit}" });
  256. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Anode A Usage(AHr)", Value = $"{metalUsage.AnodeAUsage}", FaultLimit = $"{anodeATotalAmpHoursFaultLimit}", WarningLimit = $"{anodeATotalAmpHoursWarningLimit}" });
  257. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Anode B Usage(AHr)", Value = $"{metalUsage.AnodeBUsage}", FaultLimit = $"{anodeBTotalAmpHoursFaultLimit}", WarningLimit = $"{anodeBTotalAmpHoursWarningLimit}" });
  258. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Membrane A Usage(AHr)", Value = $"{metalUsage.MembranceAUsage}", FaultLimit = $"{membraneATotalAmpHoursFaultLimit}", WarningLimit = $"{membraneATotalAmpHoursWarningLimit}" });
  259. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Membrane B Usage(AHr)", Value = $"{metalUsage.MembranceBUsage}", FaultLimit = $"{membraneBTotalAmpHoursFaultLimit}", WarningLimit = $"{membraneBTotalAmpHoursWarningLimit}" });
  260. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Metal Total Wafers", Value = $"{metalUsage.TotalWafers}", FaultLimit = $"{metalTotalWafersFaultLimit}", WarningLimit = $"{metalTotalWafersWarningLimit}" });
  261. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Anode A Total Wafers", Value = $"{metalUsage.AnodeAWafers}", FaultLimit = $"{anodeATotalWafersFaultLimit}", WarningLimit = $"{anodeATotalWafersWarningLimit}" });
  262. ComponentNodes[i].Children.Add(new PMCounterCommonData { ComponentName = $"{strMetals[i]}", CounterName = "Anode B Total Wafers", Value = $"{metalUsage.AnodeBWafers}", FaultLimit = $"{anodeBTotalWafersFaultLimit}", WarningLimit = $"{anodeBTotalWafersWarningLimit}" });
  263. }
  264. }
  265. }
  266. }
  267. ComponentNodes.Add(ReservoirPMCounterNode);
  268. }
  269. _rtDataKeys.Clear();
  270. _rtDataKeys.Add($"{Module}.{PERSISTENT_VALUE}");
  271. _rtDataKeys.Add($"{Module}.ReservoirData");
  272. _rtDataKeys.Add($"{Module}.CurrentRecipe");
  273. _rtDataKeys.Add($"{Module}.FsmState");
  274. if (_timer == null)
  275. {
  276. _timer = new DispatcherTimer();
  277. _timer.Interval = TimeSpan.FromMilliseconds(200);
  278. _timer.Tick += Timer_Tick;
  279. }
  280. _timer.Start();
  281. }
  282. private void Timer_Tick(object sender, EventArgs e)
  283. {
  284. if (_rtDataKeys.Count != 0)
  285. {
  286. _rtDataValueDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys);
  287. if (_rtDataValueDic != null)
  288. {
  289. State = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.FsmState");
  290. ReservoirData = CommonFunction.GetValue<CompactMembranReservoirData>(_rtDataValueDic, $"{Module}.ReservoirData");
  291. CurrentRecipe = CommonFunction.GetValue<ResRecipe>(_rtDataValueDic, $"{Module}.CurrentRecipe");
  292. ReservoirsPersistent = CommonFunction.GetValue<ReservoirsPersistentValue>(_rtDataValueDic, $"{Module}.{PERSISTENT_VALUE}");
  293. if ("Manual".Equals(ReservoirsPersistent.OperatingMode))
  294. {
  295. IsEnabled = true;
  296. IsAutoEnabled = true;
  297. }
  298. else if ("Auto".Equals(ReservoirsPersistent.OperatingMode))
  299. {
  300. IsAutoEnabled = true;
  301. IsEnabled = false;
  302. }
  303. else
  304. {
  305. State = "Stopped";
  306. IsEnabled = false;
  307. IsAutoEnabled = false;
  308. }
  309. }
  310. }
  311. }
  312. #region 命令方法
  313. /// <summary>
  314. /// 回到Reservoir页面
  315. /// </summary>
  316. /// <param name="param"></param>
  317. private void BackAction(object param)
  318. {
  319. GlobalEvents.OnSwitchFixedChildSubItem(Module, Module);
  320. }
  321. private void KeyDownAction(object param)
  322. {
  323. }
  324. #endregion
  325. }
  326. }