OverViewModel.cs 40 KB

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