EfemDualViewModel.cs 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Windows;
  6. using Aitex.Core.Common.DeviceData;
  7. using Aitex.Core.Util;
  8. using Aitex.Sorter.Common;
  9. using Caliburn.Micro;
  10. using EfemDualUI.Controls.Parts;
  11. using MECF.Framework.Common.CommonData;
  12. using MECF.Framework.Common.DataCenter;
  13. using MECF.Framework.Common.Equipment;
  14. using MECF.Framework.Common.OperationCenter;
  15. using MECF.Framework.Common.RecipeCenter;
  16. using MECF.Framework.Common.SubstrateTrackings;
  17. using MECF.Framework.UI.Client.CenterViews.Editors.Sequence;
  18. using MECF.Framework.UI.Client.CenterViews.Operations.WaferAssociation;
  19. using MECF.Framework.UI.Client.ClientBase;
  20. using OpenSEMI.ClientBase;
  21. using VTMRobotPosition = MECF.Framework.UI.Client.ClientControls.RobotControls.VTMRobotPosition;
  22. namespace EfemDualUI.Views.Operations.Overviews
  23. {
  24. public class EfemDualViewModel : LocalUIViewModelBase
  25. {
  26. //public WaferInfo PM1WaferData { get; set; }
  27. //public WaferInfo PM2WaferData { get; set; }
  28. //public WaferInfo PM3WaferData { get; set; }
  29. //public WaferInfo PM4WaferData { get; set; }
  30. //public WaferInfo PM5WaferData { get; set; }
  31. //public WaferInfo AlignerAWaferData { get; set; }
  32. //public WaferInfo AlignerBWaferData { get; set; }
  33. //public WaferInfo TMRobotLowWaferData { get; set; }
  34. //public WaferInfo TMRobotUpWaferData { get; set; }
  35. //[Subscription("VCEA.IsFoupOn")]
  36. //public bool IsVCEAFoupOn { get; set; }
  37. //[Subscription("VCEA.CarrierId")]
  38. //public string LP1CarrierId { get; set; }
  39. //[Subscription("VCEA.LocalJobName")]
  40. //public string LP1JobName { get; set; }
  41. //[Subscription("VCEA.LocalJobStatus")]
  42. //public string LP1JobStatus { get; set; }
  43. //[Subscription("VCEB.IsFoupOn")]
  44. //public bool IsVCEBFoupOn { get; set; }
  45. //[Subscription("VCEB.CarrierId")]
  46. //public string LP2CarrierId { get; set; }
  47. //[Subscription("VCEB.LocalJobName")]
  48. //public string LP2JobName { get; set; }
  49. //[Subscription("VCEB.LocalJobStatus")]
  50. //public string LP2JobStatus { get; set; }
  51. [Subscription("Rt.Status")]
  52. public string RtStatus { get; set; }
  53. public bool IsRtInitialized
  54. {
  55. get
  56. {
  57. return RtStatus != "Init" && RtStatus != "Initializing";
  58. }
  59. }
  60. public bool IsRtRunning
  61. {
  62. get
  63. {
  64. return RtStatus != "Init" && RtStatus != "Idle";
  65. }
  66. }
  67. public bool IsAuto
  68. {
  69. get { return RtStatus == "AutoRunning" || RtStatus == "AutoIdle"; }
  70. }
  71. public bool IsEnableAbort
  72. {
  73. get
  74. {
  75. return IsRtRunning;
  76. }
  77. }
  78. public bool IsEnableAuto
  79. {
  80. get { return !IsAuto && IsRtInitialized; }
  81. }
  82. public bool IsEnableManual
  83. {
  84. get { return IsAuto && IsRtInitialized; }
  85. }
  86. public bool IsEnableInitialize
  87. {
  88. get { return !IsAuto && !IsRtRunning; }
  89. }
  90. public bool _isCycleMode;
  91. public bool _isATMMode;
  92. public Visibility IsCycleInfoVisibility
  93. {
  94. get { return _isCycleMode ? Visibility.Visible : Visibility.Hidden; }
  95. }
  96. public Visibility IsATMInfoVisibility
  97. {
  98. get { return _isATMMode ? Visibility.Visible : Visibility.Hidden; }
  99. }
  100. [Subscription("Scheduler.IsCycleMode")]
  101. public bool IsCycleMode { get; set; }
  102. [Subscription("Scheduler.CycleBy")]
  103. public string CycleBy { get; set; }
  104. [Subscription("Scheduler.CycleWaferCountSetPoint")]
  105. public int CycleWaferCountSetPointDisplay { get; set; }
  106. [Subscription("Scheduler.CycledWaferCount")]
  107. public int CycleWaferCountDisplay { get; set; }
  108. [Subscription("Scheduler.CycleCountSetPoint")]
  109. public int CycleCountSetPointDisplay { get; set; }
  110. [Subscription("Scheduler.CycledCount")]
  111. public int CycleCountDisplay { get; set; }
  112. [Subscription("Scheduler.CycleEscapeTime")]
  113. public TimeSpan CycleEscapeTime { get; set; }
  114. [Subscription("Scheduler.Throughput")]
  115. public double Throughput { get; set; }
  116. [Subscription("PMA.IsOnline")]
  117. public bool PMAIsOnline { get; set; }
  118. public Visibility PMAIsOffline { get { return PMAIsOnline ? Visibility.Hidden : Visibility.Visible; } }
  119. [Subscription("PMB.IsOnline")]
  120. public bool PMBIsOnline { get; set; }
  121. public Visibility PMBIsOffline { get { return PMBIsOnline ? Visibility.Hidden : Visibility.Visible; } }
  122. [Subscription("TM.IsOnline")]
  123. public bool TMIsOnline { get; set; }
  124. public Visibility TMIsOffline { get { return TMIsOnline ? Visibility.Hidden : Visibility.Visible; } }
  125. public bool PMASlitValveOpenFeedback1 { get { return PMASlitDoor1.OpenFeedback; } }
  126. [Subscription("PMA.SlitDoor1.DeviceData")]
  127. public AITCylinderData PMASlitDoor1
  128. {
  129. get;
  130. set;
  131. }
  132. public bool PMASlitValveOpenFeedback2 { get { return PMASlitDoor2.OpenFeedback; } }
  133. [Subscription("PMA.SlitDoor2.DeviceData")]
  134. public AITCylinderData PMASlitDoor2
  135. {
  136. get;
  137. set;
  138. }
  139. public bool PMBSlitValveOpenFeedback1 { get { return PMBSlitDoor1.OpenFeedback; } }
  140. [Subscription("PMB.SlitDoor1.DeviceData")]
  141. public AITCylinderData PMBSlitDoor1
  142. {
  143. get;
  144. set;
  145. }
  146. public bool PMBSlitValveOpenFeedback2 { get { return PMBSlitDoor2.OpenFeedback; } }
  147. [Subscription("PMB.SlitDoor2.DeviceData")]
  148. public AITCylinderData PMBSlitDoor2
  149. {
  150. get;
  151. set;
  152. }
  153. [Subscription("LP1.CurrentRecipeList")]
  154. public List<string> LP1CurrentRecipeList { get; set; }
  155. [Subscription("LP2.CurrentRecipeList")]
  156. public List<string> LP2CurrentRecipeList { get; set; }
  157. [Subscription("LP3.CurrentRecipeList")]
  158. public List<string> LP3CurrentRecipeList { get; set; }
  159. [Subscription("LP1.IsDocked")]
  160. public bool IsLP1Loaded { get; set; }
  161. [Subscription("LP2.IsDocked")]
  162. public bool IsLP2Loaded { get; set; }
  163. [Subscription("LP3.IsDocked")]
  164. public bool IsLP3Loaded { get; set; }
  165. [Subscription("LP1.WaferSize")]
  166. public string LP1WaferSize { get; set; }
  167. [Subscription("LP2.WaferSize")]
  168. public string LP2WaferSize { get; set; }
  169. [Subscription("LP3.WaferSize")]
  170. public string LP3WaferSize { get; set; }
  171. [Subscription("EFEM.IsOnline")]
  172. public bool IsEfemOnline { get; set; }
  173. public Visibility IsEfemOffline { get { return IsEfemOnline ? Visibility.Hidden : Visibility.Visible; } }
  174. public bool EnableMapLP1
  175. {
  176. get
  177. {
  178. return IsLP1Placed && IsLP1Docked && IsLP1DoorOpen;
  179. }
  180. }
  181. [Subscription("LP1.IsOnline")]
  182. public bool IsLP1Online { get; set; }
  183. public string LP1Online => IsEfemOnline ? "Online" : "Offline";
  184. [Subscription("LP1.Status")]
  185. public string LP1Status { get; set; }
  186. public string LP1StatusBackground
  187. {
  188. get { return GetUnitStatusBackground(LP1Status); }
  189. }
  190. [Subscription("LP1.JobDone")]
  191. public bool LP1JobDone { get; set; }
  192. public bool LP1Done
  193. {
  194. get { return LP1JobDone; }
  195. }
  196. public bool LP1Error
  197. {
  198. get { return (LP1Status == "error"); }
  199. }
  200. public bool LP1Transfer
  201. {
  202. get { return LP1Status == "InTransfer"; }
  203. }
  204. [Subscription("LP1.IsPresent")]
  205. public bool IsLP1Present { get; set; }
  206. public bool IsLP1LoadEnable
  207. {
  208. get { return LP1Status == "Idle" && IsLP1Present && !IsLP1Mapped; }
  209. }
  210. public bool IsLP1UnloadEnable
  211. {
  212. get { return LP1Status == "Idle" && IsLP1Present && IsLP1Clamped && IsLP1Mapped; }
  213. }
  214. [Subscription("LP1.IsPlaced")]
  215. public bool IsLP1Placed { get; set; }
  216. public Visibility Foup1Visibility => IsLP1Placed ? Visibility.Visible : Visibility.Hidden;
  217. [Subscription("LP1.IsClamped")]
  218. public bool IsLP1Clamped { get; set; }
  219. public bool IsLP1ClampEnable
  220. {
  221. get { return IsLP1Present && !IsLP1Clamped && !IsEfemOnline; }
  222. }
  223. public bool IsLP1UnclampEnable
  224. {
  225. get { return !IsLP1Docked && IsLP1Clamped && !IsEfemOnline; }
  226. }
  227. [Subscription("LP1.IsDocked")]
  228. public bool IsLP1Docked { get; set; }
  229. public bool IsLP1DockEnable
  230. {
  231. get { return IsLP1Clamped && !IsLP1Docked && !IsEfemOnline; }
  232. }
  233. public bool IsLP1UndockEnable
  234. {
  235. get { return !IsLP1DoorOpen && IsLP1Docked && !IsEfemOnline; }
  236. }
  237. [Subscription("LP1.IsDoorOpen")]
  238. public bool IsLP1DoorOpen { get; set; }
  239. public bool IsLP1OpenEnable
  240. {
  241. get { return IsLP1Docked && !IsLP1DoorOpen && !IsEfemOnline; }
  242. }
  243. public bool IsLP1CloseEnable
  244. {
  245. get { return IsLP1DoorOpen && !IsEfemOnline; }
  246. }
  247. [Subscription("LP1.IsMapped")]
  248. public bool IsLP1Mapped { get; set; }
  249. public bool IsLP1MapEnable
  250. {
  251. get { return IsLP1DoorOpen && !IsLP1Mapped && !IsEfemOnline; }
  252. }
  253. [Subscription("LP1.LastMapResult")]
  254. public string LP1LastMapResult { get; set; }
  255. [Subscription("LP1.CarrierId")]
  256. public string LP1CarrierId { get; set; }
  257. public bool IsLP1ReadCarrierIdEnable
  258. {
  259. get { return LP1Status == "Idle" && IsLP1Present; }
  260. }
  261. public bool EnableMapLP2
  262. {
  263. get
  264. {
  265. return IsLP2Placed && IsLP2Docked && IsLP2DoorOpen;
  266. }
  267. }
  268. [Subscription("LP2.Status")]
  269. public string LP2Status { get; set; }
  270. public string LP2StatusBackground
  271. {
  272. get { return GetUnitStatusBackground(LP2Status); }
  273. }
  274. [Subscription("LP2.JobDone")]
  275. public bool LP2JobDone { get; set; }
  276. public bool LP2Done
  277. {
  278. get { return LP2JobDone; }
  279. }
  280. public bool LP2Error
  281. {
  282. get { return (LP2Status == "error"); }
  283. }
  284. public bool LP2Transfer
  285. {
  286. get { return LP2Status == "InTransfer"; }
  287. }
  288. [Subscription("LP2.IsOnline")]
  289. public bool IsLP2Online { get; set; }
  290. public string LP2Online => IsEfemOnline ? "Online" : "Offline";
  291. public bool IsLP2AbortEnable
  292. {
  293. get { return LP2Status == "Homing"; }
  294. }
  295. public bool IsLP2ResetEnable
  296. {
  297. get { return LP2Status == "Error"; }
  298. }
  299. [Subscription("LP2.IsPresent")]
  300. public bool IsLP2Present { get; set; }
  301. public bool IsLP2LoadEnable
  302. {
  303. get { return LP2Status == "Idle" && IsLP2Present && !IsLP2Mapped; }
  304. }
  305. public bool IsLP2UnloadEnable
  306. {
  307. get { return LP2Status == "Idle" && IsLP2Present && IsLP2Clamped && IsLP2Mapped; }
  308. }
  309. [Subscription("LP2.IsPlaced")]
  310. public bool IsLP2Placed { get; set; }
  311. public Visibility Foup2Visibility => IsLP2Placed ? Visibility.Visible : Visibility.Hidden;
  312. [Subscription("LP2.IsClamped")]
  313. public bool IsLP2Clamped { get; set; }
  314. public bool IsLP2ClampEnable
  315. {
  316. get { return IsLP2Present && !IsLP2Clamped && !IsEfemOnline; }
  317. }
  318. public bool IsLP2UnclampEnable
  319. {
  320. get { return !IsLP2Docked && IsLP2Clamped && !IsEfemOnline; }
  321. }
  322. [Subscription("LP2.IsDocked")]
  323. public bool IsLP2Docked { get; set; }
  324. public bool IsLP2DockEnable
  325. {
  326. get { return IsLP2Clamped && !IsLP2Docked && !IsEfemOnline; }
  327. }
  328. public bool IsLP2UndockEnable
  329. {
  330. get { return !IsLP2DoorOpen && IsLP2Docked && !IsEfemOnline; }
  331. }
  332. [Subscription("LP2.IsDoorOpen")]
  333. public bool IsLP2DoorOpen { get; set; }
  334. public bool IsLP2OpenEnable
  335. {
  336. get { return IsLP2Docked && !IsLP2DoorOpen && !IsEfemOnline; }
  337. }
  338. public bool IsLP2CloseEnable
  339. {
  340. get { return IsLP2DoorOpen && !IsEfemOnline; }
  341. }
  342. [Subscription("LP2.IsMapped")]
  343. public bool IsLP2Mapped { get; set; }
  344. public bool IsLP2MapEnable
  345. {
  346. get { return IsLP2DoorOpen && !IsLP2Mapped && !IsEfemOnline; }
  347. }
  348. [Subscription("LP2.LastMapResult")]
  349. public string LP2LastMapResult { get; set; }
  350. [Subscription("LP2.CarrierId")]
  351. public string LP2CarrierId { get; set; }
  352. public bool IsLP2ReadCarrierIdEnable
  353. {
  354. get { return LP2Status == "Idle" && IsLP2Present; }
  355. }
  356. public bool EnableMapLP3
  357. {
  358. get
  359. {
  360. return IsLP3Placed && IsLP3Docked && IsLP3DoorOpen;
  361. }
  362. }
  363. [Subscription("LP3.Status")]
  364. public string LP3Status { get; set; }
  365. public string LP3StatusBackground
  366. {
  367. get { return GetUnitStatusBackground(LP3Status); }
  368. }
  369. [Subscription("LP3.JobDone")]
  370. public bool LP3JobDone { get; set; }
  371. public bool LP3Done
  372. {
  373. get { return LP3JobDone; }
  374. }
  375. public bool LP3Error
  376. {
  377. get { return (LP3Status == "error"); }
  378. }
  379. public bool LP3Transfer
  380. {
  381. get { return LP3Status == "InTransfer"; }
  382. }
  383. [Subscription("LP3.IsOnline")]
  384. public bool IsLP3Online { get; set; }
  385. public string LP3Online => IsEfemOnline ? "Online" : "Offline";
  386. public bool IsLP3AbortEnable
  387. {
  388. get { return LP3Status == "Homing"; }
  389. }
  390. public bool IsLP3ResetEnable
  391. {
  392. get { return LP3Status == "Error"; }
  393. }
  394. [Subscription("LP3.IsPresent")]
  395. public bool IsLP3Present { get; set; }
  396. public bool IsLP3LoadEnable
  397. {
  398. get { return LP3Status == "Idle" && IsLP3Present && !IsLP3Mapped; }
  399. }
  400. public bool IsLP3UnloadEnable
  401. {
  402. get { return LP3Status == "Idle" && IsLP3Present && IsLP3Clamped && IsLP3Mapped; }
  403. }
  404. [Subscription("LP3.IsPlaced")]
  405. public bool IsLP3Placed { get; set; }
  406. public Visibility Foup3Visibility => IsLP3Placed ? Visibility.Visible : Visibility.Hidden;
  407. [Subscription("LP3.IsClamped")]
  408. public bool IsLP3Clamped { get; set; }
  409. public bool IsLP3ClampEnable
  410. {
  411. get { return IsLP3Present && !IsLP3Clamped && !IsEfemOnline; }
  412. }
  413. public bool IsLP3UnclampEnable
  414. {
  415. get { return !IsLP3Docked && IsLP3Clamped && !IsEfemOnline; }
  416. }
  417. [Subscription("LP3.IsDocked")]
  418. public bool IsLP3Docked { get; set; }
  419. public bool IsLP3DockEnable
  420. {
  421. get { return IsLP3Clamped && !IsLP3Docked && !IsEfemOnline; }
  422. }
  423. public bool IsLP3UndockEnable
  424. {
  425. get { return !IsLP3DoorOpen && IsLP3Docked && !IsEfemOnline; }
  426. }
  427. [Subscription("LP3.IsDoorOpen")]
  428. public bool IsLP3DoorOpen { get; set; }
  429. public bool IsLP3OpenEnable
  430. {
  431. get { return IsLP3Docked && !IsLP3DoorOpen && !IsEfemOnline; }
  432. }
  433. public bool IsLP3CloseEnable
  434. {
  435. get { return IsLP3DoorOpen && !IsEfemOnline; }
  436. }
  437. [Subscription("LP3.IsMapped")]
  438. public bool IsLP3Mapped { get; set; }
  439. public bool IsLP3MapEnable
  440. {
  441. get { return IsLP3DoorOpen && !IsLP3Mapped && !IsEfemOnline; }
  442. }
  443. [Subscription("LP3.LastMapResult")]
  444. public string LP3LastMapResult { get; set; }
  445. [Subscription("LP3.CarrierId")]
  446. public string LP3CarrierId { get; set; }
  447. public bool IsLP3ReadCarrierIdEnable
  448. {
  449. get { return LP3Status == "Idle" && IsLP3Present; }
  450. }
  451. [Subscription("LP1.LocalJobName")]
  452. public string LP1JobName { get; set; }
  453. [Subscription("LP1.JobLotName")]
  454. public string LP1JobLotName { get; set; }
  455. [Subscription("LP1.LocalJobStatus")]
  456. public string LP1JobStatus { get; set; }
  457. [Subscription("LP2.LocalJobName")]
  458. public string LP2JobName { get; set; }
  459. [Subscription("LP2.JobLotName")]
  460. public string LP2JobLotName { get; set; }
  461. [Subscription("LP2.LocalJobStatus")]
  462. public string LP2JobStatus { get; set; }
  463. [Subscription("LP3.LocalJobName")]
  464. public string LP3JobName { get; set; }
  465. [Subscription("LP3.JobLotName")]
  466. public string LP3JobLotName { get; set; }
  467. [Subscription("LP3.LocalJobStatus")]
  468. public string LP3JobStatus { get; set; }
  469. public int LP1WaferCount
  470. {
  471. get
  472. {
  473. int iWaferCount = 0;
  474. foreach (var Wafers in ModuleManager.ModuleInfos["LP1"].WaferManager.Wafers)
  475. {
  476. if (Wafers.WaferStatus != 0)
  477. {
  478. iWaferCount++;
  479. }
  480. }
  481. return iWaferCount;
  482. }
  483. }
  484. public string LP1WaferCountInfo
  485. {
  486. get
  487. {
  488. if (!string.IsNullOrEmpty(LP1LastMapResult))
  489. {
  490. return $"Wafer数量:{LP1WaferCount}/{LP1LastMapResult.Count(x=>x=='1')}";
  491. }
  492. return $"Wafer数量:{LP1WaferCount}/0";
  493. }
  494. }
  495. public int LP2WaferCount
  496. {
  497. get
  498. {
  499. int iWaferCount = 0;
  500. foreach (var Wafers in ModuleManager.ModuleInfos["LP2"].WaferManager.Wafers)
  501. {
  502. if (Wafers.WaferStatus != 0)
  503. {
  504. iWaferCount++;
  505. }
  506. }
  507. return iWaferCount;
  508. }
  509. }
  510. public string LP2WaferCountInfo
  511. {
  512. get
  513. {
  514. if (!string.IsNullOrEmpty(LP2LastMapResult))
  515. {
  516. return $"Wafer数量:{LP2WaferCount}/{LP2LastMapResult.Count(x => x == '1')}";
  517. }
  518. return $"Wafer数量:{LP2WaferCount}/0";
  519. }
  520. }
  521. public int LP3WaferCount
  522. {
  523. get
  524. {
  525. int iWaferCount = 0;
  526. foreach (var Wafers in ModuleManager.ModuleInfos["LP3"].WaferManager.Wafers)
  527. {
  528. if (Wafers.WaferStatus != 0)
  529. {
  530. iWaferCount++;
  531. }
  532. }
  533. return iWaferCount;
  534. }
  535. }
  536. public string LP3WaferCountInfo
  537. {
  538. get
  539. {
  540. if (!string.IsNullOrEmpty(LP3LastMapResult))
  541. {
  542. return $"Wafer数量:{LP3WaferCount}/{LP3LastMapResult.Count(x => x == '1')}";
  543. }
  544. return $"Wafer数量:{LP3WaferCount}/0";
  545. }
  546. }
  547. //public ModuleInfo LP1ModuleInfo { get; set; }
  548. //public ModuleInfo LP2ModuleInfo { get; set; }
  549. //public ModuleInfo LP3ModuleInfo { get; set; }
  550. //public ModuleInfo AlignerModuleInfo { get; set; }
  551. //public ModuleInfo TMRobotModuleInfo { get; set; }
  552. //public ModuleInfo PM1ModuleInfo { get; set; }
  553. //public ModuleInfo PM2ModuleInfo { get; set; }
  554. //public ModuleInfo PM3ModuleInfo { get; set; }
  555. //public ModuleInfo PM4ModuleInfo { get; set; }
  556. //public ModuleInfo PM5ModuleInfo { get; set; }
  557. //private WaferAssociationInfo _VCEAWaferAssociation;
  558. //public WaferAssociationInfo VCEAWaferAssociation
  559. //{
  560. // get { return _VCEAWaferAssociation; }
  561. // set { _VCEAWaferAssociation = value; }
  562. //}
  563. //private WaferAssociationInfo _VCEBWaferAssociation;
  564. //public WaferAssociationInfo VCEBWaferAssociation
  565. //{
  566. // get { return _VCEBWaferAssociation; }
  567. // set { _VCEBWaferAssociation = value; }
  568. //}
  569. #region PM
  570. [Subscription("PMA.FsmState")]
  571. public string PMAServiceStatus { get; set; }
  572. [Subscription("PMA.RecipeName")]
  573. public string PMARecipeName { get; set; }
  574. [Subscription("PMA.RecipeProcessTime")]
  575. public string PMARecipeElapsedTime { get; set; }
  576. [Subscription("PMA.StepNo")]
  577. public int PMARecipeStepNo { get; set; }
  578. [Subscription("PMA.RecipeStepName")]
  579. public string PMARecipeStepName { get; set; }
  580. [Subscription("PMA.ChamberPressure")]
  581. public double PMAChamberPressure { get; set; }
  582. [Subscription("PMB.FsmState")]
  583. public string PMBServiceStatus { get; set; }
  584. [Subscription("PMB.RecipeName")]
  585. public string PMBRecipeName { get; set; }
  586. [Subscription("PMB.RecipeProcessTime")]
  587. public string PMBRecipeElapsedTime { get; set; }
  588. [Subscription("PMB.StepNo")]
  589. public string PMBRecipeStepNo { get; set; }
  590. [Subscription("PMB.RecipeStepName")]
  591. public string PMBRecipeStepName { get; set; }
  592. [Subscription("PMB.ChamberPressure")]
  593. public double PMBChamberPressure { get; set; }
  594. #endregion PM
  595. public EfemDualViewModel()
  596. {
  597. DisplayName = "EfemDualViewModel";
  598. }
  599. protected override void OnInitialize()
  600. {
  601. base.OnInitialize();
  602. base.InitFOUP();
  603. base.InitLL();
  604. base.InitEFEM();
  605. base.InitAligner();
  606. base.InitPM();
  607. base.InitTM();
  608. //base.InitBuffer();
  609. //VceAModuleInfo = ModuleManager.ModuleInfos[ModuleName.VCEA.ToString()];
  610. //VceBModuleInfo = ModuleManager.ModuleInfos[ModuleName.VCEB.ToString()];
  611. //AlignerAModuleInfo = ModuleManager.ModuleInfos[ModuleName.AlignerA.ToString()];
  612. //AlignerBModuleInfo = ModuleManager.ModuleInfos[ModuleName.AlignerB.ToString()];
  613. //TMRobotModuleInfo = ModuleManager.ModuleInfos[ModuleName.TMRobot.ToString()];
  614. //PM1ModuleInfo = ModuleManager.ModuleInfos[ModuleName.PM1.ToString()];
  615. //PM2ModuleInfo = ModuleManager.ModuleInfos[ModuleName.PM2.ToString()];
  616. //PM3ModuleInfo = ModuleManager.ModuleInfos[ModuleName.PM3.ToString()];
  617. //PM4ModuleInfo = ModuleManager.ModuleInfos[ModuleName.PM4.ToString()];
  618. //PM5ModuleInfo = ModuleManager.ModuleInfos[ModuleName.PM5.ToString()];
  619. StationPosition = new VTMRobotPosition()
  620. {
  621. Rotations = new Dictionary<string, int>()
  622. {
  623. { "ArmA.System", 0},
  624. { "ArmA.PMA", 90},
  625. { "ArmA.PMB", 135},
  626. { "ArmA.PMC", 180},
  627. { "ArmA.PM4", 225},
  628. { "ArmA.PM5", 270},
  629. { "ArmA.PA1", 50},
  630. { "ArmA.PA2", 305},
  631. { "ArmA.VCE1", 128},
  632. { "ArmA.VCEA", 27},
  633. { "ArmA.AlignerA", 27},
  634. { "ArmA.VCE2", 328},
  635. { "ArmA.VCEB", 328},
  636. { "ArmA.AlignerB", 328},
  637. { "ArmB.PMA",-90},
  638. { "ArmB.PMB",-45},
  639. { "ArmB.PMC",0},
  640. { "ArmB.PM4", 45},
  641. { "ArmB.PM5", 90},
  642. { "ArmB.PA1", -153},
  643. { "ArmB.PA2", 148},
  644. { "ArmB.VCE1",-150},
  645. { "ArmB.VCEA", -150},
  646. { "ArmB.AlignerA",-150},
  647. { "ArmB.VCE2", 153},
  648. { "ArmB.VCEB", 153},
  649. { "ArmB.AlignerB", 153},
  650. },
  651. Home = new int[8] { 180, 165, -77, 0, -165, 194, 77, 165 },
  652. Arm1Extend = new int[8] { 100, 180, -12, 80, -180, 340, 12, 20 },
  653. Arm2Extend = new int[8] { 255, 26, -8, -76, -30, 180, 20, 180 },
  654. Arm3Extend = new int[8] { 140, 180, -47, 40, -180, 265, 47, 95 },
  655. Arm4Extend = new int[8] { 255, 26, -8, -76, -30, 180, 20, 180 },
  656. };
  657. }
  658. protected override void OnActivate()
  659. {
  660. base.OnActivate();
  661. _isCycleMode = (bool)QueryDataClient.Instance.Service.GetConfig("System.IsCycleMode");
  662. _isATMMode = (bool)QueryDataClient.Instance.Service.GetConfig("System.IsATMMode");
  663. _isLP1Visibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.LP1.IsInstalled");
  664. _isLP2Visibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.LP2.IsInstalled");
  665. _isLP3Visibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.LP3.IsInstalled");
  666. _isLLAVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.LLA.IsInstalled");
  667. _isLLBVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.LLB.IsInstalled");
  668. _isAlignerVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.Aligner.IsInstalled");
  669. _isPMAVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.PMA.IsInstalled");
  670. _isPMBVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.PMB.IsInstalled");
  671. _isPMCVisibility = (bool)QueryDataClient.Instance.Service.GetConfig("System.SetUp.PMC.IsInstalled");
  672. }
  673. public bool _isLP1Visibility;
  674. public Visibility IsLP1Visibility
  675. {
  676. get { return _isLP1Visibility ? Visibility.Visible : Visibility.Hidden; }
  677. }
  678. public bool _isLP2Visibility;
  679. public Visibility IsLP2Visibility
  680. {
  681. get { return _isLP2Visibility ? Visibility.Visible : Visibility.Hidden; }
  682. }
  683. public bool _isLP3Visibility;
  684. public Visibility IsLP3Visibility
  685. {
  686. get { return _isLP3Visibility ? Visibility.Visible : Visibility.Hidden; }
  687. }
  688. public bool _isPMAVisibility;
  689. public Visibility IsPMAVisibility
  690. {
  691. get { return _isPMAVisibility ? Visibility.Visible : Visibility.Hidden; }
  692. }
  693. public bool _isPMBVisibility;
  694. public Visibility IsPMBVisibility
  695. {
  696. get { return _isPMBVisibility ? Visibility.Visible : Visibility.Hidden; }
  697. }
  698. public bool _isPMCVisibility;
  699. public Visibility IsPMCVisibility
  700. {
  701. get { return _isPMCVisibility ? Visibility.Visible : Visibility.Hidden; }
  702. }
  703. public bool _isLLAVisibility;
  704. public Visibility IsLLAVisibility
  705. {
  706. get { return _isLLAVisibility ? Visibility.Visible : Visibility.Hidden; }
  707. }
  708. public bool _isLLBVisibility;
  709. public Visibility IsLLBVisibility
  710. {
  711. get { return _isLLBVisibility ? Visibility.Visible : Visibility.Hidden; }
  712. }
  713. public bool _isAlignerVisibility;
  714. public Visibility IsAlignerVisibility
  715. {
  716. get { return _isAlignerVisibility ? Visibility.Visible : Visibility.Hidden; }
  717. }
  718. private R_TRIG _lp1JobFinished = new R_TRIG();
  719. private R_TRIG _lp2JobFinished = new R_TRIG();
  720. private R_TRIG _lp3JobFinished = new R_TRIG();
  721. protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
  722. {
  723. if (LP1WaferAssociation == null)
  724. {
  725. LP1WaferAssociation = new WaferAssociationInfo();
  726. LP1WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP1"];
  727. }
  728. if (LP2WaferAssociation == null)
  729. {
  730. LP2WaferAssociation = new WaferAssociationInfo();
  731. LP2WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP2"];
  732. }
  733. if (LP3WaferAssociation == null)
  734. {
  735. LP3WaferAssociation = new WaferAssociationInfo();
  736. LP3WaferAssociation.ModuleData = ModuleManager.ModuleInfos["LP3"];
  737. }
  738. LP1WaferAssociation.JobID = LP1JobName;
  739. LP1WaferAssociation.JobStatus = LP1JobStatus;
  740. if (!string.IsNullOrEmpty(LP1JobName))
  741. LP1WaferAssociation.LotId = LP1JobLotName;
  742. LP2WaferAssociation.JobID = LP2JobName;
  743. LP2WaferAssociation.JobStatus = LP2JobStatus;
  744. if (!string.IsNullOrEmpty(LP2JobName))
  745. LP2WaferAssociation.LotId = LP2JobLotName;
  746. LP3WaferAssociation.JobID = LP3JobName;
  747. LP3WaferAssociation.JobStatus = LP3JobStatus;
  748. if (!string.IsNullOrEmpty(LP3JobName))
  749. LP3WaferAssociation.LotId = LP3JobLotName;
  750. //PM1WaferData = PM1ModuleInfo.WaferManager.Wafers[0];
  751. //PM2WaferData = PM2ModuleInfo.WaferManager.Wafers[0];
  752. //PM3WaferData = PM3ModuleInfo.WaferManager.Wafers[0];
  753. //PM4WaferData = PM4ModuleInfo.WaferManager.Wafers[0];
  754. //PM5WaferData = PM5ModuleInfo.WaferManager.Wafers[0];
  755. //AlignerAWaferData = AlignerAModuleInfo.WaferManager.Wafers[0];
  756. //AlignerBWaferData = AlignerBModuleInfo.WaferManager.Wafers[0];
  757. //TMRobotLowWaferData = TMRobotModuleInfo.WaferManager.Wafers[0];
  758. //TMRobotUpWaferData = TMRobotModuleInfo.WaferManager.Wafers[1];
  759. if (!string.IsNullOrEmpty(LP1JobStatus) && LP1JobStatus == "Executing")
  760. {
  761. var wafers = LP1WaferAssociation.ModuleData.WaferManager.Wafers;
  762. for (int i = 0; i < wafers.Count; i++)
  763. {
  764. wafers[i].SequenceName = LP1CurrentRecipeList[wafers[i].SlotID];
  765. }
  766. }
  767. if (!string.IsNullOrEmpty(LP2JobStatus) && LP2JobStatus == "Executing")
  768. {
  769. var wafers = LP2WaferAssociation.ModuleData.WaferManager.Wafers;
  770. for (int i = 0; i < wafers.Count; i++)
  771. {
  772. wafers[i].SequenceName = LP2CurrentRecipeList[wafers[i].SlotID];
  773. }
  774. }
  775. if (!string.IsNullOrEmpty(LP3JobStatus) && LP3JobStatus == "Executing")
  776. {
  777. var wafers = LP3WaferAssociation.ModuleData.WaferManager.Wafers;
  778. for (int i = 0; i < wafers.Count; i++)
  779. {
  780. wafers[i].SequenceName = LP3CurrentRecipeList[wafers[i].SlotID];
  781. }
  782. }
  783. _lp1JobFinished.CLK = string.IsNullOrEmpty(LP1JobName);
  784. if (_lp1JobFinished.Q)
  785. {
  786. foreach (var wafer in LP1WaferAssociation.ModuleData.WaferManager.Wafers)
  787. {
  788. wafer.SequenceName = "";
  789. }
  790. LP1WaferAssociation.LotId = "";
  791. LP1WaferAssociation.SequenceName = "";
  792. }
  793. _lp2JobFinished.CLK = string.IsNullOrEmpty(LP2JobName);
  794. if (_lp2JobFinished.Q)
  795. {
  796. foreach (var wafer in LP2WaferAssociation.ModuleData.WaferManager.Wafers)
  797. {
  798. wafer.SequenceName = "";
  799. }
  800. LP2WaferAssociation.LotId = "";
  801. LP2WaferAssociation.SequenceName = "";
  802. }
  803. _lp3JobFinished.CLK = string.IsNullOrEmpty(LP3JobName);
  804. if (_lp3JobFinished.Q)
  805. {
  806. foreach (var wafer in LP3WaferAssociation.ModuleData.WaferManager.Wafers)
  807. {
  808. wafer.SequenceName = "";
  809. }
  810. LP3WaferAssociation.LotId = "";
  811. LP3WaferAssociation.SequenceName = "";
  812. }
  813. }
  814. public void Preset()
  815. {
  816. }
  817. public void Clear()
  818. {
  819. }
  820. public void Apply()
  821. {
  822. }
  823. public void HomeAll()
  824. {
  825. InvokeClient.Instance.Service.DoOperation("System.HomeAll");
  826. }
  827. public void Abort()
  828. {
  829. InvokeClient.Instance.Service.DoOperation("System.Abort");
  830. }
  831. public void ReturnWafer()
  832. {
  833. InvokeClient.Instance.Service.DoOperation("System.ReturnAllWafer");
  834. }
  835. public void TMCycleStart()
  836. {
  837. InvokeClient.Instance.Service.DoOperation("System.TMCycleStart");
  838. }
  839. public void Auto()
  840. {
  841. InvokeClient.Instance.Service.DoOperation("System.SetAutoMode");
  842. }
  843. public void Manual()
  844. {
  845. InvokeClient.Instance.Service.DoOperation("System.SetManualMode");
  846. }
  847. public void Load(string loadPortName)
  848. {
  849. InvokeClient.Instance.Service.DoOperation($"{loadPortName}.Load");
  850. }
  851. public void Unload(string loadPortName)
  852. {
  853. InvokeClient.Instance.Service.DoOperation($"{loadPortName}.Unload");
  854. }
  855. public void MapLP(string loadPortName)
  856. {
  857. int efemwafer1 = ModuleManager.ModuleInfos["EfemRobot"].WaferManager.Wafers[0].WaferStatus;
  858. int efemwafer2 = ModuleManager.ModuleInfos["EfemRobot"].WaferManager.Wafers[1].WaferStatus;
  859. if(efemwafer1!=0|| efemwafer2 != 0)
  860. {
  861. DialogBox.ShowWarning("EFEM has wafer!");
  862. return;
  863. }
  864. InvokeClient.Instance.Service.DoOperation($"{ModuleName.EFEM}.Map", loadPortName);
  865. }
  866. #region Wafer association
  867. #region Sequence operation
  868. public void SelectSequence(WaferAssociationInfo info)
  869. {
  870. SequenceDialogViewModel dialog = new SequenceDialogViewModel();
  871. dialog.DisplayName = "Select Sequence";
  872. dialog.Files = new ObservableCollection<FileNode>(RecipeSequenceTreeBuilder.GetFiles("",
  873. RecipeClient.Instance.Service.GetSequenceNameList()
  874. ));
  875. WindowManager wm = new WindowManager();
  876. bool? bret = wm.ShowDialog(dialog);
  877. if ((bool)bret)
  878. {
  879. info.SequenceName = dialog.DialogResult;
  880. }
  881. }
  882. public void SetSlot(WaferAssociationInfo info)
  883. {
  884. if (InputSlotCheck(info.SlotFrom, info.SlotTo))
  885. AssociateSequence(info, true);
  886. }
  887. public void SkipSlot(WaferAssociationInfo info)
  888. {
  889. if (InputSlotCheck(info.SlotFrom, info.SlotTo))
  890. AssociateSequence(info, false);
  891. }
  892. public void SetAll(WaferAssociationInfo info)
  893. {
  894. info.SlotFrom = 1;
  895. info.SlotTo = 25;
  896. AssociateSequence(info, true);
  897. }
  898. public void DeselectAll(WaferAssociationInfo info)
  899. {
  900. info.SlotFrom = 1;
  901. info.SlotTo = 25;
  902. AssociateSequence(info, false);
  903. }
  904. public void SetSequence(WaferAssociationInfo info, int slotIndex, string seqName)
  905. {
  906. bool flag = string.IsNullOrEmpty(seqName);
  907. AssociateSequence(info, flag, slotIndex - 1);
  908. }
  909. private bool InputSlotCheck(int from, int to)
  910. {
  911. if (from > to)
  912. {
  913. DialogBox.ShowInfo("This index of from slot should be large than the index of to slot.");
  914. return false;
  915. }
  916. if (from < 1 || to > 25)
  917. {
  918. DialogBox.ShowInfo("This input value for from should be between 1 and 25.");
  919. return false;
  920. }
  921. return true;
  922. }
  923. private void AssociateSequence(WaferAssociationInfo info, bool flag, int slot = -1)
  924. {
  925. ObservableCollection<WaferInfo> wafers = info.ModuleData.WaferManager.Wafers;
  926. if (slot >= 0) //by wafer
  927. {
  928. int index = wafers.Count - slot - 1;
  929. if (index < wafers.Count)
  930. {
  931. if (flag && HasWaferOnSlot(wafers.ToList(), index))
  932. wafers[index].SequenceName = info.SequenceName;
  933. else
  934. wafers[index].SequenceName = string.Empty;
  935. }
  936. }
  937. else //by from-to
  938. {
  939. for (int i = info.SlotFrom - 1; i < info.SlotTo; i++)
  940. {
  941. int index = wafers.Count - i - 1;
  942. if (index < wafers.Count)
  943. {
  944. if (flag && HasWaferOnSlot(wafers.ToList(), index))
  945. wafers[index].SequenceName = info.SequenceName;
  946. else
  947. wafers[index].SequenceName = string.Empty;
  948. }
  949. }
  950. }
  951. }
  952. private bool HasWaferOnSlot(List<WaferInfo> wafers, int index)
  953. {
  954. if (wafers[index].WaferStatus == 0)
  955. return false;
  956. return true;
  957. }
  958. #endregion
  959. #region Job operation
  960. private bool JobCheck(string jobID)
  961. {
  962. if (jobID.Length == 0)
  963. {
  964. DialogBox.ShowWarning("Please create job first.");
  965. return false;
  966. }
  967. else
  968. return true;
  969. }
  970. public void CreateJob(WaferAssociationInfo info)
  971. {
  972. List<string> slotSequence = new List<string>();
  973. foreach (var wafer in info.ModuleData.WaferManager.Wafers)
  974. {
  975. slotSequence.Insert(0, wafer.SequenceName);
  976. }
  977. string jobId = info.LotId.Trim();
  978. if (string.IsNullOrEmpty(jobId))
  979. jobId = "CJ_Local_" + info.ModuleData.ModuleID;
  980. //info.LotId = "test";
  981. info.LotIdSaved = true;
  982. WaferAssociationProvider.Instance.CreateJob(jobId, info.ModuleData.ModuleID, slotSequence, true);
  983. }
  984. public void AbortJob(string jobID)
  985. {
  986. if (JobCheck(jobID))
  987. WaferAssociationProvider.Instance.AbortJob(jobID);
  988. }
  989. public void Start(string jobID)
  990. {
  991. if (JobCheck(jobID))
  992. WaferAssociationProvider.Instance.Start(jobID);
  993. }
  994. public void Pause(string jobID)
  995. {
  996. if (JobCheck(jobID))
  997. WaferAssociationProvider.Instance.Pause(jobID);
  998. }
  999. public void Resume(string jobID)
  1000. {
  1001. if (JobCheck(jobID))
  1002. WaferAssociationProvider.Instance.Resume(jobID);
  1003. }
  1004. public void Stop(string jobID)
  1005. {
  1006. if (JobCheck(jobID))
  1007. WaferAssociationProvider.Instance.Stop(jobID);
  1008. }
  1009. #endregion
  1010. #endregion
  1011. }
  1012. }