PrewetHomePageViewModel.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Data;
  7. using System.Windows.Input;
  8. using System.Windows.Threading;
  9. using MECF.Framework.Common.OperationCenter;
  10. using Prism.Mvvm;
  11. using Prism.Commands;
  12. using Aitex.Core.RT.DataCenter;
  13. using MECF.Framework.Common.CommonData.PUF;
  14. using MECF.Framework.Common.DataCenter;
  15. using MECF.Framework.Common.Utilities;
  16. using MECF.Framework.Common.RecipeCenter;
  17. using System.Collections.ObjectModel;
  18. using CyberX8_MainPages.PMs;
  19. using Aitex.Core.Utilities;
  20. using CyberX8_Core;
  21. using System.Windows.Documents;
  22. using System.Windows;
  23. using MECF.Framework.Common.WaferHolder;
  24. using MECF.Framework.Common.CommonData.Prewet;
  25. using MECF.Framework.Common.Persistent.Prewet;
  26. using MECF.Framework.Common.Device.LinMot;
  27. using Aitex.Core.RT.RecipeCenter;
  28. using MECF.Framework.Common.Device.ResistivityProbe;
  29. using MECF.Framework.Common.Equipment;
  30. namespace CyberX8_MainPages.ViewModels
  31. {
  32. internal class PrewetHomePageViewModel : BindableBase
  33. {
  34. #region 常量
  35. private const string PUMP_DATA = "PumpData";
  36. private const string PWT = "pwt";
  37. private const string PERSISTENT_VALUE = "PersistentValue";
  38. #endregion
  39. #region 内部变量
  40. #region Common
  41. /// <summary>
  42. /// 模块名称
  43. /// </summary>
  44. private string _module;
  45. /// <summary>
  46. /// StateMachine
  47. /// </summary>
  48. private string _stateMachine;
  49. /// <summary>
  50. /// Status
  51. /// </summary>
  52. private string _status;
  53. /// <summary>
  54. /// 数据
  55. /// </summary>
  56. private PrewetPumpData _prewetPumpData;
  57. /// <summary>
  58. /// Threshold
  59. /// </summary>
  60. private PrewetPersistentValue _prewetPersistent;
  61. /// <summary>
  62. /// KepWetLimitTime
  63. /// </summary>
  64. private int _keepWetLimitTime;
  65. /// <summary>
  66. /// 当前选择Recipe节点
  67. /// </summary>
  68. private RecipeNode _selectedRecipeNode;
  69. /// <summary>
  70. /// 选中的Recipe文件的Linmot扫描次数
  71. /// </summary>
  72. private int _numberOfRecipeScans;
  73. /// <summary>
  74. /// Linmot RunRecipeTotalScanComplete
  75. /// </summary>
  76. private int _scanComplete;
  77. /// <summary>
  78. /// 是否是Manual模式
  79. /// </summary>
  80. private bool _isManualOperationMode;
  81. #endregion
  82. #region Motion
  83. /// <summary>
  84. /// 当前位置
  85. /// </summary>
  86. private double _linmotCurrentPosition;
  87. /// <summary>
  88. /// Linmot ScanCount
  89. /// </summary>
  90. private int _scanCount;
  91. /// <summary>
  92. /// Linmot StatusWord
  93. /// </summary>
  94. private short _statusWord;
  95. /// <summary>
  96. /// UpMaxSpeed
  97. /// </summary>
  98. private double _upMaxSpeed;
  99. /// <summary>
  100. /// LinmotDeviceData
  101. /// </summary>
  102. private LinMotDeviceData _linMotDeviceData;
  103. /// <summary>
  104. /// LinmotName
  105. /// </summary>
  106. private string _linmotName;
  107. #endregion
  108. #region UI
  109. /// <summary>
  110. /// Linmot UI Y轴位置
  111. /// </summary>
  112. private double _uiLinmotYPosition = 60.0;
  113. /// <summary>
  114. /// IsErrorState 用于腔体变红
  115. /// </summary>
  116. private bool _isErrorState;
  117. /// <summary>
  118. /// 页面功能启用
  119. /// </summary>
  120. private bool _isEnabled;
  121. /// <summary>
  122. /// AutoMode页面功能启用
  123. /// </summary>
  124. private bool _isAutoEnabled;
  125. /// <summary>
  126. /// 是否存在WaferHolder
  127. /// </summary>
  128. private bool _isWaferHolder;
  129. #endregion
  130. #region Wafer Holder
  131. /// <summary>
  132. /// Wafer Holder属性
  133. /// </summary>
  134. private WaferHolderInfo _waferHolderInfo;
  135. /// <summary>
  136. /// SeqRecipe
  137. /// </summary>
  138. private string _seqRecipe;
  139. #endregion
  140. #region 系统数据
  141. /// <summary>
  142. /// 定时器
  143. /// </summary>
  144. DispatcherTimer _timer;
  145. /// <summary>
  146. /// 查询后台数据集合
  147. /// </summary>
  148. private List<string> _rtDataKeys = new List<string>();
  149. /// <summary>
  150. /// rt查询key数值字典
  151. /// </summary>
  152. private Dictionary<string, object> _rtDataValueDic = new Dictionary<string, object>();
  153. #endregion
  154. #region PreWet1
  155. /// <summary>
  156. /// RecipeContent
  157. /// </summary>
  158. private string _recipeContent;
  159. /// <summary>
  160. /// TimeRemaining
  161. /// </summary>
  162. private int _timeRemaining;
  163. /// <summary>
  164. /// OfTotalTime
  165. /// </summary>
  166. private int _totalTime;
  167. /// <summary>
  168. /// OperatingMode
  169. /// </summary>
  170. private string _operatingMode;
  171. /// <summary>
  172. /// State Machine
  173. /// </summary>
  174. private string _state;
  175. /// <summary>
  176. /// RecipeMode
  177. /// </summary>
  178. private string _recipeMode;
  179. #endregion
  180. #region PWT recipe
  181. /// <summary>
  182. /// RecipeModuleName
  183. /// </summary>
  184. private string _recipeModuleName;
  185. /// <summary>
  186. /// RecipeType
  187. /// </summary>
  188. private string _recipeType;
  189. /// <summary>
  190. /// AchievedRunRecipeCycle
  191. /// </summary>
  192. private int _achievedRunRecipeCycle;
  193. /// <summary>
  194. /// 当前Recipe
  195. /// </summary>
  196. private string _currentRecipe;
  197. #endregion
  198. #endregion
  199. #region 属性
  200. #region Common
  201. /// <summary>
  202. /// 模块名称
  203. /// </summary>
  204. public string Module { get { return _module; } set { SetProperty(ref _module, value); } }
  205. /// <summary>
  206. /// StateMachine
  207. /// </summary>
  208. public string StateMachine { get { return _stateMachine; } set { SetProperty(ref _stateMachine, value); } }
  209. /// <summary>
  210. /// Status
  211. /// </summary>
  212. public string Status { get { return _status; } set { SetProperty(ref _status, value); } }
  213. /// <summary>
  214. /// Commondata
  215. /// </summary>
  216. public PrewetPumpData PrewetPumpData
  217. {
  218. get { return _prewetPumpData; }
  219. set { SetProperty(ref _prewetPumpData, value); }
  220. }
  221. /// <summary>
  222. /// KeepWetLimitTime
  223. /// </summary>
  224. public int KeepWetLimitTime { get { return _keepWetLimitTime; } set { SetProperty(ref _keepWetLimitTime, value); } }
  225. /// <summary>
  226. /// 选中的Recipe文件的Linmot扫描次数
  227. /// </summary>
  228. public int NumberOfRecipeScans { get { return _numberOfRecipeScans; } set { SetProperty(ref _numberOfRecipeScans, value); } }
  229. /// <summary>
  230. /// Linmot RunRecipeTotalScanComplete
  231. /// </summary>
  232. public int ScanComplete { get { return _scanComplete; } set { SetProperty(ref _scanComplete, value); } }
  233. /// <summary>
  234. /// Threshold
  235. /// </summary>
  236. public PrewetPersistentValue PrewetPersistent
  237. {
  238. get { return _prewetPersistent; }
  239. set { SetProperty(ref _prewetPersistent, value); }
  240. }
  241. public RecipeNode SelectedRecipeNode
  242. {
  243. get { return _selectedRecipeNode; }
  244. set { SetProperty(ref _selectedRecipeNode, value); }
  245. }
  246. /// <summary>
  247. /// 是否是Manual模式
  248. /// </summary>
  249. public bool IsManualOperationMode { get { return _isManualOperationMode; } set { SetProperty(ref _isManualOperationMode, value); } }
  250. #endregion
  251. #region Motion
  252. /// <summary>
  253. /// 当前位置
  254. /// </summary>
  255. public double LinmotCurrentPosition { get { return _linmotCurrentPosition; } set { SetProperty(ref _linmotCurrentPosition, value); } }
  256. /// <summary>
  257. /// Linmot Scan次数
  258. /// </summary>
  259. public int ScanCount { get { return _scanCount; } set { SetProperty(ref _scanCount, value); } }
  260. /// <summary>
  261. /// Linmot StatusWord
  262. /// </summary>
  263. public short StatusWord { get { return _statusWord; } set { SetProperty(ref _statusWord, value); } }
  264. /// <summary>
  265. /// LinMotDeviceData
  266. /// </summary>
  267. public LinMotDeviceData LinmotDeviceCommonData { get { return _linMotDeviceData; } set { SetProperty(ref _linMotDeviceData, value); } }
  268. /// <summary>
  269. /// UpMaxSpeed
  270. /// </summary>
  271. public double UpMaxSpeed { get { return _upMaxSpeed; } set { SetProperty(ref _upMaxSpeed, value); } }
  272. /// <summary>
  273. /// LinmotName
  274. /// </summary>
  275. public string LinmotName { get { return _linmotName; } set { SetProperty(ref _linmotName, value); } }
  276. #endregion
  277. #region UI
  278. /// <summary>
  279. /// Linmot UI Y轴位置
  280. /// </summary>
  281. public double UILinmotYPosition { get { return _uiLinmotYPosition; } set { SetProperty(ref _uiLinmotYPosition, value); } }
  282. /// <summary>
  283. /// IsErrorState
  284. /// </summary>
  285. public bool IsErrorState { get { return _isErrorState; } set { SetProperty(ref _isErrorState, value); } }
  286. /// <summary>
  287. /// 页面功能启用
  288. /// </summary>
  289. public bool IsEnabled
  290. {
  291. get { return _isEnabled; }
  292. set { SetProperty(ref _isEnabled, value); }
  293. }
  294. /// <summary>
  295. /// AutoMode页面功能启用
  296. /// </summary>
  297. public bool IsAutoEnabled
  298. {
  299. get { return _isAutoEnabled; }
  300. set { SetProperty(ref _isAutoEnabled, value); }
  301. }
  302. /// <summary>
  303. /// 是否存在WaferHolder
  304. /// </summary>
  305. public bool IsWaferHolder { get { return _isWaferHolder; } set { SetProperty(ref _isWaferHolder, value); } }
  306. #endregion
  307. #region Prewet1
  308. /// <summary>
  309. /// RecipeContent
  310. /// </summary>
  311. public string RecipeContent
  312. {
  313. get { return _recipeContent; }
  314. set { SetProperty(ref _recipeContent, value); }
  315. }
  316. /// <summary>
  317. /// TimeRemaining
  318. /// </summary>
  319. public int TimeRemaining
  320. {
  321. get { return _timeRemaining; }
  322. set { SetProperty(ref _timeRemaining, value); }
  323. }
  324. /// <summary>
  325. /// TotalTime
  326. /// </summary>
  327. public int TotalTime
  328. {
  329. get { return _totalTime; }
  330. set { SetProperty(ref _totalTime, value); }
  331. }
  332. /// <summary>
  333. /// OperatingMode
  334. /// </summary>
  335. public string OperatingMode
  336. {
  337. get { return _operatingMode; }
  338. set { SetProperty(ref _operatingMode, value); }
  339. }
  340. /// <summary>
  341. /// State
  342. /// </summary>
  343. public string State
  344. {
  345. get { return _state; }
  346. set { SetProperty(ref _state, value); }
  347. }
  348. /// <summary>
  349. /// RecipeMode
  350. /// </summary>
  351. public string RecipeMode
  352. {
  353. get { return _recipeMode; }
  354. set { SetProperty(ref _recipeMode, value); }
  355. }
  356. #endregion
  357. #region PWT recipe
  358. /// <summary>
  359. /// RecipeModuleName
  360. /// </summary>
  361. public string RecipeModuleName
  362. {
  363. get { return _recipeModuleName; }
  364. set { SetProperty(ref _recipeModuleName, value); }
  365. }
  366. /// <summary>
  367. /// RecipeType
  368. /// </summary>
  369. public string RecipeType
  370. {
  371. get { return _recipeType; }
  372. set { SetProperty(ref _recipeType, value); }
  373. }
  374. public int AchievedRunRecipeCycle
  375. {
  376. get { return _achievedRunRecipeCycle; }
  377. set { SetProperty(ref _achievedRunRecipeCycle, value); }
  378. }
  379. /// <summary>
  380. /// 当前运行的Recipe
  381. /// </summary>
  382. public string CurrentRecipe
  383. {
  384. get { return _currentRecipe; }
  385. set { SetProperty(ref _currentRecipe, value); }
  386. }
  387. #endregion
  388. #region Wafer Holder
  389. /// <summary>
  390. /// Wafer Holder属性
  391. /// </summary>
  392. public WaferHolderInfo WaferHolderInfo { get { return _waferHolderInfo; } set { SetProperty(ref _waferHolderInfo, value); } }
  393. /// <summary>
  394. /// SeqRecipe
  395. /// </summary>
  396. public string SeqRecipe
  397. {
  398. get { return _seqRecipe; }
  399. set { SetProperty(ref _seqRecipe, value); }
  400. }
  401. #endregion
  402. #endregion
  403. #region Command指令
  404. public ICommand InitializeCommand { get; set; }
  405. #endregion
  406. /// <summary>
  407. /// 构造函数
  408. /// </summary>
  409. public PrewetHomePageViewModel()
  410. {
  411. InitializeCommand = new DelegateCommand<object>(InitializeAction);
  412. }
  413. /// <summary>
  414. /// 加载数据
  415. /// </summary>
  416. public void LoadData(string systemName)
  417. {
  418. Module = systemName;
  419. RecipeModuleName = "PWT Recipe";
  420. RecipeType = "pwt";
  421. _rtDataKeys.Clear();
  422. List<string> lst = new List<string>();
  423. lst.Add($"{Module}.LinmotName");
  424. _rtDataValueDic = QueryDataClient.Instance.Service.PollData(lst);
  425. if (_rtDataValueDic != null)
  426. {
  427. LinmotName = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.LinmotName");
  428. if (!string.IsNullOrEmpty(LinmotName))
  429. {
  430. _rtDataKeys.Add($"{LinmotName}.ScanCount");
  431. _rtDataKeys.Add($"{LinmotName}.StatusWord");
  432. _rtDataKeys.Add($"{LinmotName}.Position");
  433. _rtDataKeys.Add($"{LinmotName}.CurrentPrewetUIPostion");
  434. }
  435. }
  436. _rtDataKeys.Add($"{Module}.WaferHolder");
  437. _rtDataKeys.Add($"{Module}.SequenceRecipe");
  438. _rtDataKeys.Add($"{Module}.AchievedCycle");
  439. _rtDataKeys.Add($"{Module}.GetKeepWetLimit");
  440. _rtDataKeys.Add($"{Module}.{PERSISTENT_VALUE}");
  441. _rtDataKeys.Add($"{Module}.{PUMP_DATA}");
  442. _rtDataKeys.Add($"{Module}.FsmState");
  443. _rtDataKeys.Add($"{Module}.TotalTime");
  444. _rtDataKeys.Add($"{Module}.TimeRemain");
  445. _rtDataKeys.Add($"{Module}.LinmotDeviceData");
  446. _rtDataKeys.Add($"{Module}.CurrentStateMachine");
  447. _rtDataKeys.Add($"{Module}.CurrentStatus");
  448. _rtDataKeys.Add($"{Module}.CurrentRecipe");
  449. if (_timer == null)
  450. {
  451. _timer = new DispatcherTimer();
  452. _timer.Interval = TimeSpan.FromMilliseconds(200);
  453. _timer.Tick += Timer_Tick;
  454. }
  455. _timer.Start();
  456. }
  457. /// <summary>
  458. /// 定时器执行
  459. /// </summary>
  460. /// <param name="sender"></param>
  461. /// <param name="e"></param>
  462. private void Timer_Tick(object sender, EventArgs e)
  463. {
  464. if (_rtDataKeys.Count != 0)
  465. {
  466. _rtDataValueDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys);
  467. if (_rtDataValueDic != null)
  468. {
  469. PrewetPumpData = CommonFunction.GetValue<PrewetPumpData>(_rtDataValueDic, $"{Module}.{PUMP_DATA}");
  470. WaferHolderInfo = CommonFunction.GetValue<WaferHolderInfo>(_rtDataValueDic, $"{Module}.WaferHolder");
  471. if(WaferHolderInfo != null)
  472. {
  473. IsWaferHolder = true;
  474. }
  475. else
  476. {
  477. IsWaferHolder = false;
  478. }
  479. SeqRecipe = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.SequenceRecipe");
  480. AchievedRunRecipeCycle = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.AchievedCycle");
  481. //获取的是配置文件中keepwet开始的等待时间,后续倒计时实现在后端实现
  482. KeepWetLimitTime = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.GetKeepWetLimit");
  483. PrewetPersistent = CommonFunction.GetValue<PrewetPersistentValue>(_rtDataValueDic, $"{Module}.{PERSISTENT_VALUE}");
  484. State = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.FsmState");
  485. if ("Manual".Equals(PrewetPersistent.OperatingMode))
  486. {
  487. IsEnabled = true;
  488. IsAutoEnabled = true;
  489. }
  490. else if ("Auto".Equals(PrewetPersistent.OperatingMode))
  491. {
  492. IsAutoEnabled = true;
  493. IsEnabled = false;
  494. }
  495. else
  496. {
  497. State = "Stopped";
  498. IsEnabled = false;
  499. IsAutoEnabled = false;
  500. }
  501. StateMachine = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.CurrentStateMachine");
  502. Status = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.CurrentStatus");
  503. LinmotDeviceCommonData = CommonFunction.GetValue<LinMotDeviceData>(_rtDataValueDic, $"{Module}.LinmotDeviceData");
  504. UpMaxSpeed = LinmotDeviceCommonData.UpMaxSpeed / 1000;
  505. if(!string.IsNullOrEmpty(LinmotName))
  506. {
  507. ScanCount = CommonFunction.GetValue<int>(_rtDataValueDic, $"{LinmotName}.ScanCount");
  508. StatusWord = CommonFunction.GetValue<short>(_rtDataValueDic, $"{LinmotName}.StatusWord");
  509. LinmotCurrentPosition = CommonFunction.GetValue<double>(_rtDataValueDic, $"{LinmotName}.Position");
  510. UILinmotYPosition = CommonFunction.GetValue<double>(_rtDataValueDic, $"{LinmotName}.CurrentPrewetUIPostion");
  511. }
  512. //Error时UI腔体变红
  513. IsErrorState = "Error".Equals(State) ? true : false;
  514. //Recipe Running时Linmot完成完整Scan的计数
  515. ScanComplete = AchievedRunRecipeCycle * NumberOfRecipeScans + ScanCount;
  516. if ((StatusWord & 0b010000000000000) >> 13 != 1)
  517. {
  518. ScanComplete -= ScanCount;
  519. }
  520. CurrentRecipe = CommonFunction.GetValue<string>(_rtDataValueDic, $"{Module}.CurrentRecipe");
  521. TotalTime = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.TotalTime");
  522. TimeRemaining = CommonFunction.GetValue<int>(_rtDataValueDic, $"{Module}.TimeRemain");
  523. TimeRemaining = TimeRemaining < 0 ? 0 : TimeRemaining;
  524. if (State == "Idle")
  525. {
  526. TimeRemaining = 0;
  527. }
  528. }
  529. }
  530. }
  531. /// <summary>
  532. /// 隐藏
  533. /// </summary>
  534. public void Hide()
  535. {
  536. if (_timer != null)
  537. {
  538. _timer.Stop();
  539. }
  540. }
  541. #region 指令Action
  542. /// <summary>
  543. /// Initialize Action
  544. /// </summary>
  545. /// <param name="param"></param>
  546. private void InitializeAction(object param)
  547. {
  548. InvokeClient.Instance.Service.DoOperation($"{Module}.InitializeAll");
  549. }
  550. #endregion
  551. }
  552. }