Loadport.cs 29 KB

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