Loadport.cs 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.OperationCenter;
  5. using Aitex.Core.RT.SCCore;
  6. using Aitex.Core.Util;
  7. using Aitex.Sorter.Common;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.SubstrateTrackings;
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.Diagnostics;
  14. using Venus_Core;
  15. using Venus_RT.Devices.YASKAWA;
  16. using Venus_RT.HostWrapper;
  17. using Venus_RT.Modules;
  18. namespace Venus_RT.Devices.EFEM
  19. {
  20. sealed class Loadport : ILoadport
  21. {
  22. private readonly EfemBase _controller;
  23. //---------------------------------Properties------------------------------------
  24. //
  25. public OnlineFlag OnlineFlag { get; set; }
  26. public ModuleName Module { get; set; }
  27. public DeviceState Status { get; set; }
  28. public WaferSize WaferSize { get; set; }
  29. public WaferStatus[] WaferInfo { get; set; }
  30. public bool HasCassette { get; set; }
  31. public bool Protrusion { get; set; }
  32. public bool IsMapped { get; set; }
  33. public bool JobDone { get; set; }
  34. public Stopwatch TimerNotifyJobDone { get; set; }
  35. public bool IsThicknessValid
  36. {
  37. get
  38. {
  39. return !_enableThickness || !string.IsNullOrEmpty(_waferThicknessType);
  40. }
  41. }
  42. public string ThicknessType
  43. {
  44. get
  45. {
  46. return _waferThicknessType;
  47. }
  48. }
  49. public bool IsClamped { get; set; }
  50. public bool IsLoaded { get; set; }
  51. public bool IsDocked { get; set; }
  52. public string CarrierId { get; set; }
  53. public string SmartTag { get; set; }
  54. public string LotId { get; set; }
  55. public bool IsBusy { get; set; }
  56. public bool IsError { get; set; }
  57. private string[] _slotMap = new string[25];
  58. public string SlotMap
  59. {
  60. get
  61. {
  62. if (_slotMap == null)
  63. {
  64. _slotMap = new string[SC.GetValue<int>("EFEM.LoadPort.SlotNumber")];
  65. }
  66. for (int i = 0; i < _slotMap.Length; i++)
  67. {
  68. _slotMap[i] = ((int)WaferManager.Instance.GetWafer(Module, i).Status).ToString();
  69. }
  70. return string.Join("", _slotMap);
  71. }
  72. }
  73. private string Port1CassetteArrive = "Port1CassetteArrive";
  74. private string Port1CassetteRemoved = "Port1CassetteRemoved";
  75. private string Port1MappingComplete = "Port1MappingComplete";
  76. private string Port1MappingFailed = "Port1MappingFailed";
  77. private string Port2CassetteArrive = "Port2CassetteArrive";
  78. private string Port2CassetteRemoved = "Port2CassetteRemoved";
  79. private string Port2MappingComplete = "Port2MappingComplete";
  80. private string Port2MappingFailed = "Port2MappingFailed";
  81. private string _waferThicknessType;
  82. private bool _enableThickness;
  83. private string AlarmWaferProtrude = "WaferProtrude";
  84. private LoadPortFACallback _faCallback = new LoadPortFACallback();
  85. // Constructor
  86. //
  87. public Loadport(ModuleName mod, EfemBase efem)
  88. {
  89. Module = mod;
  90. _controller = efem;
  91. TimerNotifyJobDone = new Stopwatch();
  92. _enableThickness = false;// SC.GetValue<bool>("System.WaferThickness.EnableThickness");
  93. EV.Subscribe(new EventItem("Event", Port1CassetteArrive, "Port1CassetteArrive"));
  94. EV.Subscribe(new EventItem("Event", Port1CassetteRemoved, "Port1CassetteRemoved"));
  95. EV.Subscribe(new EventItem("Event", Port1MappingComplete, "Port1MappingComplete"));
  96. EV.Subscribe(new EventItem("Event", Port1MappingFailed, "Port1MappingFailed"));
  97. EV.Subscribe(new EventItem("Event", Port2CassetteArrive, "Port2CassetteArrive"));
  98. EV.Subscribe(new EventItem("Event", Port2CassetteRemoved, "Port2CassetteRemoved"));
  99. EV.Subscribe(new EventItem("Event", Port2MappingComplete, "Port2MappingComplete"));
  100. EV.Subscribe(new EventItem("Event", Port2MappingFailed, "Port2MappingFailed"));
  101. EV.Subscribe(new EventItem("Event", AlarmWaferProtrude, "Wafer protrude", EventLevel.Alarm, EventType.HostNotification));
  102. DATA.Subscribe($"{mod}.WaferSize", () => WaferSize.ToString());
  103. DATA.Subscribe($"{mod}.CassetteState", () => HasCassette ? LoadportCassetteState.Normal : LoadportCassetteState.Absent);
  104. DATA.Subscribe($"{mod}.CassettePresent", () => HasCassette ? 1 : 0);
  105. DATA.Subscribe($"{mod}.CassettePlaced", () => HasCassette);
  106. DATA.Subscribe($"{mod}.SlotMap", () => SlotMap);
  107. DATA.Subscribe($"{mod}.IsWaferProtrude", () => Protrusion ? 1 : 0);
  108. DATA.Subscribe($"{mod}.IsMapped", () => IsMapped);
  109. DATA.Subscribe($"{mod}.IsLoaded", () => IsLoaded);
  110. DATA.Subscribe($"{mod}.IsClamped", () => IsClamped);
  111. DATA.Subscribe($"{mod}.IsDocked", () => IsDocked);
  112. DATA.Subscribe($"{mod}.CarrierId", () => CarrierId);
  113. DATA.Subscribe($"{mod}.SmartTag", () => SmartTag);
  114. DATA.Subscribe($"{Module}.WaferThicknessType", () => _waferThicknessType);
  115. OP.Subscribe($"{Module}.SetThick", (cmd, args) => { SetThick(); return true; });
  116. OP.Subscribe($"{Module}.SetThin", (cmd, args) => { SetThin(); return true; });
  117. }
  118. // Methods
  119. //
  120. public void OnError()
  121. {
  122. IsError = true;
  123. IsBusy = false;
  124. }
  125. public void SetThick()
  126. {
  127. _waferThicknessType = "Thick";
  128. SC.SetItemValue($"System.WaferThickness.{Module}WaferThicknessType", _waferThicknessType);
  129. _controller.SetThickness(Module, _waferThicknessType);
  130. }
  131. public void SetThin()
  132. {
  133. _waferThicknessType = "Thin";
  134. SC.SetItemValue($"System.WaferThickness.{Module}WaferThicknessType", _waferThicknessType);
  135. _controller.SetThickness(Module, _waferThicknessType);
  136. }
  137. #region Home
  138. public void Home()
  139. {
  140. if (IsBusy)
  141. {
  142. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not home");
  143. return;
  144. }
  145. IsBusy = true;
  146. _controller.Home(Module);
  147. }
  148. public void NoteJobStart()
  149. {
  150. JobDone = false;
  151. }
  152. public void NoteJobComplete()
  153. {
  154. TimerNotifyJobDone.Restart();
  155. JobDone = true;
  156. }
  157. public void OnHomeFailed(string data)
  158. {
  159. IsError = true;
  160. IsBusy = false;
  161. }
  162. public void OnHomed()
  163. {
  164. IsError = false;
  165. IsBusy = false;
  166. IsClamped = false;
  167. IsLoaded = false;
  168. IsMapped = false;
  169. IsDocked = false;
  170. }
  171. #endregion
  172. #region Load
  173. public void Load()
  174. {
  175. if (IsLoaded)
  176. {
  177. EV.PostWarningLog(Module.ToString(), $"{Module} is loaded, can not load");
  178. return;
  179. }
  180. if (IsBusy)
  181. {
  182. EV.PostInfoLog(Module.ToString(), $"{Module} is busy, can not load");
  183. return;
  184. }
  185. if (IsError)
  186. {
  187. EV.PostInfoLog(Module.ToString(), $"{Module} is error, can not load");
  188. return;
  189. }
  190. IsBusy = true;
  191. _controller.Load(Module);
  192. }
  193. public void OnLoadFailed(string data)
  194. {
  195. IsError = true;
  196. IsBusy = false;
  197. _faCallback.LoadFailed(this);
  198. }
  199. public void OnLoaded()
  200. {
  201. IsError = false;
  202. IsBusy = false;
  203. IsLoaded = true;
  204. IsMapped = true;
  205. _faCallback.LoadComplete(this);
  206. }
  207. #endregion
  208. #region unload
  209. public void Unload()
  210. {
  211. if (!IsLoaded)
  212. {
  213. EV.PostWarningLog(Module.ToString(), $"{Module} is not loaded, can not unload");
  214. return;
  215. }
  216. if (IsBusy)
  217. {
  218. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not unload");
  219. return;
  220. }
  221. if (IsError)
  222. {
  223. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not unload");
  224. return;
  225. }
  226. IsBusy = true;
  227. _controller.Unload(Module);
  228. }
  229. public void OnUnloadFailed(string data)
  230. {
  231. IsError = true;
  232. IsBusy = false;
  233. _faCallback.UnloadFailed(this);
  234. }
  235. public void OnUnloaded()
  236. {
  237. IsBusy = false;
  238. IsError = false;
  239. IsLoaded = false;
  240. IsMapped = false;
  241. if (SC.GetValue<bool>("EFEM.AutoUnlockAfterUnload"))
  242. {
  243. _faCallback.UnloadComplete(this);
  244. }
  245. else
  246. {
  247. }
  248. }
  249. #endregion
  250. #region Dock
  251. public void Dock()
  252. {
  253. if (IsBusy)
  254. {
  255. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not dock");
  256. return;
  257. }
  258. if (IsError)
  259. {
  260. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not dock");
  261. return;
  262. }
  263. IsBusy = true;
  264. _controller.Dock(Module);
  265. }
  266. public void OnDocked()
  267. {
  268. IsBusy = false;
  269. IsError = false;
  270. IsDocked = true;
  271. }
  272. public void OnDockFailed(string data)
  273. {
  274. IsError = true;
  275. IsBusy = false;
  276. }
  277. #endregion
  278. #region Undock
  279. public void Undock()
  280. {
  281. if (IsBusy)
  282. {
  283. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not undock");
  284. return;
  285. }
  286. if (IsError)
  287. {
  288. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not undock");
  289. return;
  290. }
  291. IsBusy = true;
  292. _controller.Undock(Module);
  293. }
  294. public void OnUndocked()
  295. {
  296. IsBusy = false;
  297. IsError = false;
  298. IsDocked = false;
  299. }
  300. public void OnUndockFailed(string data)
  301. {
  302. IsError = true;
  303. IsBusy = false;
  304. }
  305. #endregion
  306. #region Clamp
  307. public void Clamp(bool isUnloadClamp)
  308. {
  309. if (IsBusy)
  310. {
  311. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not clamp");
  312. return;
  313. }
  314. if (IsError)
  315. {
  316. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not clamp");
  317. return;
  318. }
  319. IsBusy = true;
  320. _controller.Clamp(Module, isUnloadClamp);
  321. }
  322. public void OnClamped(bool isUnloadClamp)
  323. {
  324. IsBusy = false;
  325. IsError = false;
  326. IsClamped = true;
  327. if (isUnloadClamp)
  328. {
  329. _faCallback.UnloadComplete(this);
  330. }
  331. else
  332. {
  333. _faCallback.Clamped(this);
  334. }
  335. }
  336. public void OnClampFailed(string data)
  337. {
  338. IsError = true;
  339. IsBusy = false;
  340. }
  341. #endregion
  342. #region Unclamp
  343. public void Unclamp()
  344. {
  345. if (IsBusy)
  346. {
  347. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not unclamp");
  348. return;
  349. }
  350. if (IsError)
  351. {
  352. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not unclamp");
  353. return;
  354. }
  355. IsBusy = true;
  356. _controller.Unclamp(Module);
  357. }
  358. public void OnUnclamped()
  359. {
  360. IsBusy = false;
  361. IsError = false;
  362. IsClamped = false;
  363. _faCallback.Unclamped(this);
  364. }
  365. public void OnUnclampFailed(string data)
  366. {
  367. }
  368. #endregion
  369. #region map
  370. public void Map()
  371. {
  372. _controller.Map(Module);
  373. }
  374. #endregion
  375. #region carrierID
  376. public void ReadCarrierID()
  377. {
  378. if (IsBusy)
  379. {
  380. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not read carrier ID");
  381. return;
  382. }
  383. if (IsError)
  384. {
  385. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not read carrier ID");
  386. return;
  387. }
  388. IsBusy = true;
  389. _controller.ReadCarrierId(Module);
  390. }
  391. public void OnCarrierIDRead(string data)
  392. {
  393. IsBusy = false;
  394. IsError = false;
  395. //Regex rg = new Regex("(?<=(" + "LOT :" + "))[.\\s\\S]*?(?=(" + "QTY :" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  396. //string carrierID = rg.Match(data).Value.Replace(":", "").Trim();
  397. //data =
  398. // "CST:C082259 TYPE:CST25_AU LOT:AF2403 QTY:24 FLOW:033000 STATUS:HOLD PRI:3-1 PD:0418A CSRLOT: CLEAN:2021/11/14 19:57:50 EQPGRP:DUMMY STAGE:CP-TEST1 RECIPE:DUMMY EMP:N ";
  399. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  400. CarrierId = "";
  401. foreach (var item in items)
  402. {
  403. if (item.StartsWith("CST:") && item.Length > 4)
  404. CarrierId = item.Substring(4).Trim();
  405. if (item.StartsWith("LOT:") && item.Length > 4)
  406. LotId = item.Substring(4).Trim();
  407. }
  408. if (string.IsNullOrEmpty(CarrierId))
  409. {
  410. CarrierId = data;
  411. }
  412. SmartTag = data;
  413. _faCallback.IDRead(this);
  414. }
  415. public void OnCarrierIDReadFailed(string data)
  416. {
  417. IsError = true;
  418. IsBusy = false;
  419. _faCallback.ReadIDFailed(this);
  420. }
  421. public void WriteCarrierID(string id)
  422. {
  423. if (IsBusy)
  424. {
  425. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not write carrier ID");
  426. return;
  427. }
  428. if (IsError)
  429. {
  430. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not write carrier ID");
  431. return;
  432. }
  433. IsBusy = true;
  434. _controller.WriteCarrierId(Module, id);
  435. }
  436. public void OnCarrierIDWrite(string data)
  437. {
  438. IsBusy = false;
  439. IsError = false;
  440. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  441. CarrierId = "";
  442. foreach (var item in items)
  443. {
  444. if (item.StartsWith("CST:") && item.Length > 4)
  445. CarrierId = item.Substring(4);
  446. }
  447. if (string.IsNullOrEmpty(CarrierId))
  448. {
  449. CarrierId = data;
  450. }
  451. SmartTag = data;
  452. _faCallback.IDWrite(this);
  453. }
  454. public void OnCarrierIDWriteFailed(string data)
  455. {
  456. IsError = true;
  457. IsBusy = false;
  458. _faCallback.WriteIDFailed(this);
  459. }
  460. #endregion
  461. #region event
  462. public void HandleEvent(EfemEventArgs eArg)
  463. {
  464. switch (eArg.CommandType)
  465. {
  466. case EfemOperation.GetWaferInfo:
  467. string sWaferInfo = eArg.DataList[0];
  468. bool resultNormal = true;
  469. for (byte index = 0; index < sWaferInfo.Length; index++)
  470. {
  471. int waferState = int.Parse(sWaferInfo.Substring(index, 1));
  472. //合理的映射到内部支持的叠片/交叉片
  473. if (waferState >= 7) waferState = 7;
  474. else if (waferState >= 2) waferState = 3;
  475. WaferStatus st = (WaferStatus)waferState;
  476. WaferManager.Instance.UpdateWaferSize(this.Module, index, WaferSize);
  477. if (st != WaferStatus.Empty)
  478. {
  479. WaferManager.Instance.CreateWafer(this.Module, index, st);
  480. if (st == WaferStatus.Normal)
  481. {
  482. //EV.PostInfoLog(this.Module.ToString(), $"Found Wafer on Slot {index + 1} {WaferSize}");
  483. }
  484. else
  485. {
  486. resultNormal = false;
  487. //EV.PostAlarmLog(this.Module.ToString(), $"Found {st} Wafer on Slot {index + 1} {WaferSize}");
  488. }
  489. }
  490. }
  491. var dvidMap = new SerializableDictionary<string, string>();
  492. dvidMap[DVIDName.SlotMap] = sWaferInfo;
  493. dvidMap[DVIDName.PortID] = Module == ModuleName.LP1 ? "1" : "2";
  494. if (resultNormal)
  495. {
  496. //EV.Notify(Module == ModuleName.LP1 ? Port1MappingComplete : Port2MappingComplete, dvidMap);
  497. }
  498. else
  499. {
  500. //EV.Notify(Module == ModuleName.LP1 ? Port1MappingFailed : Port2MappingFailed, dvidMap);
  501. //EV.PostAlarmLog(Module == ModuleName.LP1 ? "Port1" : "Port2", " MappingFailed");
  502. }
  503. this.IsMapped = true;
  504. break;
  505. case EfemOperation.SigStatus:
  506. // EVT: SIGSTAT/P2/00000381/00000000;
  507. string sParam = eArg.DataList[0];
  508. ModuleName mod = sParam.ToModule();
  509. if (!ModuleHelper.IsLoadPort(mod))
  510. return;
  511. // DATA1 & DATA2
  512. int nData1 = Convert.ToInt32(eArg.DataList[1], 16);
  513. int nData2 = Convert.ToInt32(eArg.DataList[2], 16);
  514. BitArray baData1 = new BitArray(new int[] { nData1 });
  515. BitArray baData2 = new BitArray(new int[] { nData2 });
  516. // wafer size
  517. this.WaferSize = !baData1[6] ? WaferSize.WS3 :
  518. !baData1[7] ? WaferSize.WS4 :
  519. !baData1[8] ? WaferSize.WS6 : WaferSize.WS0;
  520. // placement & present
  521. bool bPlacement = baData1[0]; // bit 0
  522. bool bPresence = !baData1[1]; // bit 1
  523. bool bArrived = bPlacement && bPresence;
  524. if (HasCassette)
  525. {
  526. if (!bArrived)
  527. {
  528. this.HasCassette = false;
  529. this.IsMapped = false;
  530. //EV.PostInfoLog(mod.ToString(), "Cassette removed");
  531. OP.DoOperation("System.CassetteLeave"); //For unload light control off afer job done
  532. CarrierManager.Instance.DeleteCarrier(Module.ToString());
  533. WaferManager.Instance.DeleteWafer(this.Module, 0, 25);
  534. SerializableDictionary<string, string> dvid = new SerializableDictionary<string, string>();
  535. dvid["PortID"] = mod == ModuleName.LP1 ? "1" : "2";
  536. EV.Notify(mod == ModuleName.LP1 ? Port1CassetteRemoved : Port2CassetteRemoved, dvid);
  537. JobDone = false;
  538. _waferThicknessType = "";
  539. }
  540. }
  541. else
  542. {
  543. if (bArrived)
  544. {
  545. this.HasCassette = true;
  546. CarrierManager.Instance.CreateCarrier(Module.ToString());
  547. EV.PostInfoLog(mod.ToString(), $"Cassette {WaferSize} arrived");
  548. //var dvid1 = new SerializableDictionary<string, string>();
  549. //dvid1["PortID"] = mod == ModuleName.LP1 ? "1" : "2";
  550. //EV.Notify(mod == ModuleName.LP1 ? Port1CassetteArrive : Port2CassetteArrive, dvid1);
  551. JobDone = false;
  552. _waferThicknessType = "";
  553. }
  554. }
  555. this.Protrusion = !baData1[9];
  556. if (Protrusion)
  557. {
  558. //EV.PostAlarmLog(Module.ToString(), "发现 wafer 突出");
  559. //EV.Notify(AlarmWaferProtrude);
  560. Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
  561. }
  562. // DATA2, loadport上面的LED 灯, 暂时不需要用到
  563. break;
  564. default:
  565. break;
  566. }
  567. }
  568. #endregion
  569. #region TagData
  570. public void ReadTagData()
  571. {
  572. if (IsBusy)
  573. {
  574. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not read tag data");
  575. return;
  576. }
  577. if (IsError)
  578. {
  579. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not read tag data");
  580. return;
  581. }
  582. IsBusy = true;
  583. _controller.ReadTagData(Module);
  584. }
  585. public void OnTagDataRead(string data)
  586. {
  587. IsBusy = false;
  588. IsError = false;
  589. //Regex rg = new Regex("(?<=(" + "LOT :" + "))[.\\s\\S]*?(?=(" + "QTY :" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  590. //string carrierID = rg.Match(data).Value.Replace(":", "").Trim();
  591. //data =
  592. // "CST:C082259 TYPE:CST25_AU LOT:AF2403 QTY:24 FLOW:033000 STATUS:HOLD PRI:3-1 PD:0418A CSRLOT: CLEAN:2021/11/14 19:57:50 EQPGRP:DUMMY STAGE:CP-TEST1 RECIPE:DUMMY EMP:N ";
  593. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  594. CarrierId = "";
  595. foreach (var item in items)
  596. {
  597. if (item.StartsWith("CST:") && item.Length > 4)
  598. CarrierId = item.Substring(4);
  599. if (item.StartsWith("LOT:") && item.Length > 4)
  600. LotId = item.Substring(4).Trim();
  601. }
  602. if (string.IsNullOrEmpty(CarrierId))
  603. {
  604. CarrierId = data;
  605. }
  606. SmartTag = data;
  607. _faCallback.TagDataRead(this);
  608. }
  609. public void OnTagDataReadFailed(string data)
  610. {
  611. IsError = true;
  612. IsBusy = false;
  613. _faCallback.ReadTagDataFailed(this);
  614. }
  615. public void WriteTagData(string tagData)
  616. {
  617. if (IsBusy)
  618. {
  619. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not write tag data");
  620. return;
  621. }
  622. if (IsError)
  623. {
  624. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not write tag data");
  625. return;
  626. }
  627. IsBusy = true;
  628. _controller.WriteTagData(Module, tagData);
  629. }
  630. public void OnTagDataWrite(string data)
  631. {
  632. IsBusy = false;
  633. IsError = false;
  634. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  635. CarrierId = "";
  636. foreach (var item in items)
  637. {
  638. if (item.StartsWith("CST:") && item.Length > 4)
  639. CarrierId = item.Substring(4);
  640. }
  641. if (string.IsNullOrEmpty(CarrierId))
  642. {
  643. CarrierId = data;
  644. }
  645. SmartTag = data;
  646. _faCallback.TagDataWrite(this);
  647. }
  648. public void OnTagDataWriteFailed(string data)
  649. {
  650. IsError = true;
  651. IsBusy = false;
  652. _faCallback.WriteTagDataFailed( this);
  653. }
  654. #endregion
  655. public void SetOnline(bool online)
  656. {
  657. OnlineFlag = online ? OnlineFlag.Online : OnlineFlag.Offline;
  658. }
  659. sealed class LoadPortFACallback
  660. {
  661. private const string Port1LoadComplete = "Port1LoadComplete";
  662. private const string Port1LoadFailed = "Port1LoadFailed";
  663. private const string Port1UnloadComplete = "Port1UnloadComplete";
  664. private const string Port1UnloadFailed = "Port1UnloadFailed";
  665. private const string Port1Clamped = "Port1Clamped";
  666. private const string Port1Unclamped = "Port1Unclamped";
  667. private const string Port1IDRead = "Port1IDRead";
  668. private const string Port1ReadIDFailed = "Port1ReadIDFailed";
  669. private const string Port1IDWrite = "Port1IDWrite";
  670. private const string Port1WriteIDFailed = "Port1WriteIDFailed";
  671. private const string Port1TagDataRead = "Port1TagDataRead";
  672. private const string Port1ReadTagDataFailed = "Port1ReadTagDataFailed";
  673. private const string Port1TagDataWrite = "Port1TagDataWrite";
  674. private const string Port1WriteTagDataFailed = "Port1WriteTagDataFailed";
  675. private const string Port2LoadComplete = "Port2LoadComplete";
  676. private const string Port2LoadFailed = "Port2LoadFailed";
  677. private const string Port2UnloadComplete = "Port2UnloadComplete";
  678. private const string Port2UnloadFailed = "Port2UnloadFailed";
  679. private const string Port2Clamped = "Port2Clamped";
  680. private const string Port2Unclamped = "Port2Unclamped";
  681. private const string Port2IDRead = "Port2IDRead";
  682. private const string Port2ReadIDFailed = "Port2ReadIDFailed";
  683. private const string Port2IDWrite = "Port2IDWrite";
  684. private const string Port2WriteIDFailed = "Port2WriteIDFailed";
  685. private const string Port2TagDataRead = "Port2TagDataRead";
  686. private const string Port2ReadTagDataFailed = "Port2ReadTagDataFailed";
  687. private const string Port2TagDataWrite = "Port2TagDataWrite";
  688. private const string Port2WriteTagDataFailed = "Port2WriteTagDataFailed";
  689. private Dictionary<ModuleName, string> PortLoadComplete = new Dictionary<ModuleName, string>()
  690. {
  691. {ModuleName.LP1, Port1LoadComplete},
  692. {ModuleName.LP2, Port2LoadComplete},
  693. };
  694. private Dictionary<ModuleName, string> PortLoadFailed = new Dictionary<ModuleName, string>()
  695. {
  696. {ModuleName.LP1, Port1LoadFailed},
  697. {ModuleName.LP2, Port2LoadFailed},
  698. };
  699. private Dictionary<ModuleName, string> PortUnloadComplete = new Dictionary<ModuleName, string>()
  700. {
  701. {ModuleName.LP1, Port1UnloadComplete},
  702. {ModuleName.LP2, Port2UnloadComplete},
  703. };
  704. private Dictionary<ModuleName, string> PortUnloadFailed = new Dictionary<ModuleName, string>()
  705. {
  706. {ModuleName.LP1, Port1UnloadFailed},
  707. {ModuleName.LP2, Port2UnloadFailed},
  708. };
  709. private Dictionary<ModuleName, string> PortClamped = new Dictionary<ModuleName, string>()
  710. {
  711. {ModuleName.LP1, Port1Clamped},
  712. {ModuleName.LP2, Port2Clamped},
  713. };
  714. private Dictionary<ModuleName, string> PortUnclamped = new Dictionary<ModuleName, string>()
  715. {
  716. {ModuleName.LP1, Port1Unclamped},
  717. {ModuleName.LP2, Port2Unclamped},
  718. };
  719. private Dictionary<ModuleName, string> PortIDRead = new Dictionary<ModuleName, string>()
  720. {
  721. {ModuleName.LP1, Port1IDRead},
  722. {ModuleName.LP2, Port2IDRead},
  723. };
  724. private Dictionary<ModuleName, string> PortReadIDFailed = new Dictionary<ModuleName, string>()
  725. {
  726. {ModuleName.LP1, Port1ReadIDFailed},
  727. {ModuleName.LP2, Port2ReadIDFailed},
  728. };
  729. private Dictionary<ModuleName, string> PortIDWrite = new Dictionary<ModuleName, string>()
  730. {
  731. {ModuleName.LP1, Port1IDWrite},
  732. {ModuleName.LP2, Port2IDWrite},
  733. };
  734. private Dictionary<ModuleName, string> PortWriteIDFailed = new Dictionary<ModuleName, string>()
  735. {
  736. {ModuleName.LP1, Port1WriteIDFailed},
  737. {ModuleName.LP2, Port2WriteIDFailed},
  738. };
  739. private Dictionary<ModuleName, string> PortTagDataRead = new Dictionary<ModuleName, string>()
  740. {
  741. {ModuleName.LP1, Port1TagDataRead},
  742. {ModuleName.LP2, Port2TagDataRead},
  743. };
  744. private Dictionary<ModuleName, string> PortReadTagDataFailed = new Dictionary<ModuleName, string>()
  745. {
  746. {ModuleName.LP1, Port1ReadTagDataFailed},
  747. {ModuleName.LP2, Port2ReadTagDataFailed},
  748. };
  749. private Dictionary<ModuleName, string> PortTagDataWrite = new Dictionary<ModuleName, string>()
  750. {
  751. {ModuleName.LP1, Port1TagDataWrite},
  752. {ModuleName.LP2, Port2TagDataWrite},
  753. };
  754. private Dictionary<ModuleName, string> PortWriteTagDataFailed = new Dictionary<ModuleName, string>()
  755. {
  756. {ModuleName.LP1, Port1WriteTagDataFailed},
  757. {ModuleName.LP2, Port2WriteTagDataFailed},
  758. };
  759. private Dictionary<ModuleName, string> PortId = new Dictionary<ModuleName, string>()
  760. {
  761. {ModuleName.LP1, "1"},
  762. {ModuleName.LP2, "2"},
  763. };
  764. public LoadPortFACallback()
  765. {
  766. EV.Subscribe(new EventItem("Event", Port1LoadComplete, Port1LoadComplete));
  767. EV.Subscribe(new EventItem("Event", Port1LoadFailed, Port1LoadFailed));
  768. EV.Subscribe(new EventItem("Event", Port1UnloadComplete, Port1UnloadComplete));
  769. EV.Subscribe(new EventItem("Event", Port1UnloadFailed, Port1UnloadFailed));
  770. EV.Subscribe(new EventItem("Event", Port1Clamped, Port1Clamped));
  771. EV.Subscribe(new EventItem("Event", Port1Unclamped, Port1Unclamped));
  772. EV.Subscribe(new EventItem("Event", Port1IDRead, Port1IDRead));
  773. EV.Subscribe(new EventItem("Event", Port1ReadIDFailed, Port1ReadIDFailed));
  774. EV.Subscribe(new EventItem("Event", Port1IDWrite, Port1IDWrite));
  775. EV.Subscribe(new EventItem("Event", Port1WriteIDFailed, Port1WriteIDFailed));
  776. EV.Subscribe(new EventItem("Event", Port1TagDataRead, Port1TagDataRead));
  777. EV.Subscribe(new EventItem("Event", Port1ReadTagDataFailed, Port1ReadTagDataFailed));
  778. EV.Subscribe(new EventItem("Event", Port1TagDataWrite, Port1TagDataWrite));
  779. EV.Subscribe(new EventItem("Event", Port1WriteTagDataFailed, Port1WriteTagDataFailed));
  780. EV.Subscribe(new EventItem("Event", Port2LoadComplete, Port2LoadComplete));
  781. EV.Subscribe(new EventItem("Event", Port2LoadFailed, Port2LoadFailed));
  782. EV.Subscribe(new EventItem("Event", Port2UnloadComplete, Port2UnloadComplete));
  783. EV.Subscribe(new EventItem("Event", Port2UnloadFailed, Port2UnloadFailed));
  784. EV.Subscribe(new EventItem("Event", Port2Clamped, Port2Clamped));
  785. EV.Subscribe(new EventItem("Event", Port2Unclamped, Port2Unclamped));
  786. EV.Subscribe(new EventItem("Event", Port2IDRead, Port2IDRead));
  787. EV.Subscribe(new EventItem("Event", Port2ReadIDFailed, Port2ReadIDFailed));
  788. EV.Subscribe(new EventItem("Event", Port2IDWrite, Port2IDWrite));
  789. EV.Subscribe(new EventItem("Event", Port2WriteIDFailed, Port2WriteIDFailed));
  790. EV.Subscribe(new EventItem("Event", Port2TagDataRead, Port2TagDataRead));
  791. EV.Subscribe(new EventItem("Event", Port2ReadTagDataFailed, Port2ReadTagDataFailed));
  792. EV.Subscribe(new EventItem("Event", Port2TagDataWrite, Port2TagDataWrite));
  793. EV.Subscribe(new EventItem("Event", Port2WriteTagDataFailed, Port2WriteTagDataFailed));
  794. }
  795. public void LoadComplete(Loadport lp)
  796. {
  797. ModuleName moduleName = lp.Module;
  798. EV.Notify(PortLoadComplete[moduleName], new SerializableDictionary<string, string>()
  799. {
  800. {DVIDName.PortID, PortId[lp.Module] },
  801. });
  802. }
  803. public void LoadFailed(Loadport lp)
  804. {
  805. ModuleName moduleName = lp.Module;
  806. EV.Notify(PortLoadFailed[moduleName], new SerializableDictionary<string, string>()
  807. {
  808. {DVIDName.PortID, PortId[lp.Module] },
  809. });
  810. }
  811. public void UnloadComplete(Loadport lp)
  812. {
  813. ModuleName moduleName = lp.Module;
  814. EV.Notify(PortUnloadComplete[moduleName], new SerializableDictionary<string, string>()
  815. {
  816. {DVIDName.PortID, PortId[lp.Module] },
  817. });
  818. }
  819. public void UnloadFailed(Loadport lp)
  820. {
  821. ModuleName moduleName = lp.Module;
  822. EV.Notify(PortUnloadFailed[moduleName], new SerializableDictionary<string, string>()
  823. {
  824. {DVIDName.PortID, PortId[lp.Module] },
  825. });
  826. }
  827. public void Clamped(Loadport lp)
  828. {
  829. ModuleName moduleName = lp.Module;
  830. EV.Notify(PortClamped[moduleName], new SerializableDictionary<string, string>()
  831. {
  832. {DVIDName.PortID, PortId[lp.Module] },
  833. });
  834. }
  835. public void Unclamped(Loadport lp)
  836. {
  837. ModuleName moduleName = lp.Module;
  838. EV.Notify(PortUnclamped[moduleName], new SerializableDictionary<string, string>()
  839. {
  840. {DVIDName.PortID, PortId[lp.Module] },
  841. });
  842. }
  843. public void IDRead(Loadport lp)
  844. {
  845. ModuleName moduleName = lp.Module;
  846. EV.Notify(PortIDRead[moduleName], new SerializableDictionary<string, string>()
  847. {
  848. {DVIDName.PortID, PortId[lp.Module] },
  849. {DVIDName.CarrierID, lp.CarrierId },
  850. {DVIDName.LotID, lp.LotId },
  851. });
  852. }
  853. public void ReadIDFailed(Loadport lp)
  854. {
  855. ModuleName moduleName = lp.Module;
  856. EV.Notify(PortReadIDFailed[moduleName], new SerializableDictionary<string, string>()
  857. {
  858. {DVIDName.PortID, PortId[lp.Module] },
  859. });
  860. }
  861. public void IDWrite(Loadport lp)
  862. {
  863. ModuleName moduleName = lp.Module;
  864. EV.Notify(PortIDWrite[moduleName], new SerializableDictionary<string, string>()
  865. {
  866. {DVIDName.PortID, PortId[lp.Module] },
  867. {DVIDName.CarrierID, lp.CarrierId },
  868. });
  869. }
  870. public void WriteIDFailed(Loadport lp)
  871. {
  872. ModuleName moduleName = lp.Module;
  873. EV.Notify(PortWriteIDFailed[moduleName], new SerializableDictionary<string, string>()
  874. {
  875. {DVIDName.PortID, PortId[lp.Module] },
  876. });
  877. }
  878. public void TagDataRead(Loadport lp)
  879. {
  880. ModuleName moduleName = lp.Module;
  881. EV.Notify(PortTagDataRead[moduleName], new SerializableDictionary<string, string>()
  882. {
  883. {DVIDName.PortID, PortId[lp.Module] },
  884. {DVIDName.TagData, lp.SmartTag },
  885. {DVIDName.CarrierID, lp.CarrierId },
  886. {DVIDName.LotID, lp.LotId },
  887. });
  888. }
  889. public void ReadTagDataFailed(Loadport lp)
  890. {
  891. ModuleName moduleName = lp.Module;
  892. EV.Notify(PortReadTagDataFailed[moduleName], new SerializableDictionary<string, string>()
  893. {
  894. {DVIDName.PortID, PortId[lp.Module] },
  895. });
  896. }
  897. public void TagDataWrite(Loadport lp)
  898. {
  899. ModuleName moduleName = lp.Module;
  900. EV.Notify(PortTagDataWrite[moduleName], new SerializableDictionary<string, string>()
  901. {
  902. {DVIDName.PortID, PortId[lp.Module] },
  903. {DVIDName.CarrierID, lp.CarrierId },
  904. {DVIDName.TagData, lp.SmartTag },
  905. });
  906. }
  907. public void WriteTagDataFailed(Loadport lp)
  908. {
  909. ModuleName moduleName = lp.Module;
  910. EV.Notify(PortWriteTagDataFailed[moduleName], new SerializableDictionary<string, string>()
  911. {
  912. {DVIDName.PortID, PortId[lp.Module] },
  913. });
  914. }
  915. }
  916. }
  917. }