WaferManager.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows.Forms;
  5. using Aitex.Core.Common;
  6. using Aitex.Core.RT.DataCenter;
  7. using Aitex.Core.RT.Event;
  8. using Aitex.Core.RT.Log;
  9. using Aitex.Core.RT.OperationCenter;
  10. using Aitex.Core.Util;
  11. using MECF.Framework.Common.DBCore;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.Utilities;
  14. namespace MECF.Framework.Common.SubstrateTrackings
  15. {
  16. public class WaferManager : Singleton<WaferManager>
  17. {
  18. Dictionary<string, WaferInfo> _dict = new Dictionary<string, WaferInfo>();
  19. object _lockerWaferList = new object();
  20. Dictionary<ModuleName, Dictionary<int, WaferInfo>> _locationWafers = new Dictionary<ModuleName, Dictionary<int, WaferInfo>>();
  21. private const string EventWaferLeft = "WAFER_LEFT_POSITION";
  22. private const string EventWaferArrive = "WAFER_ARRIVE_POSITION";
  23. public WaferManager()
  24. {
  25. }
  26. public void Serialize()
  27. {
  28. try
  29. {
  30. if (_locationWafers != null)
  31. {
  32. BinarySerializer<Dictionary<ModuleName, Dictionary<int, WaferInfo>>>.ToStream(_locationWafers, "WaferManager");
  33. }
  34. }
  35. catch (Exception ex)
  36. {
  37. LOG.Write(ex);
  38. }
  39. }
  40. public void Deserialize()
  41. {
  42. try
  43. {
  44. var ccc = BinarySerializer<Dictionary<ModuleName, Dictionary<int, WaferInfo>>>.FromStream("WaferManager");
  45. if (ccc != null)
  46. {
  47. foreach (var moduleWafers in ccc)
  48. {
  49. if (ModuleHelper.IsLoadPort(moduleWafers.Key))
  50. {
  51. foreach (var waferInfo in moduleWafers.Value)
  52. {
  53. waferInfo.Value.SetEmpty();
  54. }
  55. }
  56. }
  57. _locationWafers = ccc;
  58. }
  59. }
  60. catch (Exception ex)
  61. {
  62. LOG.Write(ex);
  63. }
  64. }
  65. public void Initialize()
  66. {
  67. EV.Subscribe(new EventItem("Event", EventWaferLeft, "Wafer Left"));
  68. EV.Subscribe(new EventItem("Event", EventWaferArrive, "Wafer Arrived"));
  69. Deserialize();
  70. }
  71. public void SubscribeLocation(string module, int slotNumber)
  72. {
  73. ModuleName mod;
  74. if (Enum.TryParse(module, out mod))
  75. {
  76. SubscribeLocation(mod, slotNumber);
  77. }
  78. else
  79. {
  80. LOG.Write(string.Format("Failed SubscribeLocation, module name invalid, {0} ", module));
  81. }
  82. }
  83. public void SubscribeLocation(ModuleName module, int slotNumber)
  84. {
  85. if (!_locationWafers.ContainsKey(module))
  86. {
  87. _locationWafers[module] = new Dictionary<int, WaferInfo>();
  88. for (int i = 0; i < slotNumber; i++)
  89. {
  90. _locationWafers[module][i] = new WaferInfo();
  91. }
  92. }
  93. DATA.Subscribe(module.ToString(), "ModuleWaferList", () => _locationWafers[module].Values.ToArray());
  94. }
  95. public void WaferMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
  96. {
  97. if (_locationWafers[moduleFrom][slotFrom].IsEmpty)
  98. {
  99. LOG.Write(string.Format("Invalid wafer move, no wafer at source, {0}{1}=>{2}{3}", moduleFrom, slotFrom+1, moduleTo, slotTo+1));
  100. return;
  101. }
  102. if (!_locationWafers[moduleTo][slotTo].IsEmpty)
  103. {
  104. LOG.Write(string.Format("Invalid wafer move, destination has wafer, {0}{1}=>{2}{3}", moduleFrom, slotFrom + 1, moduleTo, slotTo + 1));
  105. return;
  106. }
  107. string waferOrigin = _locationWafers[moduleFrom][slotFrom].WaferOrigin;
  108. WaferInfo wafer = CopyWaferInfo(moduleTo, slotTo, _locationWafers[moduleFrom][slotFrom]);
  109. DeleteWafer(moduleFrom, slotFrom);
  110. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferMoved, waferOrigin, moduleFrom.ToString(), slotFrom + 1, moduleTo.ToString(), slotTo + 1);
  111. WaferMoveHistoryRecorder.WaferMoved(wafer.InnerId.ToString(), moduleTo.ToString(), slotTo, wafer.Status.ToString());
  112. if (ModuleHelper.IsLoadPort(moduleFrom))
  113. {
  114. EV.Notify(EventWaferLeft, new SerializableDictionary<string, string>()
  115. {
  116. {"SLOT_NO", (slotFrom+1).ToString("D2")},
  117. {"WAFER_ID", wafer.WaferID},
  118. {"LOT_ID", wafer.LotId},
  119. { "CAR_ID", CarrierManager.Instance.GetCarrier(moduleFrom.ToString()).CarrierId ?? ""},
  120. { "LEFT_POS_NAME", $"{moduleFrom}.{(slotFrom+1).ToString("D2")}" }
  121. });
  122. }
  123. if (ModuleHelper.IsLoadPort(moduleTo))
  124. {
  125. EV.Notify(EventWaferArrive, new SerializableDictionary<string, string>()
  126. {
  127. {"SLOT_NO", (slotTo+1).ToString("D2")},
  128. {"WAFER_ID", wafer.WaferID},
  129. {"LOT_ID", wafer.LotId},
  130. { "CAR_ID", CarrierManager.Instance.GetCarrier(moduleTo.ToString()).CarrierId ?? ""},
  131. { "ARRIVE_POS_NAME", $"{moduleTo}.{(slotTo+1).ToString("D2")}" }
  132. });
  133. }
  134. Serialize();
  135. }
  136. public bool IsWaferSlotLocationValid(ModuleName module, int slot)
  137. {
  138. return _locationWafers.ContainsKey(module) && _locationWafers[module].ContainsKey(slot);
  139. }
  140. public WaferInfo[] GetWafers(ModuleName module)
  141. {
  142. return _locationWafers[module].Values.ToArray() ;
  143. }
  144. public WaferInfo[] GetWaferByProcessJob(string jobName)
  145. {
  146. List<WaferInfo> wafers = new List<WaferInfo>();
  147. foreach (var moduleWafer in _locationWafers)
  148. {
  149. foreach (var waferInfo in moduleWafer.Value)
  150. {
  151. if (waferInfo.Value!=null && !waferInfo.Value.IsEmpty
  152. && (waferInfo.Value.ProcessJob!=null)
  153. && waferInfo.Value.ProcessJob.Name == jobName)
  154. wafers.Add(waferInfo.Value);
  155. }
  156. }
  157. return wafers.ToArray();
  158. }
  159. public WaferInfo[] GetWafer(string waferID)
  160. {
  161. List<WaferInfo> result = new List<WaferInfo>();
  162. foreach (var locationWafer in _locationWafers)
  163. {
  164. foreach (var wafer in locationWafer.Value)
  165. {
  166. if (wafer.Value.WaferID == waferID)
  167. result.Add(wafer.Value);
  168. }
  169. }
  170. return result.ToArray();
  171. }
  172. public WaferInfo GetWafer(ModuleName module, int slot)
  173. {
  174. return _locationWafers[module][slot];
  175. }
  176. public string GetWaferID(ModuleName module, int slot)
  177. {
  178. return IsWaferSlotLocationValid(module, slot) ? _locationWafers[module][slot].WaferID: "";
  179. }
  180. public bool CheckNoWafer(ModuleName module, int slot)
  181. {
  182. return IsWaferSlotLocationValid(module, slot) && _locationWafers[module][slot].IsEmpty;
  183. }
  184. public bool CheckNoWafer(string module, int slot)
  185. {
  186. return CheckNoWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot);
  187. }
  188. public bool CheckHasWafer(ModuleName module, int slot)
  189. {
  190. return IsWaferSlotLocationValid(module, slot) && !_locationWafers[module][slot].IsEmpty;
  191. }
  192. public bool CheckWaferIsDummy(ModuleName module, int slot)
  193. {
  194. return IsWaferSlotLocationValid(module, slot) && !_locationWafers[module][slot].IsEmpty
  195. && _locationWafers[module][slot].Status == WaferStatus.Dummy;
  196. }
  197. /// <summary>
  198. /// Verify the slot map in string[] format, if there's any mis-match it will return false.
  199. /// </summary>
  200. /// <param name="moduleNo">LP No</param>
  201. /// <param name="flagStrings">Flag input</param>
  202. /// <returns></returns>
  203. public bool CheckWaferExistFlag(string moduleNo, string[] flagStrings, out string reason)
  204. {
  205. var i = 0;
  206. reason = string.Empty;
  207. if (!Enum.TryParse($"LP{moduleNo}", out ModuleName module))
  208. {
  209. reason = "Port Number Error";
  210. return false;
  211. }
  212. foreach (var slot in flagStrings)
  213. {
  214. if (slot == "1")
  215. {
  216. if (IsWaferSlotLocationValid(module, i) && _locationWafers[module][i].IsEmpty)
  217. {
  218. reason = "Flag Mis-Match";
  219. return false;
  220. }
  221. }
  222. else
  223. {
  224. if (IsWaferSlotLocationValid(module, i) && !_locationWafers[module][i].IsEmpty)
  225. {
  226. reason = "Flag Mis-Match";
  227. return false;
  228. }
  229. }
  230. i++;
  231. }
  232. return true;
  233. }
  234. public bool CheckHasWafer(string module, int slot)
  235. {
  236. return CheckHasWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot);
  237. }
  238. public bool CheckWaferFull(ModuleName module)
  239. {
  240. var wafers = _locationWafers[module];
  241. foreach (var waferInfo in wafers)
  242. {
  243. if (waferInfo.Value.IsEmpty)
  244. return false;
  245. }
  246. return true;
  247. }
  248. public bool CheckWaferEmpty(ModuleName module)
  249. {
  250. var wafers = _locationWafers[module];
  251. foreach (var waferInfo in wafers)
  252. {
  253. if (!waferInfo.Value.IsEmpty)
  254. return false;
  255. }
  256. return true;
  257. }
  258. public bool CheckWafer(ModuleName module, int slot, WaferStatus state)
  259. {
  260. if (module==ModuleName.Robot && slot == 2)
  261. {
  262. return IsWaferSlotLocationValid(module, 0) && (_locationWafers[module][0].Status==state)
  263. && IsWaferSlotLocationValid(module, 1) && (_locationWafers[module][1].Status==state);
  264. }
  265. return IsWaferSlotLocationValid(module, slot) && (_locationWafers[module][slot].Status==state);
  266. }
  267. public WaferInfo CreateWafer(ModuleName module, int slot, WaferStatus state)
  268. {
  269. if (!IsWaferSlotLocationValid(module, slot))
  270. {
  271. LOG.Write(string.Format("Invalid wafer create, invalid parameter, {0},{1}", module, slot+1));
  272. return null;
  273. }
  274. string carrierInnerId = "";
  275. string carrierID = string.Empty;
  276. if (ModuleHelper.IsLoadPort(module))
  277. {
  278. CarrierInfo carrier = CarrierManager.Instance.GetCarrier(module.ToString());
  279. if (carrier == null)
  280. {
  281. EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning,
  282. string.Format("No carrier at {0}, can not create wafer", module));
  283. return null;
  284. }
  285. carrierInnerId = carrier.InnerId.ToString();
  286. carrierID = carrier.CarrierId;
  287. }
  288. lock (_lockerWaferList)
  289. {
  290. _locationWafers[module][slot].Status = state;
  291. _locationWafers[module][slot].ProcessState = EnumWaferProcessStatus.Idle;
  292. _locationWafers[module][slot].WaferID = GenerateWaferId(module, slot);
  293. _locationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot);
  294. _locationWafers[module][slot].Station = (int)module;
  295. _locationWafers[module][slot].Slot = slot;
  296. _locationWafers[module][slot].InnerId = Guid.NewGuid();
  297. _locationWafers[module][slot].OriginStation = (int)module;
  298. _locationWafers[module][slot].OriginSlot = slot;
  299. _locationWafers[module][slot].OriginCarrierID = carrierID;
  300. _dict[_locationWafers[module][slot].WaferID] = _locationWafers[module][slot];
  301. }
  302. WaferDataRecorder.CreateWafer(_locationWafers[module][slot].InnerId.ToString(), carrierInnerId, module.ToString(), slot, _locationWafers[module][slot].WaferID);
  303. Serialize();
  304. return _locationWafers[module][slot];
  305. }
  306. public void DeleteWafer(ModuleName module, int slotFrom, int count = 1)
  307. {
  308. lock (_lockerWaferList)
  309. {
  310. for (int i = 0; i < count; i++)
  311. {
  312. int slot = slotFrom+i;
  313. if (!IsWaferSlotLocationValid(module, slot))
  314. {
  315. LOG.Write(string.Format("Invalid wafer delete, invalid parameter, {0},{1}", module, slot + 1));
  316. continue;
  317. }
  318. WaferDataRecorder.DeleteWafer(_locationWafers[module][slot].InnerId.ToString());
  319. _locationWafers[module][slot].SetEmpty();
  320. _dict.Remove(_locationWafers[module][slot].WaferID);
  321. }
  322. }
  323. Serialize();
  324. }
  325. public void UpdateWaferLaser(ModuleName module, int slot, string laserMarker)
  326. {
  327. if (!IsWaferSlotLocationValid(module, slot))
  328. {
  329. LOG.Write(string.Format("Failed UpdateWaferLaser, invalid parameter, {0},{1}", module, slot + 1));
  330. return;
  331. }
  332. lock (_lockerWaferList)
  333. {
  334. _locationWafers[module][slot].LaserMarker = laserMarker;
  335. WaferDataRecorder.SetWaferMarker(_locationWafers[module][slot].InnerId.ToString(), laserMarker);
  336. }
  337. Serialize();
  338. }
  339. public void UpdateWaferT7Code(ModuleName module, int slot, string T7Code)
  340. {
  341. if (!IsWaferSlotLocationValid(module, slot))
  342. {
  343. LOG.Write(string.Format("Failed UpdateWaferT7Code, invalid parameter, {0},{1}", module, slot + 1));
  344. return;
  345. }
  346. lock (_lockerWaferList)
  347. {
  348. _locationWafers[module][slot].T7Code = T7Code;
  349. WaferDataRecorder.SetWaferT7Code(_locationWafers[module][slot].InnerId.ToString(), T7Code);
  350. }
  351. Serialize();
  352. }
  353. public void UpdateWaferTransFlag(ModuleName module, int slot, string flag)
  354. {
  355. if (!IsWaferSlotLocationValid(module, slot))
  356. {
  357. LOG.Write(string.Format("Failed UpdateWaferTransFlag, invalid parameter, {0},{1}", module, slot + 1));
  358. return;
  359. }
  360. lock (_lockerWaferList)
  361. {
  362. _locationWafers[module][slot].TransFlag = flag;
  363. }
  364. Serialize();
  365. }
  366. public void UpdateWaferNotch(ModuleName module, int slot, int angle)
  367. {
  368. if (!IsWaferSlotLocationValid(module, slot))
  369. {
  370. LOG.Write(string.Format("Failed UpdateWaferNotch, invalid parameter, {0},{1}", module, slot + 1));
  371. return;
  372. }
  373. lock (_lockerWaferList)
  374. {
  375. _locationWafers[module][slot].Notch = angle;
  376. }
  377. Serialize();
  378. }
  379. public void UpdateWaferProcessStatus(ModuleName module, int slot, EnumWaferProcessStatus status)
  380. {
  381. if (!IsWaferSlotLocationValid(module, slot))
  382. {
  383. LOG.Write(string.Format("Failed UpdateWaferProcessStatus, invalid parameter, {0},{1}", module, slot + 1));
  384. return;
  385. }
  386. lock (_lockerWaferList)
  387. {
  388. _locationWafers[module][slot].ProcessState = status;
  389. }
  390. Serialize();
  391. }
  392. #pragma warning disable CS0618
  393. public void UpdateWaferProcessStatus(ModuleName module, int slot, ProcessStatus status)
  394. {
  395. switch (status)
  396. {
  397. case ProcessStatus.Busy:
  398. UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.InProcess);
  399. break;
  400. case ProcessStatus.Completed:
  401. UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.Completed);
  402. break;
  403. case ProcessStatus.Failed:
  404. UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.Failed);
  405. break;
  406. case ProcessStatus.Idle:
  407. UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.Idle);
  408. break;
  409. case ProcessStatus.Wait:
  410. UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.InProcess);
  411. break;
  412. }
  413. }
  414. public void UpdateWaferProcessStatus(string waferID, ProcessStatus status)
  415. {
  416. switch (status)
  417. {
  418. case ProcessStatus.Busy:
  419. UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.InProcess);
  420. break;
  421. case ProcessStatus.Completed:
  422. UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.Completed);
  423. break;
  424. case ProcessStatus.Failed:
  425. UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.Failed);
  426. break;
  427. case ProcessStatus.Idle:
  428. UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.Idle);
  429. break;
  430. case ProcessStatus.Wait:
  431. UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.InProcess);
  432. break;
  433. }
  434. }
  435. #pragma warning restore CS0618
  436. public void UpdateWaferId(ModuleName module, int slot, string waferId)
  437. {
  438. if (!IsWaferSlotLocationValid(module, slot))
  439. {
  440. LOG.Write(string.Format("Failed UpdateWaferId, invalid parameter, {0},{1}", module, slot + 1));
  441. return;
  442. }
  443. lock (_lockerWaferList)
  444. {
  445. _locationWafers[module][slot].WaferID = waferId;
  446. }
  447. Serialize();
  448. }
  449. public void UpdateWaferLotId(ModuleName module, int slot, string lotId)
  450. {
  451. if (!IsWaferSlotLocationValid(module, slot))
  452. {
  453. LOG.Write(string.Format("Failed UpdateWaferLotId, invalid parameter, {0},{1}", module, slot + 1));
  454. return;
  455. }
  456. lock (_lockerWaferList)
  457. {
  458. _locationWafers[module][slot].LotId = lotId;
  459. }
  460. Serialize();
  461. }
  462. public void UpdateWaferProcessStatus(string waferID, EnumWaferProcessStatus status)
  463. {
  464. WaferInfo[] wafers = GetWafer(waferID);
  465. lock (_lockerWaferList)
  466. {
  467. foreach (var waferInfo in wafers)
  468. {
  469. waferInfo.ProcessState = status;
  470. }
  471. }
  472. Serialize();
  473. }
  474. public void UpdateWaferProcess(string waferID, string processId)
  475. {
  476. WaferInfo[] wafers = GetWafer(waferID);
  477. lock (_lockerWaferList)
  478. {
  479. foreach (var waferInfo in wafers)
  480. {
  481. WaferDataRecorder.SetProcessInfo(waferInfo.InnerId.ToString(), processId);
  482. }
  483. }
  484. Serialize();
  485. }
  486. public WaferInfo CopyWaferInfo(ModuleName module, int slot, WaferInfo wafer)
  487. {
  488. if (!IsWaferSlotLocationValid(module, slot))
  489. {
  490. LOG.Write(string.Format("Failed CopyWaferInfo, invalid parameter, {0},{1}", module, slot + 1));
  491. return null;
  492. }
  493. lock (_lockerWaferList)
  494. {
  495. _locationWafers[module][slot].Update(wafer);
  496. _locationWafers[module][slot].Station = (int)module;
  497. _locationWafers[module][slot].Slot = slot;
  498. }
  499. return _locationWafers[module][slot];
  500. }
  501. public bool UpdateWaferSize(ModuleName module, int slot, WaferSize size)
  502. {
  503. if (!IsWaferSlotLocationValid(module, slot))
  504. {
  505. LOG.Write(string.Format("Failed UpdateWaferSize, invalid parameter, {0},{1}", module, slot + 1));
  506. return false;
  507. }
  508. lock (_lockerWaferList)
  509. {
  510. _locationWafers[module][slot].Size = size;
  511. }
  512. Serialize();
  513. return true;
  514. }
  515. private string GenerateWaferId(ModuleName module, int slot)
  516. {
  517. int index = 1000;
  518. //5 + 2(unit) + 2(slot) + time(18) + index{5}
  519. return string.Format("{0}{1}{2:D2}{3}{4:D5}", "Wafer", ModuleHelper.GetAbbr(module), slot,
  520. DateTime.Now.ToString("yyyyMMddHHmmssffff"), index);
  521. }
  522. private string GenerateOrigin(ModuleName module, int slot)
  523. {
  524. return string.Format("{0}.{1:D2}", ModuleHelper.GetAbbr(module), slot + 1);
  525. }
  526. }
  527. }