OverViewModel.cs 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.Util;
  3. using Aitex.Sorter.Common;
  4. using Bolt.Toolkit.Wpf.Data.Enum;
  5. using Caliburn.Micro;
  6. using MECF.Framework.Common.DataCenter;
  7. using MECF.Framework.Common.OperationCenter;
  8. using MECF.Framework.Common.RecipeCenter;
  9. using OpenSEMI.ClientBase;
  10. using System.Collections.Generic;
  11. using System.Collections.ObjectModel;
  12. using System.Windows;
  13. using System.Windows.Input;
  14. using Aitex.Core.UI.MVVM;
  15. using VirgoCommon;
  16. using VirgoUI.Client.Dialog;
  17. using VirgoUI.Client.Models.Operate.WaferAssociation;
  18. using VirgoUI.Client.Models.Platform.LoadPort;
  19. using VirgoUI.Client.Models.Recipe;
  20. using VirgoUI.Client.Models.Sys;
  21. namespace VirgoUI.Client.Models.Operate
  22. {
  23. public enum EfemType
  24. {
  25. FutureEfem = 1,
  26. JetEfem = 2,
  27. }
  28. public class OverViewModel : UiViewModelBase
  29. {
  30. #region Property
  31. //private int MenuPermission;
  32. #region PM
  33. public string PMABackground
  34. {
  35. get
  36. {
  37. if (!PMAIsOnline)
  38. return "Red";
  39. if (PMAServiceStatus == PMState.Error.ToString())
  40. return "Red";
  41. if (PMAServiceStatus == PMState.Idle.ToString()
  42. || PMAServiceStatus == PMState.Init.ToString())
  43. {
  44. return "Transparent";
  45. }
  46. return "Green";
  47. }
  48. }
  49. public string PMBBackground
  50. {
  51. get
  52. {
  53. if (!PMBIsOnline)
  54. return "Red";
  55. if (PMBServiceStatus == PMState.Error.ToString())
  56. return "Red";
  57. if (PMBServiceStatus == PMState.Idle.ToString()
  58. || PMBServiceStatus == PMState.Init.ToString())
  59. {
  60. return "Transparent";
  61. }
  62. return "Green";
  63. }
  64. }
  65. #endregion
  66. #region EFEM
  67. private WaferAssociationInfo _lp1WaferAssociation;
  68. public WaferAssociationInfo LP1WaferAssociation
  69. {
  70. get { return _lp1WaferAssociation; }
  71. set { _lp1WaferAssociation = value; }
  72. }
  73. private WaferAssociationInfo _lp2WaferAssociation;
  74. public WaferAssociationInfo LP2WaferAssociation
  75. {
  76. get { return _lp2WaferAssociation; }
  77. set { _lp2WaferAssociation = value; }
  78. }
  79. public string LP1ProcStatus
  80. {
  81. get
  82. {
  83. if (LP1WaferAssociation.JobStatus == "")
  84. {
  85. return "Idle";
  86. }
  87. return LP1WaferAssociation.JobStatus;
  88. }
  89. }
  90. public string LP2ProcStatus
  91. {
  92. get
  93. {
  94. if (LP2WaferAssociation.JobStatus == "")
  95. {
  96. return "Idle";
  97. }
  98. return LP2WaferAssociation.JobStatus;
  99. }
  100. }
  101. private string[] _LP1StatusColor = new string[2];
  102. public string[] LP1StatusColor
  103. {
  104. get
  105. {
  106. switch (LP1ProcStatus)
  107. {
  108. case "Idle":
  109. _LP1StatusColor[0] = "Gold";
  110. _LP1StatusColor[1] = "Black";
  111. break;
  112. case "WaitingForStart":
  113. _LP1StatusColor[0] = "Blue";
  114. _LP1StatusColor[1] = "White";
  115. break;
  116. case "Executing":
  117. _LP1StatusColor[0] = "Cyan";
  118. _LP1StatusColor[1] = "Black";
  119. break;
  120. case "Paused":
  121. _LP1StatusColor[0] = "Blue";
  122. _LP1StatusColor[1] = "White";
  123. break;
  124. default:
  125. _LP1StatusColor[0] = "Gold";
  126. _LP1StatusColor[1] = "Black";
  127. break;
  128. }
  129. return _LP1StatusColor;
  130. }
  131. }
  132. private string[] _LP2StatusColor = new string[2];
  133. public string[] LP2StatusColor
  134. {
  135. get
  136. {
  137. switch (LP2ProcStatus)
  138. {
  139. case "Idle":
  140. _LP2StatusColor[0] = "Gold";
  141. _LP2StatusColor[1] = "Black";
  142. break;
  143. case "WaitingForStart":
  144. _LP2StatusColor[0] = "Blue";
  145. _LP2StatusColor[1] = "White";
  146. break;
  147. case "Executing":
  148. _LP2StatusColor[0] = "Cyan";
  149. _LP2StatusColor[1] = "Black";
  150. break;
  151. case "Paused":
  152. _LP2StatusColor[0] = "Blue";
  153. _LP2StatusColor[1] = "White";
  154. break;
  155. default:
  156. _LP2StatusColor[0] = "Gold";
  157. _LP2StatusColor[1] = "Black";
  158. break;
  159. }
  160. return _LP2StatusColor;
  161. }
  162. }
  163. [Subscription("LP1.CassetteState")]
  164. public LoadportCassetteState LP1CassetteState { get; set; }
  165. [Subscription("LP1.FoupDoorState")]
  166. public FoupDoorState LP1DoorState { get; set; }
  167. [Subscription("LP2.CassetteState")]
  168. public LoadportCassetteState LP2CassetteState { get; set; }
  169. [Subscription("LP2.FoupDoorState")]
  170. public FoupDoorState LP2DoorState { get; set; }
  171. [Subscription("LP1.CassettePlaced")]
  172. public bool PlacedLP1 { get; set; }
  173. public Visibility Foup1Visibility
  174. {
  175. get
  176. {
  177. if (IsLP1Installed)
  178. {
  179. return Visibility.Visible;
  180. }
  181. else
  182. return Visibility.Hidden;
  183. }
  184. }
  185. [Subscription("LP1.IsLoaded")]
  186. public bool IsLoadedLP1 { get; set; }
  187. [Subscription("LP2.CassettePlaced")]
  188. public bool PlacedLP2 { get; set; }
  189. public Visibility Foup2Visibility
  190. {
  191. get
  192. {
  193. if (IsLP2Installed)
  194. {
  195. return Visibility.Visible;
  196. }
  197. else
  198. return Visibility.Hidden;
  199. }
  200. }
  201. [Subscription("LP2.IsLoaded")]
  202. public bool IsLoadedLP2 { get; set; }
  203. private R_TRIG _lp1JobFinished = new R_TRIG();
  204. private R_TRIG _lp2JobFinished = new R_TRIG();
  205. private R_TRIG _lp1Removed = new R_TRIG();
  206. private R_TRIG _lp2Removed = new R_TRIG();
  207. [Subscription("EfemRobot.RobotMoveAction")]
  208. public MECF.Framework.Common.CommonData.RobotMoveInfo EfemRobotMoveAction
  209. {
  210. get;
  211. set;
  212. }
  213. public bool Foup1Present
  214. {
  215. get { return LP1CassetteState == LoadportCassetteState.Normal; }
  216. }
  217. public bool Foup1Idle
  218. {
  219. get { return LP1CassetteState == LoadportCassetteState.Normal && !Foup1Busy && !Foup1Complete; }
  220. }
  221. public bool Foup1Complete
  222. {
  223. get { return LP1JobDone && Foup1Present; }
  224. }
  225. public bool Foup1Busy
  226. {
  227. get { return LP1JobStatus == "WaitingForStart" || LP1JobStatus == "Executing" || LP1JobStatus == "Paused"; }
  228. }
  229. public bool Foup1Error
  230. {
  231. get { return LP1WaferProtrude == 1; }
  232. }
  233. public bool Foup2Present
  234. {
  235. get { return LP2CassetteState == LoadportCassetteState.Normal; }
  236. }
  237. public bool Foup2Idle
  238. {
  239. get { return LP2CassetteState == LoadportCassetteState.Normal && !Foup2Busy && !Foup2Complete; }
  240. }
  241. public bool Foup2Complete
  242. {
  243. get { return LP2JobDone && Foup2Present; }
  244. }
  245. public bool Foup2Busy
  246. {
  247. get { return LP2JobStatus == "WaitingForStart" || LP2JobStatus == "Executing" || LP2JobStatus == "Paused"; }
  248. }
  249. public bool Foup2Error
  250. {
  251. get { return LP2WaferProtrude == 1; }
  252. }
  253. //public RobotMoveInfo EfemRobotMoveInfo
  254. //{
  255. // get
  256. // {
  257. // RobotMoveInfo _moveInfo = new RobotMoveInfo() { BladeTarget = "System" };
  258. // if (!string.IsNullOrEmpty(EfemRobotMoveAction))
  259. // {
  260. // var action = EfemRobotMoveAction.Split('.');
  261. // _moveInfo.BladeTarget = action[0];
  262. // _moveInfo.Action = (RobotAction)Enum.Parse(typeof(RobotAction), action[1]);
  263. // }
  264. // return _moveInfo;
  265. // }
  266. //}
  267. [Subscription("LP1.JobDone")]
  268. public bool LP1JobDone { get; set; }
  269. [Subscription("LP1.IsWaferProtrude")]
  270. public int LP1WaferProtrude { get; set; }
  271. [Subscription("LP2.JobDone")]
  272. public bool LP2JobDone { get; set; }
  273. [Subscription("LP2.IsWaferProtrude")]
  274. public int LP2WaferProtrude { get; set; }
  275. [Subscription("LP1.WaferSize")]
  276. public string LP1WaferSize { get; set; }
  277. public string WaferSizeLP1
  278. {
  279. get { return LP1CassetteState == LoadportCassetteState.Normal ? GetWaferSize(LP1WaferSize) : "--"; }
  280. }
  281. [Subscription("LP2.WaferSize")]
  282. public string LP2WaferSize { get; set; }
  283. public string WaferSizeLP2
  284. {
  285. get { return LP2CassetteState == LoadportCassetteState.Normal ? GetWaferSize(LP2WaferSize) : "--"; }
  286. }
  287. [Subscription("Aligner1.WaferSize")]
  288. public string Aligner1WaferSize { get; set; }
  289. public string WaferSizeAligner1
  290. {
  291. get { return GetWaferSize(Aligner1WaferSize); }
  292. }
  293. [Subscription("Aligner2.WaferSize")]
  294. public string Aligner2WaferSize { get; set; }
  295. public string WaferSizeAligner2
  296. {
  297. get { return GetWaferSize(Aligner2WaferSize); }
  298. }
  299. [Subscription("Cooling1.WaferSize")]
  300. public string Cooling1WaferSize { get; set; }
  301. public string WaferSizeCooling1
  302. {
  303. get { return GetWaferSize(Cooling1WaferSize); }
  304. }
  305. [Subscription("Cooling2.WaferSize")]
  306. public string Cooling2WaferSize { get; set; }
  307. public string WaferSizeCooling2
  308. {
  309. get { return GetWaferSize(Cooling2WaferSize); }
  310. }
  311. [Subscription("EfemRobot.WaferSize")]
  312. public string EfemRobotWaferSize { get; set; }
  313. public string WaferSizeEfemRobot
  314. {
  315. get { return GetWaferSize(EfemRobotWaferSize); }
  316. }
  317. [Subscription("PMA.WaferSize")]
  318. public string PMAWaferSize { get; set; }
  319. public string WaferSizePMA
  320. {
  321. get { return GetWaferSize(PMAWaferSize); }
  322. }
  323. [Subscription("PMB.WaferSize")]
  324. public string PMBWaferSize { get; set; }
  325. public string WaferSizePMB
  326. {
  327. get { return GetWaferSize(PMBWaferSize); }
  328. }
  329. [Subscription("PMA.IsAutoMode")]
  330. public bool PMAIsAutoMode { get; set; }
  331. [Subscription("PMB.IsAutoMode")]
  332. public bool PMBIsAutoMode { get; set; }
  333. [Subscription("PMA.IsOnline")]
  334. public bool PMAIsOnline { get; set; }
  335. [Subscription("PMB.IsOnline")]
  336. public bool PMBIsOnline { get; set; }
  337. public string PMAState
  338. {
  339. get
  340. {
  341. return "PMA/" + (PMAIsAutoMode ? "Auto/" : "Manual/") + (PMAIsOnline ? "Online" : "Offline");
  342. }
  343. }
  344. public string PMBState
  345. {
  346. get
  347. {
  348. return "PMB/" + (PMBIsAutoMode ? "Auto/" : "Manual/") + (PMBIsOnline ? "Online" : "Offline");
  349. }
  350. }
  351. [Subscription("EFEM.SmallWafer")]
  352. public int SmallWafer { get; set; }
  353. [Subscription("EFEM.MidWafer")]
  354. public int MidWafer { get; set; }
  355. [Subscription("EFEM.BigWafer")]
  356. public int BigWafer { get; set; }
  357. //[Subscription("EFEM.CassetteDoor")]
  358. //public AITSensorData CassetteDoorStatus
  359. //{
  360. // get;
  361. // set;
  362. //}
  363. [Subscription("EFEM.CassetteDoor")]
  364. public LidState CassetteDoorStatus
  365. {
  366. get;
  367. set;
  368. }
  369. public Visibility CassetteDoorIsOpened
  370. {
  371. get
  372. {
  373. return CassetteDoorStatus == LidState.Open ? Visibility.Visible : Visibility.Hidden;
  374. }
  375. }
  376. //public Visibility CassetteDoorVisibility
  377. //{
  378. // get
  379. // {
  380. // return _efemType == EfemType.FutureEfem ? Visibility.Visible : Visibility.Collapsed;
  381. // }
  382. //}
  383. public Dictionary<string, string> _waferSizeMap = new Dictionary<string, string>()
  384. {
  385. {"WS3", "3'"},{"WS4", "4'"},{"WS6", "6'"}
  386. };
  387. private string GetWaferSize(string size)
  388. {
  389. //if (_efemType == EfemType.JetEfem)
  390. // return "";
  391. if (size != null && _waferSizeMap.ContainsKey(size))
  392. switch (size)
  393. {
  394. case "WS3": return SmallWafer.ToString();
  395. case "WS4": return MidWafer.ToString();
  396. case "WS6": return BigWafer.ToString();
  397. default: return "";
  398. }
  399. //return _waferSizeMap[size];
  400. return "";
  401. }
  402. public DoorState Chamber1DoorState
  403. {
  404. get { return DoorState.Unknown; }
  405. }
  406. public DoorState Chamber2DoorState
  407. {
  408. get { return DoorState.Unknown; }
  409. }
  410. public bool EnableAuto
  411. {
  412. get { return !IsAutoMode; }
  413. }
  414. public bool EnableManual
  415. {
  416. get { return IsAutoMode; }
  417. }
  418. public bool IsRtInitialized
  419. {
  420. get { return false; }
  421. }
  422. public bool EnableMapLP1
  423. {
  424. get
  425. {
  426. return Foup1Present && CassetteDoorStatus == LidState.Close;
  427. }
  428. }
  429. public bool EnableMapLP2
  430. {
  431. get
  432. {
  433. return Foup2Present && CassetteDoorStatus == LidState.Close;
  434. }
  435. }
  436. public bool EnableJobLP1
  437. {
  438. get { return IsAutoMode; }
  439. }
  440. public bool EnableJobLP2
  441. {
  442. get { return IsAutoMode; }
  443. }
  444. #region Mainframe
  445. public bool ButtonControl { get; set; }
  446. [Subscription("Aligner.Status")]
  447. public string AlignerStatus { get; set; }
  448. [Subscription("EFEM.Status")]
  449. public string EFEMStatus { get; set; }
  450. [Subscription("LP1.Status")]
  451. public string LP1Status { get; set; }
  452. [Subscription("LP2.Status")]
  453. public string LP2Status { get; set; }
  454. #endregion Mainframe
  455. #region PM
  456. public string PMALabel
  457. {
  458. get;
  459. set;
  460. }
  461. public string PMBLabel
  462. {
  463. get;
  464. set;
  465. }
  466. [Subscription("PMA.FsmState")]
  467. public string PMAServiceStatus { get; set; }
  468. [Subscription("PMA.RecipeName")]
  469. public string PMARecipeName { get; set; }
  470. [Subscription("PMA.RecipeProcessTime")]
  471. public string PMARemainTime { get; set; }
  472. [Subscription("PMA.StepNo")]
  473. public int PMAStepNo { get; set; }
  474. [Subscription("PMA.RecipeStepName")]
  475. public string PMAStepName { get; set; }
  476. [Subscription("PMA.ChamberPressure")]
  477. public double PMAChamberPressure { get; set; }
  478. [Subscription("PMA.HeaterChamber.Temperature")]
  479. public double PMATemperature { get; set; }
  480. [Subscription("PMA.Chiller.CoolantOutletTempFeedback")]
  481. public double PMAChillerTemperature { get; set; }
  482. public bool PMASlitValveIsOpen
  483. {
  484. get { return SlitDoorDataA != null && SlitDoorDataA.OpenFeedback && !SlitDoorDataA.CloseFeedback; }
  485. }
  486. [Subscription("PMA.SlitDoor.DeviceData")]
  487. public AITCylinderData SlitDoorDataA
  488. {
  489. get;
  490. set;
  491. }
  492. [Subscription("PMB.FsmState")]
  493. public string PMBServiceStatus { get; set; }
  494. [Subscription("PMB.RecipeName")]
  495. public string PMBRecipeName { get; set; }
  496. [Subscription("PMB.RecipeProcessTime")]
  497. public string PMBRemainTime { get; set; }
  498. [Subscription("PMB.StepNo")]
  499. public string PMBStepNo { get; set; }
  500. [Subscription("PMB.RecipeStepName")]
  501. public string PMBStepName { get; set; }
  502. [Subscription("PMB.ChamberPressure")]
  503. public double PMBChamberPressure { get; set; }
  504. [Subscription("PMB.HeaterChamber.Temperature")]
  505. public double PMBTemperature { get; set; }
  506. [Subscription("PMB.Chiller.CoolantOutletTempFeedback")]
  507. public double PMBChillerTemperature { get; set; }
  508. public bool PMBSlitValveIsOpen
  509. {
  510. get { return SlitDoorDataB != null && SlitDoorDataB.OpenFeedback && !SlitDoorDataB.CloseFeedback; }
  511. }
  512. [Subscription("PMB.SlitDoor.DeviceData")]
  513. public AITCylinderData SlitDoorDataB
  514. {
  515. get;
  516. set;
  517. }
  518. public bool IsPMAChillerVisibility
  519. {
  520. get
  521. {
  522. return (bool)QueryDataClient.Instance.Service.GetConfig($"PMA.Chiller.EnableChiller");
  523. }
  524. }
  525. public bool IsPMBChillerVisibility
  526. {
  527. get
  528. {
  529. return (bool)QueryDataClient.Instance.Service.GetConfig($"PMB.Chiller.EnableChiller");
  530. }
  531. }
  532. public bool IsPMAHeaterVisibility
  533. {
  534. get
  535. {
  536. return !IsPMAChillerVisibility;
  537. }
  538. }
  539. public bool IsPMBHeaterVisibility
  540. {
  541. get
  542. {
  543. return !IsPMBChillerVisibility;
  544. }
  545. }
  546. #endregion PM
  547. #region Scheduler
  548. [Subscription("System.IsAutoMode")]
  549. public bool IsAutoMode { get; set; }
  550. public bool _isCycleMode;
  551. public bool _isATMMode;
  552. public Visibility IsCycleInfoVisibility
  553. {
  554. get { return _isCycleMode ? Visibility.Visible : Visibility.Hidden; }
  555. }
  556. public Visibility IsATMInfoVisibility
  557. {
  558. get { return _isATMMode ? Visibility.Visible : Visibility.Hidden; }
  559. }
  560. [Subscription("Scheduler.CycledCount")]
  561. public int CycledCount { get; set; }
  562. [Subscription("Scheduler.CycledWafer")]
  563. public int CycledWafer { get; set; }
  564. [Subscription("Scheduler.CycleSetPoint")]
  565. public int CycleSetPoint { get; set; }
  566. public string CycleCountDisplay
  567. {
  568. get { return (CycleSetPoint > 0 && (CycledCount > CycleSetPoint)) ? $"{CycledCount + 1}/{CycleSetPoint}" : $"{CycledCount}/{CycleSetPoint}"; }
  569. }
  570. [Subscription("LP1.CurrentRecipeList")]
  571. public List<string> LP1CurrentRecipeList { get; set; }
  572. [Subscription("LP1.LocalJobName")]
  573. public string LP1JobName { get; set; }
  574. [Subscription("LP1.LocalJobStatus")]
  575. public string LP1JobStatus { get; set; }
  576. [Subscription("LP1.JobLotName")]
  577. public string LP1JobLotName { get; set; }
  578. [Subscription("LP2.CurrentRecipeList")]
  579. public List<string> LP2CurrentRecipeList { get; set; }
  580. [Subscription("LP2.LocalJobName")]
  581. public string LP2JobName { get; set; }
  582. [Subscription("LP2.LocalJobStatus")]
  583. public string LP2JobStatus { get; set; }
  584. [Subscription("LP2.JobLotName")]
  585. public string LP2JobLotName { get; set; }
  586. public bool IsPauseAllEnable => LP1JobStatus == "Executing" || LP2JobStatus == "Executing";
  587. #endregion Scheduler
  588. #endregion EFEM
  589. public Visibility MapVisibility => (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.HasMapFunction") ? Visibility.Visible : Visibility.Collapsed;
  590. public Visibility LoadVisibility => (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.HasLoadFunction") ? Visibility.Visible : Visibility.Collapsed;
  591. #region LP
  592. public bool EnableLoadLP1
  593. {
  594. get
  595. {
  596. return Foup1Present && string.IsNullOrEmpty(LP1JobStatus) && !IsLoadedLP1 && LP1Status != "Loading";
  597. }
  598. }
  599. public bool EnableLoadLP2
  600. {
  601. get
  602. {
  603. return Foup2Present && string.IsNullOrEmpty(LP2JobStatus) && !IsLoadedLP2 && LP1Status != "Loading";
  604. }
  605. }
  606. public bool EnableUnloadLP1
  607. {
  608. get
  609. {
  610. return Foup1Present && (string.IsNullOrEmpty(LP1JobStatus) || LP1JobStatus == "Completed") && IsLoadedLP1 && LP1Status != "Unloading";
  611. }
  612. }
  613. public bool EnableUnloadLP2
  614. {
  615. get
  616. {
  617. return Foup2Present && (string.IsNullOrEmpty(LP2JobStatus) || LP2JobStatus == "Completed") && IsLoadedLP2 && LP1Status != "Unloading";
  618. }
  619. }
  620. public ICommand LP1CarrierIDChangedCommand
  621. {
  622. get;
  623. set;
  624. }
  625. public ICommand LP2CarrierIDChangedCommand
  626. {
  627. get;
  628. set;
  629. }
  630. public string LP1CarrierIDText
  631. {
  632. get;
  633. set;
  634. }
  635. public string LP2CarrierIDText
  636. {
  637. get;
  638. set;
  639. }
  640. public Visibility ScannerVisibility
  641. {
  642. get;
  643. set;
  644. }
  645. #endregion
  646. public Visibility IsLP1Visibility
  647. {
  648. get { return IsLP1Installed ? Visibility.Visible : Visibility.Collapsed; }
  649. }
  650. public Visibility IsLP2Visibility
  651. {
  652. get { return IsLP2Installed ? Visibility.Visible : Visibility.Collapsed; }
  653. }
  654. #endregion Property
  655. public OverViewModel()
  656. {
  657. this.DisplayName = "OverView";
  658. }
  659. protected override void OnInitialize()
  660. {
  661. base.OnInitialize();
  662. base.InitModules();
  663. LP1WaferAssociation = new WaferAssociationInfo();
  664. if(ModuleManager.ModuleInfos.ContainsKey("LP1"))
  665. {
  666. LP1WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP1"];
  667. }
  668. LP2WaferAssociation = new WaferAssociationInfo();
  669. if (ModuleManager.ModuleInfos.ContainsKey("LP2"))
  670. {
  671. LP2WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP2"];
  672. }
  673. LP1CarrierIDChangedCommand = new DelegateCommand<object>(LP1CarrierIDInputChanged);
  674. LP2CarrierIDChangedCommand = new DelegateCommand<object>(LP2CarrierIDInputChanged);
  675. }
  676. protected override void OnActivate()
  677. {
  678. base.OnActivate();
  679. ScannerVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.EnableScanner") ? Visibility.Visible:Visibility.Hidden;
  680. _isCycleMode = (bool)QueryDataClient.Instance.Service.GetConfig("System.IsCycleMode");
  681. _isATMMode = (bool)QueryDataClient.Instance.Service.GetConfig("System.IsATMMode");
  682. PMALabel = (string)QueryDataClient.Instance.Service.GetConfig("PMA.ChamberLabel");
  683. PMBLabel = (string)QueryDataClient.Instance.Service.GetConfig("PMB.ChamberLabel");
  684. }
  685. public void Start()
  686. {
  687. //if (MenuPermission != 3) return;
  688. InvokeClient.Instance.Service.DoOperation("System.StartAutoRun");
  689. }
  690. public void Stop()
  691. {
  692. //InvokeClient.Instance.Service.DoOperation("System.StartAutoRun");
  693. }
  694. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  695. {
  696. ContextMenuManager.Instance.IsAutoMode = this.IsAutoMode;
  697. ModuleTemperature["PMA"] = (float)PMATemperature;
  698. ModuleTemperature["PMB"] = (float)PMBTemperature;
  699. LP1WaferAssociation.JobID = LP1JobName;
  700. LP1WaferAssociation.JobStatus = LP1JobStatus;
  701. LP2WaferAssociation.JobID = LP2JobName;
  702. LP2WaferAssociation.JobStatus = LP2JobStatus;
  703. LP1WaferAssociation.JobID = LP1JobName;
  704. LP1WaferAssociation.JobStatus = LP1JobStatus;
  705. if (!string.IsNullOrEmpty(LP1JobName))
  706. LP1WaferAssociation.LotId = LP1JobLotName;
  707. LP2WaferAssociation.JobID = LP2JobName;
  708. LP2WaferAssociation.JobStatus = LP2JobStatus;
  709. if (!string.IsNullOrEmpty(LP2JobName))
  710. LP2WaferAssociation.LotId = LP2JobLotName;
  711. _lp1JobFinished.CLK = string.IsNullOrEmpty(LP1JobName);
  712. if (_lp1JobFinished.Q)
  713. {
  714. var wafers = LP1WaferAssociation.ModuleData.WaferManager.Wafers;
  715. for (int i = 0; i < wafers.Count; i++)
  716. {
  717. wafers[i].SequenceName = "";
  718. }
  719. LP1WaferAssociation.LotId = "";
  720. LP1WaferAssociation.SequenceName = "";
  721. }
  722. _lp2JobFinished.CLK = string.IsNullOrEmpty(LP2JobName);
  723. if (_lp2JobFinished.Q)
  724. {
  725. var wafers = LP2WaferAssociation.ModuleData.WaferManager.Wafers;
  726. for (int i = 0; i < wafers.Count; i++)
  727. {
  728. wafers[i].SequenceName = "";
  729. }
  730. LP2WaferAssociation.LotId = "";
  731. LP2WaferAssociation.SequenceName = "";
  732. }
  733. if (!string.IsNullOrEmpty(LP1JobStatus) && LP1JobStatus == "Executing")
  734. {
  735. var wafers = LP1WaferAssociation.ModuleData.WaferManager.Wafers;
  736. for (int i = 0; i < wafers.Count; i++)
  737. {
  738. wafers[i].SequenceName = LP1CurrentRecipeList[wafers[i].SlotID];
  739. }
  740. }
  741. if (!string.IsNullOrEmpty(LP2JobStatus) && LP2JobStatus == "Executing")
  742. {
  743. var wafers = LP2WaferAssociation.ModuleData.WaferManager.Wafers;
  744. for (int i = 0; i < wafers.Count; i++)
  745. {
  746. wafers[i].SequenceName = LP2CurrentRecipeList[wafers[i].SlotID];
  747. }
  748. }
  749. _lp1Removed.CLK = (LP1CassetteState != LoadportCassetteState.Normal);
  750. if (_lp1Removed.Q)
  751. {
  752. LP1CarrierIDText = "";
  753. }
  754. _lp2Removed.CLK = (LP2CassetteState != LoadportCassetteState.Normal);
  755. if (_lp2Removed.Q)
  756. {
  757. LP2CarrierIDText = "";
  758. }
  759. if (LP1CassetteState != LoadportCassetteState.Normal)
  760. {
  761. foreach (var wafer in LP1WaferAssociation.ModuleData.WaferManager.Wafers)
  762. {
  763. wafer.SequenceName = "";
  764. }
  765. }
  766. if (LP2CassetteState != LoadportCassetteState.Normal)
  767. {
  768. foreach (var wafer in LP2WaferAssociation.ModuleData.WaferManager.Wafers)
  769. {
  770. wafer.SequenceName = "";
  771. }
  772. }
  773. FOUPA.IsJobDone = LP1JobDone;
  774. FOUPB.IsJobDone = LP2JobDone;
  775. }
  776. #region LP Operation
  777. public void SetThick(string moduleID)
  778. {
  779. //if (MenuPermission != 3) return;
  780. //LoadPortProvider.Instance.SetThick(moduleID);
  781. }
  782. public void SetThin(string moduleID)
  783. {
  784. //if (MenuPermission != 3) return;
  785. //LoadPortProvider.Instance.SetThin(moduleID);
  786. }
  787. public void MapLP(string moduleID)
  788. {
  789. //if (MenuPermission != 3) return;
  790. LoadPortProvider.Instance.MapLP(moduleID);
  791. }
  792. public void LoadLP(string moduleID)
  793. {
  794. InvokeClient.Instance.Service.DoOperation($"{moduleID}.Load");
  795. }
  796. public void UnloadLP(string moduleID)
  797. {
  798. InvokeClient.Instance.Service.DoOperation($"{moduleID}.Unload");
  799. }
  800. public void HomeAll()
  801. {
  802. //if (MenuPermission != 3) return;
  803. InvokeClient.Instance.Service.DoOperation("System.HomeAll");
  804. }
  805. public void ReturnAllWafer()
  806. {
  807. //if (MenuPermission != 3) return;
  808. WindowManager wm = new WindowManager();
  809. bool needCooling = false;
  810. int coolingTime = 0;
  811. bool needAligning = false;
  812. int alignAngle = 0;
  813. if (ModuleManager.ModuleInfos.ContainsKey("Cooling1") || ModuleManager.ModuleInfos.ContainsKey("Cooling2"))
  814. {
  815. WaferTransferDialogViewModel _transferVM = new WaferTransferDialogViewModel("Would the wafer need cooling?", false, true, "");
  816. bool? bret = wm.ShowDialogWithNoStyle(_transferVM);
  817. if ((bool)bret)
  818. {
  819. //get and use transfer conditions
  820. WaferTransferCondition conditions = _transferVM.DialogResult;
  821. needCooling = conditions.IsPassCooling;
  822. coolingTime = conditions.CoolingTime;
  823. InvokeClient.Instance.Service.DoOperation("System.ReturnAllWafer", needCooling, coolingTime, needAligning, alignAngle);
  824. }
  825. }
  826. else if(ModuleManager.ModuleInfos.ContainsKey("Aligner1") || ModuleManager.ModuleInfos.ContainsKey("Aligner2"))
  827. {
  828. WaferTransferDialogViewModel _transferVM = new WaferTransferDialogViewModel("Would the wafer need aligning?", true, false, "");
  829. bool? bret = wm.ShowDialogWithNoStyle(_transferVM);
  830. if ((bool)bret)
  831. {
  832. //get and use transfer conditions
  833. WaferTransferCondition conditions = _transferVM.DialogResult;
  834. needAligning = conditions.IsPassAligner;
  835. alignAngle = conditions.AlignerAngle;
  836. InvokeClient.Instance.Service.DoOperation("System.ReturnAllWafer", needCooling, coolingTime, needAligning, alignAngle);
  837. }
  838. }
  839. }
  840. public void PauseAllJob()
  841. {
  842. if (!string.IsNullOrEmpty(LP1WaferAssociation.JobID))
  843. WaferAssociationProvider.Instance.Pause(LP1WaferAssociation.JobID);
  844. if (!string.IsNullOrEmpty(LP2WaferAssociation.JobID))
  845. WaferAssociationProvider.Instance.Pause(LP2WaferAssociation.JobID);
  846. }
  847. public void Abort()
  848. {
  849. //if (MenuPermission != 3) return;
  850. InvokeClient.Instance.Service.DoOperation("System.Abort");
  851. }
  852. public void Auto()
  853. {
  854. //if (MenuPermission != 3) return;
  855. InvokeClient.Instance.Service.DoOperation("System.SetAutoMode");
  856. }
  857. public void Manual()
  858. {
  859. //if (MenuPermission != 3) return;
  860. InvokeClient.Instance.Service.DoOperation("System.SetManualMode");
  861. }
  862. #endregion LP Operation
  863. #region Sequence operation
  864. public void SelectSequence(WaferAssociationInfo info)
  865. {
  866. //if (MenuPermission != 3) return;
  867. SequenceDialogViewModel dialog = new SequenceDialogViewModel();
  868. dialog.DisplayName = "Select Sequence";
  869. dialog.Files = new ObservableCollection<FileNode>(RecipeSequenceTreeBuilder.GetFiles(
  870. RecipeClient.Instance.Service.GetSequenceNameList()
  871. ));
  872. WindowManager wm = new WindowManager();
  873. bool? bret = wm.ShowDialog(dialog);
  874. if ((bool)bret)
  875. {
  876. info.SequenceName = dialog.DialogResult;
  877. }
  878. }
  879. public void SetSlot(WaferAssociationInfo info)
  880. {
  881. if (InputSlotCheck(info.SlotFrom, info.SlotTo))
  882. AssociateSequence(info, true);
  883. }
  884. public void SkipSlot(WaferAssociationInfo info)
  885. {
  886. if (InputSlotCheck(info.SlotFrom, info.SlotTo))
  887. AssociateSequence(info, false);
  888. }
  889. public void SetAll(WaferAssociationInfo info)
  890. {
  891. //if (MenuPermission != 3) return;
  892. info.SlotFrom = 1;
  893. info.SlotTo = (int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber");
  894. AssociateSequence(info, true);
  895. }
  896. public void DeselectAll(WaferAssociationInfo info)
  897. {
  898. //if (MenuPermission != 3) return;
  899. info.SlotFrom = 1;
  900. info.SlotTo = (int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber");
  901. AssociateSequence(info, false);
  902. }
  903. public void SetSequence(WaferAssociationInfo info, int slotIndex, string seqName)
  904. {
  905. bool flag = string.IsNullOrEmpty(seqName);
  906. AssociateSequence(info, flag, slotIndex - 1);
  907. }
  908. private bool InputSlotCheck(int from, int to)
  909. {
  910. if (from > to)
  911. {
  912. DialogBox.ShowInfo("This index of from slot should be large than the index of to slot.");
  913. return false;
  914. }
  915. if (from < 1 || to > (int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber"))
  916. {
  917. DialogBox.ShowInfo($"This input value for from should be between 1 and {(int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber")}.");
  918. return false;
  919. }
  920. return true;
  921. }
  922. private void AssociateSequence(WaferAssociationInfo info, bool flag, int slot = -1)
  923. {
  924. List<WaferInfo> wafers = info.ModuleData.WaferManager.Wafers;
  925. var fromBottom = QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotFromBottom");
  926. int parityFlag = (int)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.WaferPlacementParityFlag");
  927. if (slot >= 0) //by wafer
  928. {
  929. // Wafer Placement Parity Checking
  930. if(parityFlag != 0 && slot % 2 == parityFlag % 2)
  931. {
  932. string slotParity = parityFlag == 2 ? "Odd" : "Even";
  933. DialogBox.ShowWarning($"Cannot process {slotParity} slot wafer.");
  934. return;
  935. }
  936. int index = wafers.Count - slot - 1;
  937. if (fromBottom != null && !((bool)fromBottom))
  938. {
  939. index = slot;
  940. }
  941. if (index < wafers.Count)
  942. {
  943. if (flag && HasWaferOnSlot(wafers, index))
  944. wafers[index].SequenceName = info.SequenceName;
  945. else
  946. wafers[index].SequenceName = string.Empty;
  947. }
  948. }
  949. else //by from-to
  950. {
  951. for (int i = info.SlotFrom - 1; i < info.SlotTo; i++)
  952. {
  953. int index = wafers.Count - i - 1;
  954. if (fromBottom != null && !((bool)fromBottom))
  955. {
  956. index = i;
  957. }
  958. if (index < wafers.Count)
  959. {
  960. if (flag && HasWaferOnSlot(wafers, index) && (parityFlag == 0 || wafers[index].SlotID % 2 != parityFlag % 2))
  961. wafers[index].SequenceName = info.SequenceName;
  962. else
  963. wafers[index].SequenceName = string.Empty;
  964. }
  965. }
  966. }
  967. }
  968. private bool HasWaferOnSlot(List<WaferInfo> wafers, int index)
  969. {
  970. if (wafers[index].WaferStatus == 0)
  971. return false;
  972. return true;
  973. }
  974. public int LP1WaferCount
  975. {
  976. get
  977. {
  978. int iWaferCount = 0;
  979. foreach (var Wafers in ModuleManager.ModuleInfos["LP1"].WaferManager.Wafers)
  980. {
  981. if (Wafers.WaferStatus != 0)
  982. {
  983. iWaferCount++;
  984. }
  985. }
  986. return iWaferCount;
  987. }
  988. }
  989. public string LP1WaferCountInfo
  990. {
  991. get
  992. {
  993. return $"Wafer Count:{LP1WaferCount}";
  994. }
  995. }
  996. public int LP2WaferCount
  997. {
  998. get
  999. {
  1000. int iWaferCount = 0;
  1001. foreach (var Wafers in ModuleManager.ModuleInfos["LP2"].WaferManager.Wafers)
  1002. {
  1003. if (Wafers.WaferStatus != 0)
  1004. {
  1005. iWaferCount++;
  1006. }
  1007. }
  1008. return iWaferCount;
  1009. }
  1010. }
  1011. public string LP2WaferCountInfo
  1012. {
  1013. get
  1014. {
  1015. return $"Wafer数量:{LP2WaferCount}";
  1016. }
  1017. }
  1018. #region barcode
  1019. private void LP1CarrierIDInputChanged(object param)
  1020. {
  1021. string barcode = param as string;
  1022. if (string.IsNullOrEmpty(barcode.Trim()))
  1023. {
  1024. return;
  1025. }
  1026. InvokeClient.Instance.Service.DoOperation($"LP1.CarrierIDScanned", barcode.Trim());
  1027. }
  1028. private void LP2CarrierIDInputChanged(object param)
  1029. {
  1030. string barcode = param as string;
  1031. if (string.IsNullOrEmpty(barcode.Trim()))
  1032. {
  1033. return;
  1034. }
  1035. InvokeClient.Instance.Service.DoOperation($"LP2.CarrierIDScanned", barcode.Trim());
  1036. }
  1037. #endregion barcode
  1038. #endregion Sequence operation
  1039. #region Job operation
  1040. private bool JobCheck(string jobID)
  1041. {
  1042. if (jobID.Length == 0)
  1043. {
  1044. DialogBox.ShowWarning("Please create job first.");
  1045. return false;
  1046. }
  1047. else
  1048. return true;
  1049. }
  1050. public void CreateJob(WaferAssociationInfo info)
  1051. {
  1052. // Parity Check
  1053. int parityFlag = (int)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.WaferPlacementParityFlag");
  1054. if(parityFlag != 0)
  1055. {
  1056. foreach (var wafer in info.ModuleData.WaferManager.Wafers)
  1057. {
  1058. if (wafer.WaferStatus != 0 && wafer.SlotID % 2 == parityFlag % 2)
  1059. {
  1060. string slotParity = parityFlag == 2 ? "Odd" : "Even";
  1061. DialogBox.ShowWarning($"Cannot create job as {slotParity} slots have wafers.");
  1062. return;
  1063. }
  1064. }
  1065. }
  1066. //if (MenuPermission != 3) return;
  1067. List<string> slotSequence = new List<string>();
  1068. var fromBottom = QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotFromBottom");
  1069. if (fromBottom != null && !((bool)fromBottom))
  1070. {
  1071. info.ModuleData.WaferManager.Wafers.ForEach(key => { slotSequence.Add(key.SequenceName); });
  1072. }
  1073. else
  1074. {
  1075. info.ModuleData.WaferManager.Wafers.ForEach(key => { slotSequence.Insert(0, key.SequenceName); });
  1076. }
  1077. string jobId = info.LotId.Trim();
  1078. if (string.IsNullOrEmpty(jobId))
  1079. jobId = "CJ_Local_" + info.ModuleData.ModuleID;
  1080. info.LotId = jobId;
  1081. info.LotIdSaved = true;
  1082. WaferAssociationProvider.Instance.CreateJob(jobId, info.ModuleData.ModuleID, slotSequence, true);
  1083. }
  1084. public void AbortJob(string jobID)
  1085. {
  1086. //if (MenuPermission != 3) return;
  1087. if (JobCheck(jobID))
  1088. WaferAssociationProvider.Instance.AbortJob(jobID);
  1089. }
  1090. public void Start(string jobID)
  1091. {
  1092. //if (MenuPermission != 3) return;
  1093. if (JobCheck(jobID))
  1094. WaferAssociationProvider.Instance.Start(jobID);
  1095. }
  1096. public void Pause(string jobID)
  1097. {
  1098. //if (MenuPermission != 3) return;
  1099. if (JobCheck(jobID))
  1100. WaferAssociationProvider.Instance.Pause(jobID);
  1101. }
  1102. public void Resume(string jobID)
  1103. {
  1104. //if (MenuPermission != 3) return;
  1105. if (JobCheck(jobID))
  1106. WaferAssociationProvider.Instance.Resume(jobID);
  1107. }
  1108. public void Stop(string jobID)
  1109. {
  1110. //if (MenuPermission != 3) return;
  1111. if (JobCheck(jobID))
  1112. WaferAssociationProvider.Instance.Stop(jobID);
  1113. }
  1114. #endregion Job operation
  1115. }
  1116. }