Loadport.cs 29 KB

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