OverViewModel.cs 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  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. public Visibility LowerArmVisibility
  589. {
  590. get
  591. {
  592. try
  593. {
  594. var armTypeConfig = QueryDataClient.Instance.Service.GetConfig("EFEM.EfemRobotArmType");
  595. if (armTypeConfig == null || !int.TryParse(armTypeConfig.ToString(), out int armType) || armType != 2)
  596. return Visibility.Visible;
  597. var lowerBladeConfig = QueryDataClient.Instance.Service.GetConfig("EFEM.EfemRobot.LowerBladeEnable");
  598. if (lowerBladeConfig != null && bool.TryParse(lowerBladeConfig.ToString(), out bool lowerEnabled))
  599. {
  600. return lowerEnabled ? Visibility.Visible : Visibility.Collapsed;
  601. }
  602. return Visibility.Collapsed;
  603. }
  604. catch
  605. {
  606. return Visibility.Visible;
  607. }
  608. }
  609. }
  610. public Visibility UpperArmVisibility
  611. {
  612. get
  613. {
  614. try
  615. {
  616. var armTypeConfig = QueryDataClient.Instance.Service.GetConfig("EFEM.EfemRobotArmType");
  617. if (armTypeConfig == null || !int.TryParse(armTypeConfig.ToString(), out int armType) || armType != 2)
  618. return Visibility.Visible;
  619. var upperBladeConfig = QueryDataClient.Instance.Service.GetConfig("EFEM.EfemRobot.UpperBladeEnable");
  620. if (upperBladeConfig != null && bool.TryParse(upperBladeConfig.ToString(), out bool upperEnabled))
  621. {
  622. return upperEnabled ? Visibility.Visible : Visibility.Collapsed;
  623. }
  624. return Visibility.Collapsed;
  625. }
  626. catch
  627. {
  628. return Visibility.Visible;
  629. }
  630. }
  631. }
  632. #endregion EFEM
  633. public Visibility MapVisibility => (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.HasMapFunction") ? Visibility.Visible : Visibility.Collapsed;
  634. public Visibility LoadVisibility => (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.HasLoadFunction") ? Visibility.Visible : Visibility.Collapsed;
  635. #region LP
  636. public bool EnableLoadLP1
  637. {
  638. get
  639. {
  640. return Foup1Present && string.IsNullOrEmpty(LP1JobStatus) && !IsLoadedLP1 && LP1Status != "Loading";
  641. }
  642. }
  643. public bool EnableLoadLP2
  644. {
  645. get
  646. {
  647. return Foup2Present && string.IsNullOrEmpty(LP2JobStatus) && !IsLoadedLP2 && LP1Status != "Loading";
  648. }
  649. }
  650. public bool EnableUnloadLP1
  651. {
  652. get
  653. {
  654. return Foup1Present && (string.IsNullOrEmpty(LP1JobStatus) || LP1JobStatus == "Completed") && IsLoadedLP1 && LP1Status != "Unloading";
  655. }
  656. }
  657. public bool EnableUnloadLP2
  658. {
  659. get
  660. {
  661. return Foup2Present && (string.IsNullOrEmpty(LP2JobStatus) || LP2JobStatus == "Completed") && IsLoadedLP2 && LP1Status != "Unloading";
  662. }
  663. }
  664. public ICommand LP1CarrierIDChangedCommand
  665. {
  666. get;
  667. set;
  668. }
  669. public ICommand LP2CarrierIDChangedCommand
  670. {
  671. get;
  672. set;
  673. }
  674. public string LP1CarrierIDText
  675. {
  676. get;
  677. set;
  678. }
  679. public string LP2CarrierIDText
  680. {
  681. get;
  682. set;
  683. }
  684. public Visibility ScannerVisibility
  685. {
  686. get;
  687. set;
  688. }
  689. #endregion
  690. public Visibility IsLP1Visibility
  691. {
  692. get { return IsLP1Installed ? Visibility.Visible : Visibility.Collapsed; }
  693. }
  694. public Visibility IsLP2Visibility
  695. {
  696. get { return IsLP2Installed ? Visibility.Visible : Visibility.Collapsed; }
  697. }
  698. #endregion Property
  699. public OverViewModel()
  700. {
  701. this.DisplayName = "OverView";
  702. }
  703. protected override void OnInitialize()
  704. {
  705. base.OnInitialize();
  706. base.InitModules();
  707. LP1WaferAssociation = new WaferAssociationInfo();
  708. if(ModuleManager.ModuleInfos.ContainsKey("LP1"))
  709. {
  710. LP1WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP1"];
  711. }
  712. LP2WaferAssociation = new WaferAssociationInfo();
  713. if (ModuleManager.ModuleInfos.ContainsKey("LP2"))
  714. {
  715. LP2WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP2"];
  716. }
  717. LP1CarrierIDChangedCommand = new DelegateCommand<object>(LP1CarrierIDInputChanged);
  718. LP2CarrierIDChangedCommand = new DelegateCommand<object>(LP2CarrierIDInputChanged);
  719. }
  720. protected override void OnActivate()
  721. {
  722. base.OnActivate();
  723. ScannerVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.EnableScanner") ? Visibility.Visible:Visibility.Hidden;
  724. _isCycleMode = (bool)QueryDataClient.Instance.Service.GetConfig("System.IsCycleMode");
  725. _isATMMode = (bool)QueryDataClient.Instance.Service.GetConfig("System.IsATMMode");
  726. PMALabel = (string)QueryDataClient.Instance.Service.GetConfig("PMA.ChamberLabel");
  727. PMBLabel = (string)QueryDataClient.Instance.Service.GetConfig("PMB.ChamberLabel");
  728. }
  729. public void Start()
  730. {
  731. //if (MenuPermission != 3) return;
  732. InvokeClient.Instance.Service.DoOperation("System.StartAutoRun");
  733. }
  734. public void Stop()
  735. {
  736. //InvokeClient.Instance.Service.DoOperation("System.StartAutoRun");
  737. }
  738. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  739. {
  740. ContextMenuManager.Instance.IsAutoMode = this.IsAutoMode;
  741. ModuleTemperature["PMA"] = (float)PMATemperature;
  742. ModuleTemperature["PMB"] = (float)PMBTemperature;
  743. LP1WaferAssociation.JobID = LP1JobName;
  744. LP1WaferAssociation.JobStatus = LP1JobStatus;
  745. LP2WaferAssociation.JobID = LP2JobName;
  746. LP2WaferAssociation.JobStatus = LP2JobStatus;
  747. LP1WaferAssociation.JobID = LP1JobName;
  748. LP1WaferAssociation.JobStatus = LP1JobStatus;
  749. if (!string.IsNullOrEmpty(LP1JobName))
  750. LP1WaferAssociation.LotId = LP1JobLotName;
  751. LP2WaferAssociation.JobID = LP2JobName;
  752. LP2WaferAssociation.JobStatus = LP2JobStatus;
  753. if (!string.IsNullOrEmpty(LP2JobName))
  754. LP2WaferAssociation.LotId = LP2JobLotName;
  755. _lp1JobFinished.CLK = string.IsNullOrEmpty(LP1JobName);
  756. if (_lp1JobFinished.Q)
  757. {
  758. var wafers = LP1WaferAssociation.ModuleData.WaferManager.Wafers;
  759. for (int i = 0; i < wafers.Count; i++)
  760. {
  761. wafers[i].SequenceName = "";
  762. }
  763. LP1WaferAssociation.LotId = "";
  764. LP1WaferAssociation.SequenceName = "";
  765. }
  766. _lp2JobFinished.CLK = string.IsNullOrEmpty(LP2JobName);
  767. if (_lp2JobFinished.Q)
  768. {
  769. var wafers = LP2WaferAssociation.ModuleData.WaferManager.Wafers;
  770. for (int i = 0; i < wafers.Count; i++)
  771. {
  772. wafers[i].SequenceName = "";
  773. }
  774. LP2WaferAssociation.LotId = "";
  775. LP2WaferAssociation.SequenceName = "";
  776. }
  777. if (!string.IsNullOrEmpty(LP1JobStatus) && LP1JobStatus == "Executing")
  778. {
  779. var wafers = LP1WaferAssociation.ModuleData.WaferManager.Wafers;
  780. for (int i = 0; i < wafers.Count; i++)
  781. {
  782. wafers[i].SequenceName = LP1CurrentRecipeList[wafers[i].SlotID];
  783. }
  784. }
  785. if (!string.IsNullOrEmpty(LP2JobStatus) && LP2JobStatus == "Executing")
  786. {
  787. var wafers = LP2WaferAssociation.ModuleData.WaferManager.Wafers;
  788. for (int i = 0; i < wafers.Count; i++)
  789. {
  790. wafers[i].SequenceName = LP2CurrentRecipeList[wafers[i].SlotID];
  791. }
  792. }
  793. _lp1Removed.CLK = (LP1CassetteState != LoadportCassetteState.Normal);
  794. if (_lp1Removed.Q)
  795. {
  796. LP1CarrierIDText = "";
  797. }
  798. _lp2Removed.CLK = (LP2CassetteState != LoadportCassetteState.Normal);
  799. if (_lp2Removed.Q)
  800. {
  801. LP2CarrierIDText = "";
  802. }
  803. if (LP1CassetteState != LoadportCassetteState.Normal)
  804. {
  805. foreach (var wafer in LP1WaferAssociation.ModuleData.WaferManager.Wafers)
  806. {
  807. wafer.SequenceName = "";
  808. }
  809. }
  810. if (LP2CassetteState != LoadportCassetteState.Normal)
  811. {
  812. foreach (var wafer in LP2WaferAssociation.ModuleData.WaferManager.Wafers)
  813. {
  814. wafer.SequenceName = "";
  815. }
  816. }
  817. FOUPA.IsJobDone = LP1JobDone;
  818. FOUPB.IsJobDone = LP2JobDone;
  819. }
  820. #region LP Operation
  821. public void SetThick(string moduleID)
  822. {
  823. //if (MenuPermission != 3) return;
  824. //LoadPortProvider.Instance.SetThick(moduleID);
  825. }
  826. public void SetThin(string moduleID)
  827. {
  828. //if (MenuPermission != 3) return;
  829. //LoadPortProvider.Instance.SetThin(moduleID);
  830. }
  831. public void MapLP(string moduleID)
  832. {
  833. //if (MenuPermission != 3) return;
  834. LoadPortProvider.Instance.MapLP(moduleID);
  835. }
  836. public void LoadLP(string moduleID)
  837. {
  838. InvokeClient.Instance.Service.DoOperation($"{moduleID}.Load");
  839. }
  840. public void UnloadLP(string moduleID)
  841. {
  842. InvokeClient.Instance.Service.DoOperation($"{moduleID}.Unload");
  843. }
  844. public void HomeAll()
  845. {
  846. //if (MenuPermission != 3) return;
  847. InvokeClient.Instance.Service.DoOperation("System.HomeAll");
  848. }
  849. public void ReturnAllWafer()
  850. {
  851. //if (MenuPermission != 3) return;
  852. WindowManager wm = new WindowManager();
  853. bool needCooling = false;
  854. int coolingTime = 0;
  855. bool needAligning = false;
  856. int alignAngle = 0;
  857. if (ModuleManager.ModuleInfos.ContainsKey("Cooling1") || ModuleManager.ModuleInfos.ContainsKey("Cooling2"))
  858. {
  859. WaferTransferDialogViewModel _transferVM = new WaferTransferDialogViewModel("Would the wafer need cooling?", false, true, "");
  860. bool? bret = wm.ShowDialogWithNoStyle(_transferVM);
  861. if ((bool)bret)
  862. {
  863. //get and use transfer conditions
  864. WaferTransferCondition conditions = _transferVM.DialogResult;
  865. needCooling = conditions.IsPassCooling;
  866. coolingTime = conditions.CoolingTime;
  867. InvokeClient.Instance.Service.DoOperation("System.ReturnAllWafer", needCooling, coolingTime, needAligning, alignAngle);
  868. }
  869. }
  870. else if(ModuleManager.ModuleInfos.ContainsKey("Aligner1") || ModuleManager.ModuleInfos.ContainsKey("Aligner2"))
  871. {
  872. WaferTransferDialogViewModel _transferVM = new WaferTransferDialogViewModel("Would the wafer need aligning?", true, false, "");
  873. bool? bret = wm.ShowDialogWithNoStyle(_transferVM);
  874. if ((bool)bret)
  875. {
  876. //get and use transfer conditions
  877. WaferTransferCondition conditions = _transferVM.DialogResult;
  878. needAligning = conditions.IsPassAligner;
  879. alignAngle = conditions.AlignerAngle;
  880. InvokeClient.Instance.Service.DoOperation("System.ReturnAllWafer", needCooling, coolingTime, needAligning, alignAngle);
  881. }
  882. }
  883. }
  884. public void PauseAllJob()
  885. {
  886. if (!string.IsNullOrEmpty(LP1WaferAssociation.JobID))
  887. WaferAssociationProvider.Instance.Pause(LP1WaferAssociation.JobID);
  888. if (!string.IsNullOrEmpty(LP2WaferAssociation.JobID))
  889. WaferAssociationProvider.Instance.Pause(LP2WaferAssociation.JobID);
  890. }
  891. public void Abort()
  892. {
  893. //if (MenuPermission != 3) return;
  894. InvokeClient.Instance.Service.DoOperation("System.Abort");
  895. }
  896. public void Auto()
  897. {
  898. //if (MenuPermission != 3) return;
  899. InvokeClient.Instance.Service.DoOperation("System.SetAutoMode");
  900. }
  901. public void Manual()
  902. {
  903. //if (MenuPermission != 3) return;
  904. InvokeClient.Instance.Service.DoOperation("System.SetManualMode");
  905. }
  906. #endregion LP Operation
  907. #region Sequence operation
  908. public void SelectSequence(WaferAssociationInfo info)
  909. {
  910. //if (MenuPermission != 3) return;
  911. SequenceDialogViewModel dialog = new SequenceDialogViewModel();
  912. dialog.DisplayName = "Select Sequence";
  913. dialog.Files = new ObservableCollection<FileNode>(RecipeSequenceTreeBuilder.GetFiles(
  914. RecipeClient.Instance.Service.GetSequenceNameList()
  915. ));
  916. WindowManager wm = new WindowManager();
  917. bool? bret = wm.ShowDialog(dialog);
  918. if ((bool)bret)
  919. {
  920. info.SequenceName = dialog.DialogResult;
  921. }
  922. }
  923. public void SetSlot(WaferAssociationInfo info)
  924. {
  925. if (InputSlotCheck(info.SlotFrom, info.SlotTo))
  926. AssociateSequence(info, true);
  927. }
  928. public void SkipSlot(WaferAssociationInfo info)
  929. {
  930. if (InputSlotCheck(info.SlotFrom, info.SlotTo))
  931. AssociateSequence(info, false);
  932. }
  933. public void SetAll(WaferAssociationInfo info)
  934. {
  935. //if (MenuPermission != 3) return;
  936. info.SlotFrom = 1;
  937. info.SlotTo = (int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber");
  938. AssociateSequence(info, true);
  939. }
  940. public void DeselectAll(WaferAssociationInfo info)
  941. {
  942. //if (MenuPermission != 3) return;
  943. info.SlotFrom = 1;
  944. info.SlotTo = (int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber");
  945. AssociateSequence(info, false);
  946. }
  947. public void SetSequence(WaferAssociationInfo info, int slotIndex, string seqName)
  948. {
  949. bool flag = string.IsNullOrEmpty(seqName);
  950. AssociateSequence(info, flag, slotIndex - 1);
  951. }
  952. private bool InputSlotCheck(int from, int to)
  953. {
  954. if (from > to)
  955. {
  956. DialogBox.ShowInfo("This index of from slot should be large than the index of to slot.");
  957. return false;
  958. }
  959. if (from < 1 || to > (int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber"))
  960. {
  961. DialogBox.ShowInfo($"This input value for from should be between 1 and {(int)QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotNumber")}.");
  962. return false;
  963. }
  964. return true;
  965. }
  966. private void AssociateSequence(WaferAssociationInfo info, bool flag, int slot = -1)
  967. {
  968. List<WaferInfo> wafers = info.ModuleData.WaferManager.Wafers;
  969. var fromBottom = QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotFromBottom");
  970. int parityFlag = (int)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.WaferPlacementParityFlag");
  971. if (slot >= 0) //by wafer
  972. {
  973. // Wafer Placement Parity Checking
  974. if(parityFlag != 0 && slot % 2 == parityFlag % 2)
  975. {
  976. string slotParity = parityFlag == 2 ? "Odd" : "Even";
  977. DialogBox.ShowWarning($"Cannot process {slotParity} slot wafer.");
  978. return;
  979. }
  980. int index = wafers.Count - slot - 1;
  981. if (fromBottom != null && !((bool)fromBottom))
  982. {
  983. index = slot;
  984. }
  985. if (index < wafers.Count)
  986. {
  987. if (flag && HasWaferOnSlot(wafers, index))
  988. wafers[index].SequenceName = info.SequenceName;
  989. else
  990. wafers[index].SequenceName = string.Empty;
  991. }
  992. }
  993. else //by from-to
  994. {
  995. for (int i = info.SlotFrom - 1; i < info.SlotTo; i++)
  996. {
  997. int index = wafers.Count - i - 1;
  998. if (fromBottom != null && !((bool)fromBottom))
  999. {
  1000. index = i;
  1001. }
  1002. if (index < wafers.Count)
  1003. {
  1004. if (flag && HasWaferOnSlot(wafers, index) && (parityFlag == 0 || wafers[index].SlotID % 2 != parityFlag % 2))
  1005. wafers[index].SequenceName = info.SequenceName;
  1006. else
  1007. wafers[index].SequenceName = string.Empty;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. private bool HasWaferOnSlot(List<WaferInfo> wafers, int index)
  1013. {
  1014. if (wafers[index].WaferStatus == 0)
  1015. return false;
  1016. return true;
  1017. }
  1018. public int LP1WaferCount
  1019. {
  1020. get
  1021. {
  1022. int iWaferCount = 0;
  1023. foreach (var Wafers in ModuleManager.ModuleInfos["LP1"].WaferManager.Wafers)
  1024. {
  1025. if (Wafers.WaferStatus != 0)
  1026. {
  1027. iWaferCount++;
  1028. }
  1029. }
  1030. return iWaferCount;
  1031. }
  1032. }
  1033. public string LP1WaferCountInfo
  1034. {
  1035. get
  1036. {
  1037. return $"Wafer Count:{LP1WaferCount}";
  1038. }
  1039. }
  1040. public int LP2WaferCount
  1041. {
  1042. get
  1043. {
  1044. int iWaferCount = 0;
  1045. foreach (var Wafers in ModuleManager.ModuleInfos["LP2"].WaferManager.Wafers)
  1046. {
  1047. if (Wafers.WaferStatus != 0)
  1048. {
  1049. iWaferCount++;
  1050. }
  1051. }
  1052. return iWaferCount;
  1053. }
  1054. }
  1055. public string LP2WaferCountInfo
  1056. {
  1057. get
  1058. {
  1059. return $"Wafer数量:{LP2WaferCount}";
  1060. }
  1061. }
  1062. #region barcode
  1063. private void LP1CarrierIDInputChanged(object param)
  1064. {
  1065. string barcode = param as string;
  1066. if (string.IsNullOrEmpty(barcode.Trim()))
  1067. {
  1068. return;
  1069. }
  1070. InvokeClient.Instance.Service.DoOperation($"LP1.CarrierIDScanned", barcode.Trim());
  1071. }
  1072. private void LP2CarrierIDInputChanged(object param)
  1073. {
  1074. string barcode = param as string;
  1075. if (string.IsNullOrEmpty(barcode.Trim()))
  1076. {
  1077. return;
  1078. }
  1079. InvokeClient.Instance.Service.DoOperation($"LP2.CarrierIDScanned", barcode.Trim());
  1080. }
  1081. #endregion barcode
  1082. #endregion Sequence operation
  1083. #region Job operation
  1084. private bool JobCheck(string jobID)
  1085. {
  1086. if (jobID.Length == 0)
  1087. {
  1088. DialogBox.ShowWarning("Please create job first.");
  1089. return false;
  1090. }
  1091. else
  1092. return true;
  1093. }
  1094. public void CreateJob(WaferAssociationInfo info)
  1095. {
  1096. // Parity Check
  1097. int parityFlag = (int)QueryDataClient.Instance.Service.GetConfig("EFEM.LoadPort.WaferPlacementParityFlag");
  1098. if(parityFlag != 0)
  1099. {
  1100. foreach (var wafer in info.ModuleData.WaferManager.Wafers)
  1101. {
  1102. if (wafer.WaferStatus != 0 && wafer.SlotID % 2 == parityFlag % 2)
  1103. {
  1104. string slotParity = parityFlag == 2 ? "Odd" : "Even";
  1105. DialogBox.ShowWarning($"Cannot create job as {slotParity} slots have wafers.");
  1106. return;
  1107. }
  1108. }
  1109. }
  1110. //if (MenuPermission != 3) return;
  1111. List<string> slotSequence = new List<string>();
  1112. var fromBottom = QueryDataClient.Instance.Service.GetConfig($"EFEM.LoadPort.SlotFromBottom");
  1113. if (fromBottom != null && !((bool)fromBottom))
  1114. {
  1115. info.ModuleData.WaferManager.Wafers.ForEach(key => { slotSequence.Add(key.SequenceName); });
  1116. }
  1117. else
  1118. {
  1119. info.ModuleData.WaferManager.Wafers.ForEach(key => { slotSequence.Insert(0, key.SequenceName); });
  1120. }
  1121. string jobId = info.LotId.Trim();
  1122. if (string.IsNullOrEmpty(jobId))
  1123. jobId = "CJ_Local_" + info.ModuleData.ModuleID;
  1124. info.LotId = jobId;
  1125. info.LotIdSaved = true;
  1126. WaferAssociationProvider.Instance.CreateJob(jobId, info.ModuleData.ModuleID, slotSequence, true);
  1127. }
  1128. public void AbortJob(string jobID)
  1129. {
  1130. //if (MenuPermission != 3) return;
  1131. if (JobCheck(jobID))
  1132. WaferAssociationProvider.Instance.AbortJob(jobID);
  1133. }
  1134. public void Start(string jobID)
  1135. {
  1136. //if (MenuPermission != 3) return;
  1137. if (JobCheck(jobID))
  1138. WaferAssociationProvider.Instance.Start(jobID);
  1139. }
  1140. public void Pause(string jobID)
  1141. {
  1142. //if (MenuPermission != 3) return;
  1143. if (JobCheck(jobID))
  1144. WaferAssociationProvider.Instance.Pause(jobID);
  1145. }
  1146. public void Resume(string jobID)
  1147. {
  1148. //if (MenuPermission != 3) return;
  1149. if (JobCheck(jobID))
  1150. WaferAssociationProvider.Instance.Resume(jobID);
  1151. }
  1152. public void Stop(string jobID)
  1153. {
  1154. //if (MenuPermission != 3) return;
  1155. if (JobCheck(jobID))
  1156. WaferAssociationProvider.Instance.Stop(jobID);
  1157. }
  1158. #endregion Job operation
  1159. }
  1160. }