Loadport.cs 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  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. _faCallback.UnloadComplete(this);
  263. }
  264. }
  265. #endregion
  266. #region Dock
  267. public void Dock()
  268. {
  269. if (IsBusy)
  270. {
  271. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not dock");
  272. return;
  273. }
  274. if (IsError)
  275. {
  276. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not dock");
  277. return;
  278. }
  279. IsBusy = true;
  280. _controller.Dock(Module);
  281. }
  282. public void OnDocked()
  283. {
  284. IsBusy = false;
  285. IsError = false;
  286. IsDocked = true;
  287. }
  288. public void OnDockFailed(string data)
  289. {
  290. IsError = true;
  291. IsBusy = false;
  292. }
  293. #endregion
  294. #region Undock
  295. public void Undock()
  296. {
  297. if (IsBusy)
  298. {
  299. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not undock");
  300. return;
  301. }
  302. if (IsError)
  303. {
  304. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not undock");
  305. return;
  306. }
  307. IsBusy = true;
  308. _controller.Undock(Module);
  309. }
  310. public void OnUndocked()
  311. {
  312. IsBusy = false;
  313. IsError = false;
  314. IsDocked = false;
  315. }
  316. public void OnUndockFailed(string data)
  317. {
  318. IsError = true;
  319. IsBusy = false;
  320. }
  321. #endregion
  322. #region Clamp
  323. public void Clamp(bool isUnloadClamp)
  324. {
  325. if (IsBusy)
  326. {
  327. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not clamp");
  328. return;
  329. }
  330. if (IsError)
  331. {
  332. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not clamp");
  333. return;
  334. }
  335. IsBusy = true;
  336. _controller.Clamp(Module, isUnloadClamp);
  337. }
  338. public void OnClamped(bool isUnloadClamp)
  339. {
  340. IsBusy = false;
  341. IsError = false;
  342. IsClamped = true;
  343. if (isUnloadClamp)
  344. {
  345. _faCallback.UnloadComplete(this);
  346. }
  347. else
  348. {
  349. _faCallback.Clamped(this);
  350. }
  351. }
  352. public void OnClampFailed(string data)
  353. {
  354. IsError = true;
  355. IsBusy = false;
  356. }
  357. #endregion
  358. #region Unclamp
  359. public void Unclamp()
  360. {
  361. if (IsBusy)
  362. {
  363. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not unclamp");
  364. return;
  365. }
  366. if (IsError)
  367. {
  368. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not unclamp");
  369. return;
  370. }
  371. IsBusy = true;
  372. _controller.Unclamp(Module);
  373. }
  374. public void OnUnclamped()
  375. {
  376. IsBusy = false;
  377. IsError = false;
  378. IsClamped = false;
  379. _faCallback.Unclamped(this);
  380. }
  381. public void OnUnclampFailed(string data)
  382. {
  383. }
  384. #endregion
  385. #region map
  386. public void Map()
  387. {
  388. _controller.Map(Module);
  389. }
  390. #endregion
  391. #region carrierID
  392. public void ReadCarrierID()
  393. {
  394. if (IsBusy)
  395. {
  396. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not read carrier ID");
  397. return;
  398. }
  399. if (IsError)
  400. {
  401. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not read carrier ID");
  402. return;
  403. }
  404. IsBusy = true;
  405. _controller.ReadCarrierId(Module);
  406. }
  407. public void OnCarrierIDRead(string data)
  408. {
  409. IsBusy = false;
  410. IsError = false;
  411. //Regex rg = new Regex("(?<=(" + "LOT :" + "))[.\\s\\S]*?(?=(" + "QTY :" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  412. //string carrierID = rg.Match(data).Value.Replace(":", "").Trim();
  413. //data =
  414. // "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 ";
  415. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  416. CarrierId = "";
  417. foreach (var item in items)
  418. {
  419. if (item.StartsWith("CST:") && item.Length > 4)
  420. CarrierId = item.Substring(4).Trim();
  421. if (item.StartsWith("LOT:") && item.Length > 4)
  422. LotId = item.Substring(4).Trim();
  423. }
  424. if (string.IsNullOrEmpty(CarrierId))
  425. {
  426. CarrierId = data;
  427. }
  428. SmartTag = data;
  429. _faCallback.IDRead(this);
  430. }
  431. public void OnCarrierIDReadFailed(string data)
  432. {
  433. IsError = true;
  434. IsBusy = false;
  435. _faCallback.ReadIDFailed(this);
  436. }
  437. public void WriteCarrierID(string id)
  438. {
  439. if (IsBusy)
  440. {
  441. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not write carrier ID");
  442. return;
  443. }
  444. if (IsError)
  445. {
  446. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not write carrier ID");
  447. return;
  448. }
  449. IsBusy = true;
  450. _controller.WriteCarrierId(Module, id);
  451. }
  452. public void OnCarrierIDWrite(string data)
  453. {
  454. IsBusy = false;
  455. IsError = false;
  456. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  457. CarrierId = "";
  458. foreach (var item in items)
  459. {
  460. if (item.StartsWith("CST:") && item.Length > 4)
  461. CarrierId = item.Substring(4);
  462. }
  463. if (string.IsNullOrEmpty(CarrierId))
  464. {
  465. CarrierId = data;
  466. }
  467. SmartTag = data;
  468. _faCallback.IDWrite(this);
  469. }
  470. public void OnCarrierIDWriteFailed(string data)
  471. {
  472. IsError = true;
  473. IsBusy = false;
  474. _faCallback.WriteIDFailed(this);
  475. }
  476. #endregion
  477. #region event
  478. public void HandleEvent(EfemEventArgs eArg)
  479. {
  480. switch (eArg.CommandType)
  481. {
  482. case EfemOperation.GetWaferInfo:
  483. string sWaferInfo = eArg.DataList[0];
  484. bool resultNormal = true;
  485. for (byte index = 0; index < sWaferInfo.Length; index++)
  486. {
  487. int waferState = int.Parse(sWaferInfo.Substring(index, 1));
  488. //合理的映射到内部支持的叠片/交叉片
  489. if (waferState >= 7) waferState = 7;
  490. else if (waferState >= 2) waferState = 3;
  491. WaferStatus st = (WaferStatus)waferState;
  492. WaferManager.Instance.UpdateWaferSize(this.Module, index, WaferSize);
  493. if (st != WaferStatus.Empty)
  494. {
  495. WaferManager.Instance.CreateWafer(this.Module, index, st);
  496. if (st == WaferStatus.Normal)
  497. {
  498. //EV.PostInfoLog(this.Module.ToString(), $"Found Wafer on Slot {index + 1} {WaferSize}");
  499. }
  500. else
  501. {
  502. resultNormal = false;
  503. }
  504. }
  505. }
  506. if (resultNormal)
  507. {
  508. _faCallback.CarrierSlotMapComplete(this);
  509. }
  510. else
  511. {
  512. _faCallback.CarrierSlotMapFailed(this);
  513. }
  514. this.IsMapped = true;
  515. break;
  516. case EfemOperation.SigStatus:
  517. // EVT: SIGSTAT/P2/00000381/00000000;
  518. string sParam = eArg.DataList[0];
  519. ModuleName mod = sParam.ToModule();
  520. if (!ModuleHelper.IsLoadPort(mod))
  521. return;
  522. // DATA1 & DATA2
  523. int nData1 = Convert.ToInt32(eArg.DataList[1], 16);
  524. int nData2 = Convert.ToInt32(eArg.DataList[2], 16);
  525. BitArray baData1 = new BitArray(new int[] { nData1 });
  526. BitArray baData2 = new BitArray(new int[] { nData2 });
  527. // wafer size
  528. this.WaferSize = !baData1[6] ? WaferSize.WS3 :
  529. !baData1[7] ? WaferSize.WS4 :
  530. !baData1[8] ? WaferSize.WS6 : WaferSize.WS0;
  531. // placement & present
  532. bool bPlacement = baData1[0]; // bit 0
  533. bool bPresence = !baData1[1]; // bit 1
  534. bool bArrived = bPlacement && bPresence;
  535. if (HasCassette)
  536. {
  537. if (!bArrived)
  538. {
  539. this.HasCassette = false;
  540. this.IsMapped = false;
  541. //EV.PostInfoLog(mod.ToString(), "Cassette removed");
  542. OP.DoOperation("System.CassetteLeave"); //For unload light control off afer job done
  543. CarrierManager.Instance.DeleteCarrier(Module.ToString());
  544. WaferManager.Instance.DeleteWafer(this.Module, 0, 25);
  545. _faCallback.CarrierRemoved(this);
  546. JobDone = false;
  547. _waferThicknessType = "";
  548. }
  549. }
  550. else
  551. {
  552. if (bArrived)
  553. {
  554. this.HasCassette = true;
  555. CarrierManager.Instance.CreateCarrier(Module.ToString());
  556. _faCallback.CarrierArrived(this);
  557. JobDone = false;
  558. _waferThicknessType = "";
  559. }
  560. }
  561. this.Protrusion = !baData1[9];
  562. if (Protrusion)
  563. {
  564. //EV.PostAlarmLog(Module.ToString(), "发现 wafer 突出");
  565. //EV.Notify(AlarmWaferProtrude);
  566. //Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
  567. }
  568. // DATA2, loadport上面的LED 灯, 暂时不需要用到
  569. break;
  570. default:
  571. break;
  572. }
  573. }
  574. #endregion
  575. #region TagData
  576. public void ReadTagData()
  577. {
  578. if (IsBusy)
  579. {
  580. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not read tag data");
  581. return;
  582. }
  583. if (IsError)
  584. {
  585. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not read tag data");
  586. return;
  587. }
  588. IsBusy = true;
  589. _controller.ReadTagData(Module);
  590. }
  591. public void OnTagDataRead(string data)
  592. {
  593. IsBusy = false;
  594. IsError = false;
  595. //Regex rg = new Regex("(?<=(" + "LOT :" + "))[.\\s\\S]*?(?=(" + "QTY :" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  596. //string carrierID = rg.Match(data).Value.Replace(":", "").Trim();
  597. //data =
  598. // "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 ";
  599. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  600. CarrierId = "";
  601. foreach (var item in items)
  602. {
  603. if (item.StartsWith("CST:") && item.Length > 4)
  604. CarrierId = item.Substring(4);
  605. if (item.StartsWith("LOT:") && item.Length > 4)
  606. LotId = item.Substring(4).Trim();
  607. }
  608. if (string.IsNullOrEmpty(CarrierId))
  609. {
  610. CarrierId = data;
  611. }
  612. SmartTag = data;
  613. _faCallback.TagDataRead(this);
  614. }
  615. public void OnTagDataReadFailed(string data)
  616. {
  617. IsError = true;
  618. IsBusy = false;
  619. _faCallback.ReadTagDataFailed(this);
  620. }
  621. public void WriteTagData(string tagData)
  622. {
  623. if (IsBusy)
  624. {
  625. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not write tag data");
  626. return;
  627. }
  628. if (IsError)
  629. {
  630. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not write tag data");
  631. return;
  632. }
  633. IsBusy = true;
  634. _controller.WriteTagData(Module, tagData);
  635. }
  636. public void OnTagDataWrite(string data)
  637. {
  638. IsBusy = false;
  639. IsError = false;
  640. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  641. CarrierId = "";
  642. foreach (var item in items)
  643. {
  644. if (item.StartsWith("CST:") && item.Length > 4)
  645. CarrierId = item.Substring(4);
  646. }
  647. if (string.IsNullOrEmpty(CarrierId))
  648. {
  649. CarrierId = data;
  650. }
  651. SmartTag = data;
  652. _faCallback.TagDataWrite(this);
  653. }
  654. public void OnTagDataWriteFailed(string data)
  655. {
  656. IsError = true;
  657. IsBusy = false;
  658. _faCallback.WriteTagDataFailed( this);
  659. }
  660. #endregion
  661. public void SetOnline(bool online)
  662. {
  663. OnlineFlag = online ? OnlineFlag.Online : OnlineFlag.Offline;
  664. }
  665. sealed class LoadPortFACallback
  666. {
  667. private string CARRIER_ARRIVED = "CARRIER_ARRIVED";
  668. private string CARRIER_REMOVED = "CARRIER_REMOVED";
  669. private string SLOT_MAP_AVAILABLE = "SLOT_MAP_AVAILABLE";
  670. private string SLOT_MAP_FAILED = "SLOT_MAP_FAILED";
  671. private const string CARRIER_LOADED = "CARRIER_LOADED";
  672. private const string PortLoadFailed = "PortLoadFailed";
  673. private const string CARRIER_UNLOADED = "CARRIER_UNLOADED";
  674. private const string PortUnloadFailed = "PortUnloadFailed";
  675. private const string PortClamped = "PortClamped";
  676. private const string PortUnclamped = "PortUnclamped";
  677. private const string CARRIER_ID_READ = "CARRIER_ID_READ";
  678. private const string PortReadIDFailed = "PortReadIDFailed";
  679. private const string PortIDWrite = "PortIDWrite";
  680. private const string PortWriteIDFailed = "PortWriteIDFailed";
  681. private const string PortTagDataRead = "PortTagDataRead";
  682. private const string PortReadTagDataFailed = "PortReadTagDataFailed";
  683. private const string PortTagDataWrite = "PortTagDataWrite";
  684. private const string PortWriteTagDataFailed = "PortWriteTagDataFailed";
  685. public LoadPortFACallback()
  686. {
  687. EV.Subscribe(new EventItem("Event", CARRIER_ARRIVED, "Carrier Arrived"));
  688. EV.Subscribe(new EventItem("Event", CARRIER_REMOVED, "Carrier Removed"));
  689. EV.Subscribe(new EventItem("Event", SLOT_MAP_AVAILABLE, "Slot map available"));
  690. EV.Subscribe(new EventItem("Event", SLOT_MAP_FAILED, "Slot map failed"));
  691. EV.Subscribe(new EventItem("Event", CARRIER_LOADED, "Carrier Loaded"));
  692. EV.Subscribe(new EventItem("Event", PortLoadFailed, PortLoadFailed));
  693. EV.Subscribe(new EventItem("Event", CARRIER_UNLOADED, "Carrier Unloaded"));
  694. EV.Subscribe(new EventItem("Event", PortUnloadFailed, PortUnloadFailed));
  695. EV.Subscribe(new EventItem("Event", PortClamped, "Port Clamped"));
  696. EV.Subscribe(new EventItem("Event", PortUnclamped, PortUnclamped));
  697. EV.Subscribe(new EventItem("Event", CARRIER_ID_READ, "Carrier Id Read"));
  698. EV.Subscribe(new EventItem("Event", PortReadIDFailed, PortReadIDFailed));
  699. EV.Subscribe(new EventItem("Event", PortIDWrite, PortIDWrite));
  700. EV.Subscribe(new EventItem("Event", PortWriteIDFailed, PortWriteIDFailed));
  701. EV.Subscribe(new EventItem("Event", PortTagDataRead, PortTagDataRead));
  702. EV.Subscribe(new EventItem("Event", PortReadTagDataFailed, PortReadTagDataFailed));
  703. EV.Subscribe(new EventItem("Event", PortTagDataWrite, PortTagDataWrite));
  704. EV.Subscribe(new EventItem("Event", PortWriteTagDataFailed, PortWriteTagDataFailed));
  705. }
  706. public void CarrierArrived(Loadport lp)
  707. {
  708. SerializableDictionary<string, string> dvid = new SerializableDictionary<string, string>();
  709. dvid["PortID"] = lp.PortId;
  710. EV.Notify(CARRIER_ARRIVED, dvid);
  711. }
  712. public void CarrierRemoved(Loadport lp)
  713. {
  714. SerializableDictionary<string, string> dvid = new SerializableDictionary<string, string>();
  715. dvid["PortID"] = lp.PortId;
  716. dvid["CarrierID"] = lp.CarrierId ?? "";
  717. EV.Notify(CARRIER_REMOVED, dvid);
  718. }
  719. public void CarrierSlotMapComplete(Loadport lp)
  720. {
  721. SerializableDictionary<string, string> dvid = new SerializableDictionary<string, string>();
  722. dvid["SlotMap"] = lp.SlotMap;
  723. dvid["PortID"] = lp.PortId;
  724. dvid["CarrierID"] = lp.CarrierId ?? "";
  725. EV.Notify(SLOT_MAP_AVAILABLE, dvid);
  726. }
  727. public void CarrierSlotMapFailed(Loadport lp)
  728. {
  729. }
  730. public void LoadComplete(Loadport lp)
  731. {
  732. ModuleName moduleName = lp.Module;
  733. var dvid = new SerializableDictionary<string, string>
  734. {
  735. ["CarrierID"] = lp.CarrierId ?? "",
  736. ["PortID"] = lp.PortId.ToString()
  737. };
  738. EV.Notify(CARRIER_LOADED, dvid);
  739. }
  740. public void LoadFailed(Loadport lp)
  741. {
  742. }
  743. public void UnloadComplete(Loadport lp)
  744. {
  745. ModuleName moduleName = lp.Module;
  746. var dvid = new SerializableDictionary<string, string>
  747. {
  748. ["CarrierID"] = lp.CarrierId ?? "",
  749. ["PortID"] = lp.PortId.ToString()
  750. };
  751. EV.Notify(CARRIER_UNLOADED, dvid);
  752. }
  753. public void UnloadFailed(Loadport lp)
  754. {
  755. }
  756. public void Clamped(Loadport lp)
  757. {
  758. ModuleName moduleName = lp.Module;
  759. var dvid = new SerializableDictionary<string, string>
  760. {
  761. ["CarrierID"] = lp.CarrierId ?? "",
  762. ["PortID"] = lp.PortId.ToString()
  763. };
  764. EV.Notify(PortClamped, dvid);
  765. }
  766. public void Unclamped(Loadport lp)
  767. {
  768. ModuleName moduleName = lp.Module;
  769. var dvid = new SerializableDictionary<string, string>
  770. {
  771. ["CarrierID"] = lp.CarrierId ?? "",
  772. ["PortID"] = lp.PortId.ToString()
  773. };
  774. EV.Notify(PortUnclamped, dvid);
  775. }
  776. public void IDRead(Loadport lp)
  777. {
  778. }
  779. public void ReadIDFailed(Loadport lp)
  780. {
  781. }
  782. public void IDWrite(Loadport lp)
  783. {
  784. }
  785. public void WriteIDFailed(Loadport lp)
  786. {
  787. }
  788. public void TagDataRead(Loadport lp)
  789. {
  790. }
  791. public void ReadTagDataFailed(Loadport lp)
  792. {
  793. }
  794. public void TagDataWrite(Loadport lp)
  795. {
  796. }
  797. public void WriteTagDataFailed(Loadport lp)
  798. {
  799. }
  800. }
  801. }
  802. }