SecsGemEquipment.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.OperationCenter;
  5. using Aitex.Core.RT.RecipeCenter;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Core.Util;
  8. using Aitex.Sorter.Common;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.RT.ModuleLibrary.EfemModules;
  11. using MECF.Framework.RT.ModuleLibrary.LPModules;
  12. using SecsGem.Core.Application;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using VirgoRT.Devices.EFEM;
  19. using VirgoRT.Modules;
  20. namespace VirgoRT.Instances
  21. {
  22. public class SecsGemEquipment : IEquipmentCommand
  23. {
  24. #region 常量
  25. private const string EventTerminalMessage = "TerminalMessage";
  26. #endregion
  27. #region 内部变量
  28. private Dictionary<string, ModuleName> _dicPortModule = new Dictionary<string, ModuleName>()
  29. {
  30. {"1", ModuleName.LP1},
  31. {"2", ModuleName.LP2},
  32. {"3", ModuleName.LP3}
  33. };
  34. #endregion
  35. /// <summary>
  36. /// 初始化
  37. /// </summary>
  38. public void Initialize()
  39. {
  40. EV.Subscribe(new EventItem("Host", EventTerminalMessage, "{0}", EventLevel.Warning, EventType.EventUI_Notify));
  41. }
  42. public bool AbortControlJob(string controlJob)
  43. {
  44. return true;
  45. }
  46. public bool CheckAuto()
  47. {
  48. return Singleton<RouteManager>.Instance.IsAutoMode;
  49. }
  50. public bool CheckCreateControlJobCondition(List<string> modules, out string reason)
  51. {
  52. reason = "";
  53. return true;
  54. }
  55. public void CreateControlJob(string controlJobId, string carrierId, List<string> processJobs)
  56. {
  57. return;
  58. }
  59. public bool CreateProcessJob(string processJobId, string sequenceName, string carrierId, out string reason)
  60. {
  61. reason = "";
  62. return true;
  63. }
  64. /// <summary>
  65. /// 执行指令
  66. /// </summary>
  67. /// <param name="command"></param>
  68. /// <param name="paras"></param>
  69. /// <param name="reason"></param>
  70. /// <returns></returns>
  71. public bool ExcuteCommand(string command, object[] paras, out string reason)
  72. {
  73. reason = "";
  74. int portID;
  75. string jobID;
  76. string lotId;
  77. object[] sequence;
  78. switch (command.ToUpper())
  79. {
  80. case "PP-SELECT":
  81. portID = int.Parse(paras[0].ToString());
  82. jobID = paras[1].ToString();
  83. lotId = paras[2].ToString();
  84. sequence = (object[])paras[3];
  85. return PPselect(portID, jobID, lotId, sequence,out reason);
  86. case "STARTJOB":
  87. jobID = paras[0].ToString();
  88. OP.DoOperation("System.StartJob", new object[] { jobID });
  89. return true;
  90. case "ABORTJOB":
  91. jobID = paras[0].ToString();
  92. OP.DoOperation("System.AbortJob", new object[] { jobID });
  93. return true;
  94. case "PAUSEJOB":
  95. jobID = paras[0].ToString();
  96. OP.DoOperation("System.PauseJob", new object[] { jobID });
  97. return true;
  98. case "RESUMEJOB":
  99. jobID = paras[0].ToString();
  100. OP.DoOperation("System.ResumeJob", new object[] { jobID });
  101. return true;
  102. case "STOPJOB":
  103. jobID = paras[0].ToString();
  104. OP.DoOperation("System.StopJob", new object[] { jobID });
  105. return true;
  106. case "LOAD":
  107. portID = int.Parse(paras[0].ToString());
  108. return Load(portID, out reason);
  109. case "UNLOAD":
  110. portID = int.Parse(paras[0].ToString());
  111. return Unload(portID, out reason);
  112. case "LOCK":
  113. portID = int.Parse(paras[0].ToString());
  114. return Lock(portID, out reason);
  115. case "UNLOCK":
  116. portID = int.Parse(paras[0].ToString());
  117. return Unlock(portID, out reason);
  118. case "READID":
  119. portID = int.Parse(paras[0].ToString());
  120. return ReadId(portID, out reason);
  121. case "WRITEID":
  122. portID = int.Parse(paras[0].ToString());
  123. string carrierID = paras[1].ToString();
  124. return WriteId(portID, carrierID, out reason);
  125. case "READTAG":
  126. portID = int.Parse(paras[0].ToString());
  127. return ReadTag(portID, out reason);
  128. case "WRITETAG":
  129. portID = int.Parse(paras[0].ToString());
  130. string tagData = paras[1].ToString();
  131. return WriteId(portID, tagData, out reason);
  132. }
  133. return true;
  134. }
  135. #region LoadPort
  136. /// <summary>
  137. /// 创建Job
  138. /// </summary>
  139. /// <param name="portID"></param>
  140. /// <param name="jobID"></param>
  141. /// <param name="lotID"></param>
  142. /// <param name="sequence"></param>
  143. /// <param name="reason"></param>
  144. /// <returns></returns>
  145. private bool PPselect(int portID,string jobID,string lotID, object[] sequence,out string reason)
  146. {
  147. if (!_dicPortModule.ContainsKey(portID.ToString()))
  148. {
  149. reason = $"{portID} not valid";
  150. return false;
  151. }
  152. var len = SC.GetValue<int>($"LoadPort.SlotNumber");
  153. if (len != sequence.Length)
  154. {
  155. reason = $"length is not match,length={len}";
  156. return false;
  157. }
  158. string[] slotsequence = new string[len];
  159. for (int i = 0; i < len; i++)
  160. {
  161. slotsequence[i] = sequence[i].ToString() == "*null*" ? "" : sequence[i].ToString();
  162. }
  163. if (!Singleton<RouteManager>.Instance.IsAutoMode)
  164. {
  165. reason = $"System not in auto mode";
  166. return false;
  167. }
  168. Dictionary<string, object> param = new Dictionary<string, object>()
  169. {
  170. {"JobId", jobID},
  171. {"LotId", lotID},
  172. {"Module", _dicPortModule[portID.ToString()].ToString()},
  173. {"SlotSequence", slotsequence},
  174. {"AutoStart", false},
  175. };
  176. OP.DoOperation("System.CreateJob", param);
  177. reason = string.Empty;
  178. return true;
  179. }
  180. /// <summary>
  181. /// Load指令
  182. /// </summary>
  183. /// <param name="portID"></param>
  184. /// <param name="reason"></param>
  185. /// <returns></returns>
  186. private bool Load(int portID,out string reason)
  187. {
  188. reason = "";
  189. if (!_dicPortModule.ContainsKey(portID.ToString()))
  190. {
  191. reason = $"{portID} not valid";
  192. return false;
  193. }
  194. Loadport LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  195. if (LPDevice == null)
  196. {
  197. reason = $"{portID} not valid";
  198. return false;
  199. }
  200. if (!LPDevice.HasCassette)
  201. {
  202. reason = $"{portID} cassette not placed";
  203. return false;
  204. }
  205. if (LPDevice.Status == DeviceState.Error)
  206. {
  207. reason = $"{portID} port in error, need reset";
  208. return false;
  209. }
  210. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Load");
  211. return true;
  212. }
  213. /// <summary>
  214. /// Load指令
  215. /// </summary>
  216. /// <param name="portID"></param>
  217. /// <param name="reason"></param>
  218. /// <returns></returns>
  219. private bool Unload(int portID, out string reason)
  220. {
  221. if (!_dicPortModule.ContainsKey(portID.ToString()))
  222. {
  223. reason = $"{portID} not valid";
  224. return false;
  225. }
  226. Loadport LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  227. if (LPDevice == null)
  228. {
  229. reason = $"{portID} not valid";
  230. return false;
  231. }
  232. if (!LPDevice.HasCassette)
  233. {
  234. reason = $"{portID} cassette not placed";
  235. return false;
  236. }
  237. if (LPDevice.Status == DeviceState.Error)
  238. {
  239. reason = $"{portID} port in error, need reset";
  240. return false;
  241. }
  242. if (SC.GetValue<bool>("EFEM.AutoUnlockAfterUnload"))
  243. {
  244. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Unload");
  245. }
  246. else
  247. {
  248. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Undock");
  249. }
  250. reason = string.Empty;
  251. return true;
  252. }
  253. /// <summary>
  254. /// Lock指令
  255. /// </summary>
  256. /// <param name="portID"></param>
  257. /// <param name="reason"></param>
  258. /// <returns></returns>
  259. private bool Lock(int portID, out string reason)
  260. {
  261. if (!_dicPortModule.ContainsKey(portID.ToString()))
  262. {
  263. reason = $"{portID} not valid";
  264. return false;
  265. }
  266. Loadport LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  267. if (LPDevice == null)
  268. {
  269. reason = $"{portID} not valid";
  270. return false;
  271. }
  272. if (!LPDevice.HasCassette)
  273. {
  274. reason = $"{portID} cassette not placed";
  275. return false;
  276. }
  277. if (LPDevice.Status == DeviceState.Error)
  278. {
  279. reason = $"{portID} port in error, need reset";
  280. return false;
  281. }
  282. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Clamp");
  283. reason = string.Empty;
  284. return true;
  285. }
  286. /// <summary>
  287. /// Unlock指令
  288. /// </summary>
  289. /// <param name="portID"></param>
  290. /// <param name="reason"></param>
  291. /// <returns></returns>
  292. private bool Unlock(int portID, out string reason)
  293. {
  294. if (!_dicPortModule.ContainsKey(portID.ToString()))
  295. {
  296. reason = $"{portID} not valid";
  297. return false;
  298. }
  299. Loadport LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  300. if (LPDevice == null)
  301. {
  302. reason = $"{portID} not valid";
  303. return false;
  304. }
  305. if (!LPDevice.HasCassette)
  306. {
  307. reason = $"{portID} cassette not placed";
  308. return false;
  309. }
  310. if (LPDevice.Status == DeviceState.Error)
  311. {
  312. reason = $"{portID} port in error, need reset";
  313. return false;
  314. }
  315. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Unclamp");
  316. reason = string.Empty;
  317. return true;
  318. }
  319. /// <summary>
  320. /// Read ID
  321. /// </summary>
  322. /// <param name="portID"></param>
  323. /// <param name="reason"></param>
  324. /// <returns></returns>
  325. private bool ReadId(int portID, out string reason)
  326. {
  327. if (!_dicPortModule.ContainsKey(portID.ToString()))
  328. {
  329. reason = $"{portID} not valid";
  330. return false;
  331. }
  332. var LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  333. if (LPDevice == null)
  334. {
  335. reason = $"{portID} not valid";
  336. return false;
  337. }
  338. if (!LPDevice.HasCassette)
  339. {
  340. reason = $"{portID} cassette not placed";
  341. return false;
  342. }
  343. if (LPDevice.Status == DeviceState.Error)
  344. {
  345. reason = $"{portID} port in error, need reset";
  346. return false;
  347. }
  348. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.ReadCarrierId");
  349. reason = string.Empty;
  350. return true;
  351. }
  352. /// <summary>
  353. /// Write ID
  354. /// </summary>
  355. /// <param name="portID"></param>
  356. /// <param name="reason"></param>
  357. /// <returns></returns>
  358. private bool WriteId(int portID,string carrierID, out string reason)
  359. {
  360. if (!_dicPortModule.ContainsKey(portID.ToString()))
  361. {
  362. reason = $"{portID} not valid";
  363. return false;
  364. }
  365. var LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  366. if (LPDevice == null)
  367. {
  368. reason = $"{portID} not valid";
  369. return false;
  370. }
  371. if (!LPDevice.HasCassette)
  372. {
  373. reason = $"{portID} cassette not placed";
  374. return false;
  375. }
  376. if (LPDevice.Status == DeviceState.Error)
  377. {
  378. reason = $"{portID} port in error, need reset";
  379. return false;
  380. }
  381. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.WriteCarrierID", carrierID);
  382. reason = string.Empty;
  383. return true;
  384. }
  385. /// <summary>
  386. /// Read ID
  387. /// </summary>
  388. /// <param name="portID"></param>
  389. /// <param name="reason"></param>
  390. /// <returns></returns>
  391. private bool ReadTag(int portID, out string reason)
  392. {
  393. if (!_dicPortModule.ContainsKey(portID.ToString()))
  394. {
  395. reason = $"{portID} not valid";
  396. return false;
  397. }
  398. var LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  399. if (LPDevice == null)
  400. {
  401. reason = $"{portID} not valid";
  402. return false;
  403. }
  404. if (!LPDevice.HasCassette)
  405. {
  406. reason = $"{portID} cassette not placed";
  407. return false;
  408. }
  409. if (LPDevice.Status == DeviceState.Error)
  410. {
  411. reason = $"{portID} port in error, need reset";
  412. return false;
  413. }
  414. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.ReadTagData");
  415. reason = string.Empty;
  416. return true;
  417. }
  418. /// <summary>
  419. /// Write ID
  420. /// </summary>
  421. /// <param name="portID"></param>
  422. /// <param name="reason"></param>
  423. /// <returns></returns>
  424. private bool WriteTag(int portID, string tagData, out string reason)
  425. {
  426. if (!_dicPortModule.ContainsKey(portID.ToString()))
  427. {
  428. reason = $"{portID} not valid";
  429. return false;
  430. }
  431. var LPDevice = Singleton<RouteManager>.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport;
  432. if (LPDevice == null)
  433. {
  434. reason = $"{portID} not valid";
  435. return false;
  436. }
  437. if (!LPDevice.HasCassette)
  438. {
  439. reason = $"{portID} cassette not placed";
  440. return false;
  441. }
  442. if (LPDevice.Status == DeviceState.Error)
  443. {
  444. reason = $"{portID} port in error, need reset";
  445. return false;
  446. }
  447. OP.DoOperation($"{_dicPortModule[portID.ToString()]}.WriteTagData", tagData);
  448. reason = string.Empty;
  449. return true;
  450. }
  451. #endregion
  452. #region recipe
  453. /// <summary>
  454. /// 删除Sequence
  455. /// </summary>
  456. /// <param name="ppid"></param>
  457. /// <returns></returns>
  458. public bool deleteSequence(string ppid)
  459. {
  460. LOG.Warning("system not support update sequence");
  461. return false;
  462. //return RecipeFileManager.Instance.DeleteSequence(ppid);
  463. }
  464. /// <summary>
  465. /// S7F25
  466. /// </summary>
  467. /// <param name="ppid"></param>
  468. /// <returns></returns>
  469. public List<string> GetFormatedSequence(string ppid)
  470. {
  471. List<string> result = new List<string>();
  472. string reason = string.Empty;
  473. try
  474. {
  475. string content = string.Empty;
  476. if (RecipeFileManager.Instance.CheckSequenceFileExist(ppid))
  477. content = RecipeFileManager.Instance.GetSequence(ppid, false);
  478. if (string.IsNullOrEmpty(content))
  479. {
  480. bool enableFolder = SC.GetValue<bool>("System.RecipeFolderByType");
  481. if (enableFolder)
  482. {
  483. if (ppid.StartsWith("PMA") && !ppid.StartsWith("PMA\\Process") &&
  484. !ppid.StartsWith("PMA\\Clean"))
  485. ppid = ppid.Replace("PMA", "PMA\\Process");
  486. if (ppid.StartsWith("PMB") && !ppid.StartsWith("PMB\\Process") &&
  487. !ppid.StartsWith("PMB\\Clean"))
  488. ppid = ppid.Replace("PMB", "PMB\\Process");
  489. }
  490. content = RecipeFileManager.Instance.LoadRecipe("", ppid, false);
  491. }
  492. result.Add(content);
  493. }
  494. catch (Exception ex)
  495. {
  496. LOG.Write(ex);
  497. reason = ex.Message;
  498. }
  499. return result;
  500. }
  501. /// <summary>
  502. /// S7F5 获取recipe body
  503. /// </summary>
  504. /// <param name="ppid"></param>
  505. /// <returns></returns>
  506. /// <exception cref="NotImplementedException"></exception>
  507. public string GetSequenceBody(string ppid)
  508. {
  509. return RecipeFileManager.Instance.GetSequence(ppid, false);
  510. }
  511. /// <summary>
  512. /// S7F3 更新Recipe
  513. /// </summary>
  514. /// <param name="ppid"></param>
  515. /// <param name="body"></param>
  516. /// <returns></returns>
  517. public bool UpdateSequence(string ppid, string body)
  518. {
  519. LOG.Warning("system not support update sequence");
  520. return false;
  521. //bool ret = false;
  522. //string reason = string.Empty;
  523. //ret = RecipeFileManager.Instance.SaveSequence(ppid, body, false);
  524. //if (!ret)
  525. //{
  526. // reason = string.Format("save recipe content failed,recipeName:{0}", ppid);
  527. // LOG.Write(reason);
  528. //}
  529. //return ret;
  530. }
  531. /// <summary>
  532. /// 获取sequence集合 S7F19
  533. /// </summary>
  534. /// <returns></returns>
  535. public string[] GetSequenceList()
  536. {
  537. var recipeList = RecipeFileManager.Instance.GetSequenceNameList();
  538. return recipeList.ToArray();
  539. }
  540. #endregion
  541. public bool PauseControlJob(string controlJob)
  542. {
  543. throw new NotImplementedException();
  544. }
  545. public bool ResumeControlJob(string controlJob)
  546. {
  547. throw new NotImplementedException();
  548. }
  549. public void ShowTerminalMessage(string message)
  550. {
  551. EV.Notify("Host", EventTerminalMessage, message);
  552. }
  553. public bool StartControlJob(string controlJob)
  554. {
  555. throw new NotImplementedException();
  556. }
  557. public bool StopControlJob(string controlJob)
  558. {
  559. throw new NotImplementedException();
  560. }
  561. public void UpdateControlJobModule(string controlJobId, string moduleName)
  562. {
  563. throw new NotImplementedException();
  564. }
  565. public void UpdateProcessJobCarrierSlot(string processJobId, string moduleName, List<int> slots)
  566. {
  567. throw new NotImplementedException();
  568. }
  569. #region eap log write in RT
  570. public void WriteErrorLog(string message)
  571. {
  572. LOG.Error(message);
  573. }
  574. public void WriteInfoLog(string message)
  575. {
  576. LOG.Info(message);
  577. }
  578. public void WriteWarningLog(string message)
  579. {
  580. LOG.Warning(message);
  581. }
  582. #endregion
  583. }
  584. }