RouteManager.cs 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Aitex.Core.RT.Fsm;
  8. using Aitex.Core.Common;
  9. using Aitex.Core.RT.DataCenter;
  10. using Aitex.Core.RT.Event;
  11. using Aitex.Core.RT.OperationCenter;
  12. using Aitex.Core.RT.SCCore;
  13. using Aitex.Core.Util;
  14. using MECF.Framework.Common.Jobs;
  15. using MECF.Framework.Common.Equipment;
  16. using MECF.Framework.Common.SubstrateTrackings;
  17. using CyberX8_Core;
  18. using Aitex.Core.RT.Log;
  19. using SecsGem.Core.Application;
  20. using CyberX8_RT.Modules.SRD;
  21. using CyberX8_RT.Modules.PUF;
  22. using CyberX8_RT.Modules.Dummy;
  23. using CyberX8_RT.Modules.Loader;
  24. using Aitex.Core.RT.Device;
  25. using CyberX8_RT.Modules.Prewet;
  26. using CyberX8_RT.Modules.Dryer;
  27. using MECF.Framework.Common.ToolLayout;
  28. using CyberX8_RT.Modules.Metal;
  29. using CyberX8_RT.Modules.Rinse;
  30. using MECF.Framework.Common.Routine;
  31. using CyberX8_RT.Dispatch;
  32. using CyberX8_RT.Modules.Reservoir;
  33. using System.IO;
  34. using CyberX8_RT.Modules.Buffer;
  35. using CyberX8_RT.Modules.Transporter;
  36. using CyberX8_RT.Devices.Loader;
  37. using CyberX8_RT.Devices.PUF;
  38. using CyberX8_RT.Devices.SRD;
  39. using MECF.Framework.Common.Alarm;
  40. using System.Diagnostics;
  41. using MECF.Framework.Common.WaferHolder;
  42. using CyberX8_RT.Schedulers;
  43. using MECF.Framework.Common.ProcessCell;
  44. using System.Reflection;
  45. namespace CyberX8_RT.Modules
  46. {
  47. class RouteManager : Entity, IEntity
  48. {
  49. public enum MSG
  50. {
  51. MoveWafer,
  52. ReturnWafer,
  53. HomeUnit,
  54. PauseAuto,
  55. ResumeAuto,
  56. Stop,
  57. StartCycle,
  58. StopCycle,
  59. HOME,
  60. RESET,
  61. ABORT,
  62. ERROR,
  63. SetAutoMode,
  64. SetManualMode,
  65. ResetIdleCleanTime,
  66. ResetIdlePurgeTime,
  67. CreateJob,
  68. PauseJob,
  69. PauseAllJobs,
  70. ResumeJob,
  71. ResumeAllJobs,
  72. StartJob,
  73. StopJob,
  74. AbortJob,
  75. JobDone,
  76. CassetteLeave, //For unload light control off afer job done
  77. Map,
  78. ReturnAllWafer,
  79. TMCycle,
  80. Retry,
  81. ConfirmComplete,
  82. ResetWafers,
  83. FaStartJob,
  84. FaStopJob,
  85. }
  86. #region 属性
  87. public string Name { get; set; }
  88. public bool IsAutoMode
  89. {
  90. get
  91. {
  92. return fsm.State == (int)RtState.AutoRunning || fsm.State == (int)RtState.AutoIdle||fsm.State==(int)RtState.AutoAborting;
  93. }
  94. }
  95. public bool IsFaAutoMode
  96. {
  97. get
  98. {
  99. return fsm.State == (int)RtState.AutoRunning || fsm.State == (int)RtState.AutoIdle;
  100. }
  101. }
  102. public bool IsInit
  103. {
  104. get { return fsm.State == (int)RtState.Init; }
  105. }
  106. public bool IsIdle
  107. {
  108. get { return fsm.State == (int)RtState.Idle || fsm.State == (int)RtState.AutoIdle; }
  109. }
  110. public bool IsAlarm
  111. {
  112. get { return fsm.State == (int)RtState.Error; }
  113. }
  114. public bool IsPaused
  115. {
  116. get { return _jobCycle.CycleState == RState.Paused; }
  117. }
  118. public bool IsRunning
  119. {
  120. get
  121. {
  122. return !IsInit && !IsAlarm && !IsIdle;
  123. }
  124. }
  125. /// <summary>
  126. /// 是否AutoRunning
  127. /// </summary>
  128. public bool IsAutoRunning
  129. {
  130. get { return fsm.State == (int)RtState.AutoRunning||fsm.State==(int)RtState.AutoAborting; }
  131. }
  132. /// <summary>
  133. /// 是否
  134. /// </summary>
  135. public bool IsAutoIdle
  136. {
  137. get { return fsm.State == (int)RtState.AutoIdle; }
  138. }
  139. /// <summary>
  140. /// EFEM实体
  141. /// </summary>
  142. public EfemEntity EFEM { get; }
  143. public WaferSize WaferSize { get; private set; }
  144. #endregion
  145. #region 内部变量
  146. private string _systemControlIp;
  147. private ICycle _jobCycle;
  148. private ModuleHomeAllRoutine _homeAllRoutine;
  149. private List<ReservoirMetalHomeRoutine> _reservoirMetalRoutines=new List<ReservoirMetalHomeRoutine>();
  150. /// <summary>
  151. /// 模块实体字典
  152. /// </summary>
  153. private Dictionary<string, IModuleEntity> _moduleEntitiesDic = new Dictionary<string, IModuleEntity>();
  154. /// <summary>
  155. /// 模块类型实体字典
  156. /// </summary>
  157. private Dictionary<ModuleType, List<IModuleEntity>> _modultTypeEntitiesDic = new Dictionary<ModuleType, List<IModuleEntity>>();
  158. /// <summary>
  159. /// Home stopwatch
  160. /// </summary>
  161. private Stopwatch _homeStopWatch = new Stopwatch();
  162. #endregion
  163. /// <summary>
  164. /// 构造函数
  165. /// </summary>
  166. public RouteManager()
  167. {
  168. Name = "System";
  169. WaferSize = (WaferSize)SC.GetValue<int>("System.WaferSize");
  170. if (ModuleHelper.IsInstalled(ModuleName.EFEM))
  171. {
  172. EFEM = new EfemEntity();
  173. EFEM.Initialize();
  174. _moduleEntitiesDic[ModuleName.EFEM.ToString()] = EFEM;
  175. }
  176. InitialModuleList(PufItemManager.Instance.InstalledModules, typeof(PUFEntity),ModuleType.PUF);
  177. InitialModuleList(DummyCasseteItemManager.Instance.InstalledModules, typeof(DummyEntity),ModuleType.Dummy);
  178. InitialModuleList(LoaderItemManager.Instance.InstalledModules, typeof(LoaderEntity),ModuleType.Loader);
  179. InitialModuleList(TransporterItemManager.Instance.InstalledModules, typeof(TransporterEntity),ModuleType.Transporter);
  180. InitialModuleList(BufferItemManager.Instance.InstalledModules, typeof(BufferEntity), ModuleType.Buffer);
  181. InitialModuleList(PrewetItemManager.Instance.InstalledModules, typeof(PrewetEntity),ModuleType.Prewet);
  182. InitialModuleList(DryerItemManager.Instance.InstalledModules, typeof(DryerEntity),ModuleType.Dryer);
  183. InitialModuleList(MetalItemManager.Instance.InstalledModules, typeof(MetalEntity),ModuleType.Metal);
  184. InitialModuleList(RinseItemManager.Instance.InstalledModules, typeof(RinseEntity),ModuleType.Rinse);
  185. InitialModuleList(ReservoirItemManager.Instance.InstalledModules,typeof(ReservoirEntity),ModuleType.Reservoir);
  186. InitialModuleList(SrdItemManager.Instance.InstalledModules, typeof(SRDEntity), ModuleType.SRD);
  187. fsm = new StateMachine<RouteManager>(Name, (int)RtState.Init, 200);
  188. SubscribeOperation();
  189. SubscribeDataVariable();
  190. SchedulerSequenceManager.Instance.Initialize();
  191. }
  192. /// <summary>
  193. /// 初始化模块集合
  194. /// </summary>
  195. /// <param name="lst"></param>
  196. /// <param name="entityType"></param>
  197. private void InitialModuleList(List<string> lst,Type entityType,ModuleType moduleType)
  198. {
  199. foreach(string item in lst)
  200. {
  201. InitialModule(item, entityType,moduleType);
  202. }
  203. }
  204. /// <summary>
  205. /// 初始化模块对象
  206. /// </summary>
  207. /// <param name="item"></param>
  208. /// <param name="moduleType"></param>
  209. private void InitialModule(string item,Type entityType,ModuleType moduleType)
  210. {
  211. ModuleName moduleName = (ModuleName)Enum.Parse(typeof(ModuleName), item);
  212. IModuleEntity moduleEntity= (IModuleEntity)System.Activator.CreateInstance(entityType,moduleName);
  213. moduleEntity.Initialize();
  214. _moduleEntitiesDic[item] = moduleEntity;
  215. List<IModuleEntity> lst = new List<IModuleEntity>();
  216. if(_modultTypeEntitiesDic.ContainsKey(moduleType))
  217. {
  218. lst= _modultTypeEntitiesDic[moduleType];
  219. }
  220. else
  221. {
  222. _modultTypeEntitiesDic[moduleType] = lst;
  223. }
  224. lst.Add(moduleEntity);
  225. }
  226. public bool Check(int msg, out string reason, params object[] args)
  227. {
  228. if (!fsm.FindTransition(fsm.State, msg))
  229. {
  230. reason = String.Format("{0} is in {1} state,can not do {2}", Name, 0, (MSG)msg);
  231. return false;
  232. }
  233. if (msg == (int)MSG.StartCycle)
  234. {
  235. if (!IsAutoMode)
  236. {
  237. reason = String.Format("can not do {0}, isn't auto mode.", msg.ToString());
  238. return false;
  239. }
  240. }
  241. reason = "";
  242. return true;
  243. }
  244. /// <summary>
  245. /// 订阅数据
  246. /// </summary>
  247. void SubscribeDataVariable()
  248. {
  249. DATA.Subscribe("System.SystemControlIp", ()=>_systemControlIp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  250. DATA.Subscribe("Rt.Status", () => ((RtState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  251. DATA.Subscribe("System.State", () => ((RtState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  252. DATA.Subscribe("System.IsAutoMode", () => IsAutoMode, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  253. DATA.Subscribe("System.IsAutoRunning", () => IsAutoRunning, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  254. DATA.Subscribe("System.IsIdle", () => IsIdle || IsInit, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  255. DATA.Subscribe("System.IsAlarm", () => IsAlarm, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  256. DATA.Subscribe("System.IsBusy", () => IsRunning, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  257. DATA.Subscribe("System.IsConnectedWithHost", () => CheckSecsGemOnline(Singleton<SecGemApplication>.Instance.ControlState),SubscriptionAttribute.FLAG.IgnoreSaveDB);
  258. DATA.Subscribe("System.IsDisconnectWithHost", () => CheckSecsGemOnline(Singleton<SecGemApplication>.Instance.ControlState),SubscriptionAttribute.FLAG.IgnoreSaveDB);
  259. DATA.Subscribe("System.EquipmentMode", () => IsAutoMode ? "Auto":"Manual", SubscriptionAttribute.FLAG.IgnoreSaveDB);
  260. DATA.Subscribe("EquipmentStatus", () =>
  261. {
  262. if (IsInit) return 0;
  263. if (IsIdle) return 1;
  264. if (IsAlarm) return 3;
  265. if (IsPaused) return 4;
  266. return 2;
  267. }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  268. }
  269. /// <summary>
  270. /// 订阅操作
  271. /// </summary>
  272. void SubscribeOperation()
  273. {
  274. OP.Subscribe("ApplySystemControl", ApplySystemControl);
  275. OP.Subscribe("ReleaseSystemControl", ReleaseSystemControl);
  276. OP.Subscribe("CreateWafer", InvokeCreateWafer);
  277. OP.Subscribe("DeleteWafer", InvokeDeleteWafer);
  278. OP.Subscribe("System.Home", (cmd, args) => CheckToPostMessage((int)MSG.HOME, args));
  279. DATA.Subscribe("SYSTEM.FsmState", () => (((RtState)fsm.State).ToString()), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  280. OP.Subscribe("System.ReturnAllWafer", (string cmd, object[] args) =>
  281. {
  282. return CheckToPostMessage((int)MSG.ReturnAllWafer, args[0], args[1], args[2], args[3]);
  283. });
  284. OP.Subscribe("System.MoveWafer", (string cmd, object[] args) =>
  285. {
  286. if (!Enum.TryParse((string)args[0], out ModuleName source))
  287. {
  288. EV.PostWarningLog(Name, $"Parameter source {(string)args[0]} not valid");
  289. return false;
  290. }
  291. if (!Enum.TryParse((string)args[2], out ModuleName destination))
  292. {
  293. EV.PostWarningLog(Name, $"Parameter destination {(string)args[1]} not valid");
  294. return false;
  295. }
  296. return CheckToPostMessage((int)MSG.MoveWafer,
  297. source, (int)args[1],
  298. destination, (int)args[3],
  299. args[4], args[5],
  300. args[6], args[7], (string)args[8]);
  301. });
  302. OP.Subscribe("System.HomeAll", (string cmd, object[] args) =>
  303. {
  304. return CheckToPostMessage((int)MSG.HOME);
  305. });
  306. OP.Subscribe("System.Abort", (string cmd, object[] args) =>
  307. {
  308. return CheckToPostMessage((int)MSG.ABORT);
  309. });
  310. OP.Subscribe("System.Reset", (string cmd, object[] args) =>
  311. {
  312. return CheckToPostMessage((int)MSG.RESET);
  313. });
  314. OP.Subscribe("System.SetAutoMode", (string cmd, object[] args) =>
  315. {
  316. return CheckToPostMessage((int)MSG.SetAutoMode);
  317. });
  318. OP.Subscribe("System.SetManualMode", (string cmd, object[] args) =>
  319. {
  320. return CheckToPostMessage((int)MSG.SetManualMode);
  321. });
  322. OP.Subscribe("System.CreateJob", (string cmd, object[] args) =>
  323. {
  324. return CheckToPostMessage((int)MSG.CreateJob, args[0]);
  325. });
  326. OP.Subscribe("System.StartJob", (string cmd, object[] args) =>
  327. {
  328. return CheckToPostMessage((int)MSG.StartJob, args[0]);
  329. });
  330. OP.Subscribe("System.PauseJob", (string cmd, object[] args) =>
  331. {
  332. return CheckToPostMessage((int)MSG.PauseJob, args[0]);
  333. });
  334. OP.Subscribe("System.ResumeJob", (string cmd, object[] args) =>
  335. {
  336. return CheckToPostMessage((int)MSG.ResumeJob, args[0]);
  337. });
  338. OP.Subscribe("System.PauseAllJob", (cmd, args) => { return CheckToPostMessage((int)MSG.PauseAllJobs); }) ;
  339. OP.Subscribe("System.ResumeAllJob", (cmd, args) => { return CheckToPostMessage((int)MSG.ResumeAllJobs); });
  340. OP.Subscribe("System.StopJob", (string cmd, object[] args) =>
  341. {
  342. return CheckToPostMessage((int)MSG.StopJob, args[0]);
  343. });
  344. OP.Subscribe("System.AbortJob", (string cmd, object[] args) =>
  345. {
  346. return CheckToPostMessage((int)MSG.AbortJob, args[0]);
  347. });
  348. OP.Subscribe(RtOperation.SetConfig.ToString(), (name, args) =>
  349. {
  350. string sc_key = args[0] as string;
  351. if (!string.IsNullOrWhiteSpace(sc_key) && args.Length > 1)
  352. {
  353. SC.SetItemValue(sc_key, args[1]);
  354. }
  355. return true;
  356. });
  357. OP.Subscribe("System.ResetIdleCleanTime", (string cmd, object[] args) =>
  358. {
  359. return CheckToPostMessage((int)MSG.ResetIdleCleanTime, args[0]);
  360. });
  361. OP.Subscribe("System.ResetIdlePurgeTime", (string cmd, object[] args) =>
  362. {
  363. return CheckToPostMessage((int)MSG.ResetIdlePurgeTime, args[0]);
  364. });
  365. OP.Subscribe("System.SetWaferSize", (string cmd, object[] args) =>
  366. {
  367. string module = (string)args[0];
  368. string size = (string)args[1];
  369. switch (size)
  370. {
  371. case "3":
  372. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS3);
  373. break;
  374. case "4":
  375. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS4);
  376. break;
  377. case "6":
  378. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS6);
  379. break;
  380. default:
  381. EV.PostWarningLog("System", $"wafer size {size} not valid");
  382. break;
  383. }
  384. return true;
  385. });
  386. //OP.Subscribe("System.CassetteLeave", (string cmd, object[] args) =>
  387. //{
  388. // return CheckToPostMessage((int)MSG.CassetteLeave);
  389. //});
  390. OP.Subscribe("System.Retry", (string cmd, object[] args) =>
  391. {
  392. return CheckToPostMessage((int)MSG.Retry, args[0]);
  393. });
  394. OP.Subscribe("System.ConfirmComplete", (string cmd, object[] args) =>
  395. {
  396. return CheckToPostMessage((int)MSG.ConfirmComplete, args[0]);
  397. });
  398. OP.Subscribe("WaferHolder.ResetLayoutWafers", (string cmd, object[] args) =>
  399. {
  400. return CheckToPostMessage((int)MSG.ResetWafers, args);
  401. });
  402. }
  403. /// <summary>
  404. /// 申请系统控制权
  405. /// </summary>
  406. /// <param name="cmd"></param>
  407. /// <param name="args"></param>
  408. /// <returns></returns>
  409. private bool ApplySystemControl(string cmd, object[] args)
  410. {
  411. if (args[0].ToString() == "")
  412. {
  413. LOG.WriteLog(eEvent.WARN_ROUTER, "System", $"Current IP does not allow the application of UI control permissions");
  414. return false;
  415. }
  416. string applyIp = args[0].ToString();
  417. if (string.IsNullOrEmpty(_systemControlIp))
  418. {
  419. _systemControlIp = applyIp;
  420. LOG.WriteLog(eEvent.EV_ROUTER, "System", $"{_systemControlIp} apply system control success");
  421. return true;
  422. }
  423. else if(_systemControlIp!=applyIp)
  424. {
  425. LOG.WriteLog(eEvent.WARN_ROUTER, "System", $"{_systemControlIp} already has system control permission");
  426. return false;
  427. }
  428. return false;
  429. }
  430. /// <summary>
  431. /// 释放系统控制权
  432. /// </summary>
  433. /// <param name="cmd"></param>
  434. /// <param name="args"></param>
  435. /// <returns></returns>
  436. private bool ReleaseSystemControl(string cmd, object[] args)
  437. {
  438. string releaseIp = args[0].ToString();
  439. if (_systemControlIp == releaseIp)
  440. {
  441. LOG.WriteLog(eEvent.EV_ROUTER, "System", $"{releaseIp} release system control success");
  442. _systemControlIp = "";
  443. }
  444. else
  445. {
  446. LOG.WriteLog(eEvent.ERR_ROUTER, "System", $"{releaseIp} is not SystemControlIp");
  447. }
  448. return false;
  449. }
  450. /// <summary>
  451. /// 检验Secsgem在线情况
  452. /// </summary>
  453. /// <param name="controlState"></param>
  454. /// <returns></returns>
  455. private bool CheckSecsGemOnline(SecsGem.Core.EnumData.ControlState controlState)
  456. {
  457. if (controlState == SecsGem.Core.EnumData.ControlState.OnlineLocal || controlState == SecsGem.Core.EnumData.ControlState.OnlineRemote)
  458. {
  459. return true;
  460. }
  461. return false;
  462. }
  463. public bool CheckToPostMessage(int msg, params object[] args)
  464. {
  465. if (!fsm.FindTransition(fsm.State, msg))
  466. {
  467. LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, $"System is in {(RtState)fsm.State} state,can not do {(MSG)msg}");
  468. return false;
  469. }
  470. Running = true;
  471. fsm.PostMsg(msg, args);
  472. return true;
  473. }
  474. private bool InvokeCreateWafer(string arg1, object[] args)
  475. {
  476. ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
  477. int slot = (int)args[1];
  478. WaferStatus state = WaferStatus.Normal;
  479. if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
  480. {
  481. if (WaferManager.Instance.CheckHasWafer(chamber, slot))
  482. {
  483. LOG.Write(eEvent.EV_ROUTER, "System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot));
  484. }
  485. else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null)
  486. {
  487. LOG.Write(eEvent.EV_WAFER_CREATE, ModuleName.System, chamber.ToString(), (slot + 1).ToString(), state.ToString());
  488. }
  489. }
  490. else
  491. {
  492. LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
  493. return false;
  494. }
  495. return true;
  496. }
  497. private bool InvokeDeleteWafer(string arg1, object[] args)
  498. {
  499. ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
  500. int slot = (int)args[1];
  501. if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
  502. {
  503. if (WaferManager.Instance.CheckHasWafer(chamber, slot))
  504. {
  505. WaferManager.Instance.DeleteWafer(chamber, slot);
  506. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDelete, chamber.ToString(), slot + 1);
  507. }
  508. else
  509. {
  510. LOG.Write(eEvent.EV_ROUTER, "System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1));
  511. }
  512. }
  513. else
  514. {
  515. LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
  516. return false;
  517. }
  518. return true;
  519. }
  520. private bool InvokeReturnWafer(string arg1, object[] args)
  521. {
  522. ModuleName target = ModuleHelper.Converter(args[0].ToString());
  523. int slot = (int)args[1];
  524. if (ModuleHelper.IsLoadPort(target))
  525. {
  526. LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Wafer already at LoadPort {0} {1}, return operation is not valid", target.ToString(), slot + 1));
  527. return false;
  528. }
  529. if (!WaferManager.Instance.IsWaferSlotLocationValid(target, slot))
  530. {
  531. LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", target.ToString(), slot.ToString()));
  532. return false;
  533. }
  534. WaferInfo wafer = WaferManager.Instance.GetWafer(target, slot);
  535. if (wafer.IsEmpty)
  536. {
  537. LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("No wafer at {0} {1}, return operation is not valid", target.ToString(), slot + 1));
  538. return false;
  539. }
  540. return CheckToPostMessage((int)MSG.MoveWafer,
  541. target, slot,
  542. (ModuleName)wafer.OriginStation, wafer.OriginSlot,
  543. false, 0, false, 0, "Blade1");
  544. }
  545. protected override bool Init()
  546. {
  547. _jobCycle = new JobDispatcher();
  548. Singleton<FaRemoteManager>.Instance.JobCycle = _jobCycle;
  549. _homeAllRoutine = new ModuleHomeAllRoutine("System");
  550. BuildTransitionTable();
  551. return true;
  552. }
  553. private void BuildTransitionTable()
  554. {
  555. //Init sequence
  556. Transition(RtState.Init, MSG.HOME, FsmStartHome, RtState.Initializing);
  557. Transition(RtState.Idle, MSG.HOME, FsmStartHome, RtState.Initializing);
  558. Transition(RtState.Error, MSG.HOME, FsmStartHome, RtState.Initializing);
  559. EnterExitTransition<RtState, FSM_MSG>(RtState.AutoRunning, FsmEnterAutoRunning, FSM_MSG.NONE, FsmExitAutoTransfer);
  560. EnterExitTransition<RtState, FSM_MSG>(RtState.Transfer, null, FSM_MSG.NONE, FsmExitTransfer);
  561. EnterExitTransition<RtState, FSM_MSG>(RtState.ReturnWafer, null, FSM_MSG.NONE, FsmExitReturnWafer);
  562. AnyStateTransition(MSG.ERROR, FsmError, RtState.Error);
  563. Transition(RtState.Idle, FSM_MSG.TIMER, FsmMonitor, RtState.Idle);
  564. Transition(RtState.Init, FSM_MSG.TIMER, FsmMonitor, RtState.Init);
  565. Transition(RtState.Init, MSG.ABORT, FsmAbort, RtState.Init);
  566. Transition(RtState.Error, MSG.ABORT, FsmAbort, RtState.Init);
  567. Transition(RtState.Idle, MSG.ABORT, FsmAbort, RtState.Idle);
  568. Transition(RtState.Initializing, MSG.ABORT, FsmAbort, RtState.Init);
  569. Transition(RtState.Initializing, FSM_MSG.TIMER, FsmMonitorHome, RtState.Idle);
  570. Transition(RtState.Initializing, MSG.ERROR, FsmError, RtState.Error);
  571. //Auto/manual
  572. Transition(RtState.Idle, MSG.SetAutoMode, FsmStartAutoTransfer, RtState.AutoIdle);
  573. Transition(RtState.AutoAborting, FSM_MSG.TIMER, FsmAutoTransfer, RtState.AutoIdle);
  574. Transition(RtState.AutoRunning, FSM_MSG.TIMER, FsmAutoTransfer, RtState.AutoIdle);
  575. Transition(RtState.AutoRunning, MSG.ABORT, FsmAbort, RtState.AutoAborting);
  576. Transition(RtState.AutoAborting, MSG.SetManualMode, FsmStartAbortingSetManualMode, RtState.Idle);
  577. //Transition(RtState.AutoRunning, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
  578. Transition(RtState.AutoRunning, MSG.JobDone, FsmJobDone, RtState.AutoIdle);
  579. //Transition(RtState.AutoRunning, MSG.CassetteLeave, fCassetteLeave, RtState.AutoRunning); //For unload light control off afer job done
  580. Transition(RtState.AutoRunning, MSG.CreateJob, FsmCreateJob, RtState.AutoRunning);
  581. Transition(RtState.AutoRunning, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
  582. Transition(RtState.AutoRunning, MSG.PauseJob, FsmPauseJob, RtState.AutoRunning);
  583. Transition(RtState.AutoRunning, MSG.PauseAllJobs, FsmPauseAllJobs, RtState.AutoRunning);
  584. Transition(RtState.AutoRunning, MSG.ResumeJob, FsmResumeJob, RtState.AutoRunning);
  585. Transition(RtState.AutoRunning, MSG.ResumeAllJobs, FsmResumeAllJobs, RtState.AutoRunning);
  586. Transition(RtState.AutoRunning, MSG.StopJob, FsmStopJob, RtState.AutoRunning);
  587. Transition(RtState.AutoRunning, MSG.Retry, FsmRetry, RtState.AutoRunning);
  588. Transition(RtState.AutoRunning, MSG.ConfirmComplete, FsmConfirmComplete, RtState.AutoRunning);
  589. Transition(RtState.AutoIdle, FSM_MSG.TIMER, FsmMonitorAutoIdle, RtState.AutoIdle);
  590. Transition(RtState.AutoIdle, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
  591. Transition(RtState.AutoIdle, MSG.CreateJob, FsmCreateJob, RtState.AutoIdle);
  592. Transition(RtState.AutoIdle, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
  593. Transition(RtState.AutoIdle, MSG.PauseJob, FsmPauseJob, RtState.AutoIdle);
  594. Transition(RtState.AutoIdle, MSG.PauseAllJobs, FsmPauseAllJobs, RtState.AutoIdle);
  595. Transition(RtState.AutoIdle, MSG.ResumeJob, FsmResumeJob, RtState.AutoIdle);
  596. Transition(RtState.AutoIdle, MSG.ResumeAllJobs, FsmResumeAllJobs, RtState.AutoIdle);
  597. Transition(RtState.AutoIdle, MSG.StopJob, FsmStopJob, RtState.AutoIdle);
  598. Transition(RtState.AutoIdle, MSG.FaStartJob, FsmEnterAutoRunning, RtState.AutoRunning);
  599. Transition(RtState.AutoRunning, MSG.FaStartJob, FsmEnterAutoRunning, RtState.AutoRunning);
  600. Transition(RtState.AutoIdle, MSG.ResetWafers, ResetWafers, RtState.AutoIdle);
  601. Transition(RtState.Idle, MSG.ResetWafers, ResetWafers, RtState.Idle);
  602. Transition(RtState.Init, MSG.ResetWafers, ResetWafers, RtState.Init);
  603. }
  604. private bool FsmMonitor(object[] objs)
  605. {
  606. return true;
  607. }
  608. /// <summary>
  609. /// 检验前置条件
  610. /// </summary>
  611. /// <returns></returns>
  612. private bool CheckPreCondition()
  613. {
  614. if (ModuleHelper.IsInstalled(ModuleName.PUF1))
  615. {
  616. PufVacuum pufVacuum = DEVICE.GetDevice<PufVacuum>($"{ModuleName.PUF1}.Vacuum");
  617. if (!pufVacuum.IsChuckAReleased || !pufVacuum.ISChuckBReleased)
  618. {
  619. LOG.WriteLog(eEvent.ERR_AXIS, ModuleName.PUF1.ToString(), "Vacuum is on");
  620. return false;
  621. }
  622. }
  623. if (ModuleHelper.IsInstalled(ModuleName.Loader1))
  624. {
  625. LoaderSideDevice loaderSideADevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideA");
  626. LoaderSideDevice loaderSideBDevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideB");
  627. if (loaderSideADevice.SideData.CRSVacuum || loaderSideBDevice.SideData.CRSVacuum)
  628. {
  629. LOG.WriteLog(eEvent.ERR_AXIS, ModuleName.Loader1.ToString(), "Vacuum is on");
  630. return false;
  631. }
  632. }
  633. if (ModuleHelper.IsInstalled(ModuleName.SRD1))
  634. {
  635. SrdCommonDevice srdCommonDevice = DEVICE.GetDevice<SrdCommonDevice>($"{ModuleName.SRD1}.Common");
  636. if (!srdCommonDevice.CommonData.ChuckVacuum)
  637. {
  638. LOG.WriteLog(eEvent.ERR_AXIS, ModuleName.SRD1.ToString(), "Vacuum is on");
  639. return false;
  640. }
  641. }
  642. if (ModuleHelper.IsInstalled(ModuleName.SRD2))
  643. {
  644. SrdCommonDevice srdCommonDevice = DEVICE.GetDevice<SrdCommonDevice>($"{ModuleName.SRD2}.Common");
  645. if (!srdCommonDevice.CommonData.ChuckVacuum)
  646. {
  647. LOG.WriteLog(eEvent.ERR_AXIS, ModuleName.SRD2.ToString(), "Vacuum is on");
  648. return false;
  649. }
  650. }
  651. return true;
  652. }
  653. private bool FsmStartHome(object[] objs)
  654. {
  655. if (!CheckPreCondition())
  656. {
  657. return false;
  658. }
  659. List<string> keys = _moduleEntitiesDic.Keys.ToList();
  660. foreach (string item in keys)
  661. {
  662. if (!NeedSequenceHome(item))
  663. {
  664. IModuleEntity entity = _moduleEntitiesDic[item];
  665. if (!entity.IsDisable)
  666. {
  667. entity.Invoke("HomeAll");
  668. }
  669. }
  670. }
  671. _homeAllRoutine.Start();
  672. _reservoirMetalRoutines.Clear();
  673. foreach (string item in keys)
  674. {
  675. if (Enum.TryParse(item, out ModuleName moduleName))
  676. {
  677. if (ModuleHelper.IsReservoir(moduleName))
  678. {
  679. IModuleEntity moduleEntity = _moduleEntitiesDic[item];
  680. if (!moduleEntity.IsDisable)
  681. {
  682. ReservoirMetalHomeRoutine reservoirMetalHomeRoutine = new ReservoirMetalHomeRoutine(item);
  683. _reservoirMetalRoutines.Add(reservoirMetalHomeRoutine);
  684. }
  685. }
  686. }
  687. }
  688. foreach (ReservoirMetalHomeRoutine item in _reservoirMetalRoutines)
  689. {
  690. item.Start();
  691. }
  692. _homeStopWatch.Restart();
  693. _jobCycle.RemoveAllJob();
  694. return true;
  695. }
  696. /// <summary>
  697. /// 需要按照顺序Home
  698. /// </summary>
  699. /// <returns></returns>
  700. private bool NeedSequenceHome(string item)
  701. {
  702. bool result = item == ModuleName.PUF1.ToString() || item == ModuleName.Loader1.ToString() ||
  703. item == ModuleName.Transporter2.ToString() || item == ModuleName.Transporter1.ToString();
  704. if (result)
  705. {
  706. return true;
  707. }
  708. else
  709. {
  710. if(Enum.TryParse(item,out ModuleName moduleName))
  711. {
  712. if (!ModuleHelper.IsMetal(moduleName)&&!ModuleHelper.IsReservoir(moduleName))
  713. {
  714. return false;
  715. }
  716. }
  717. return true;
  718. }
  719. }
  720. private bool FsmMonitorHome(object[] objs)
  721. {
  722. RState rstate = _homeAllRoutine.Monitor();
  723. if (_homeStopWatch.ElapsedMilliseconds <= 500)
  724. {
  725. return false;
  726. }
  727. if (rstate == RState.Failed || rstate == RState.Timeout)
  728. {
  729. PostMsg(MSG.ERROR);
  730. return false;
  731. }
  732. List<string> keys = LoadInitializeCheckModuleList();
  733. int idleCount = 0;
  734. foreach (string item in keys)
  735. {
  736. IModuleEntity ModuleEntity = _moduleEntitiesDic[item];
  737. if (ModuleEntity.IsError && !NeedSequenceHome(item))
  738. {
  739. LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"{ModuleEntity.Module} home error");
  740. PostMsg(MSG.ERROR);
  741. return true;
  742. }
  743. else if (ModuleEntity.IsIdle)
  744. {
  745. idleCount++;
  746. }
  747. }
  748. int homeCount = 0;
  749. foreach (ReservoirMetalHomeRoutine item in _reservoirMetalRoutines)
  750. {
  751. RState ret = item.Monitor();
  752. if (ret != RState.Running)
  753. {
  754. homeCount++;
  755. }
  756. }
  757. if (homeCount != _reservoirMetalRoutines.Count)
  758. {
  759. return false;
  760. }
  761. if (idleCount == keys.Count)
  762. {
  763. return true;
  764. }
  765. else
  766. {
  767. return false;
  768. }
  769. }
  770. /// <summary>
  771. /// 加载初始化检验模块集合
  772. /// </summary>
  773. /// <returns></returns>
  774. private List<string> LoadInitializeCheckModuleList()
  775. {
  776. string checkModuleList = SC.GetStringValue("System.InitializeCheckModuleList");
  777. List<string> moduleList= checkModuleList.Split(',').ToList();
  778. List<string> modules = new List<string>();
  779. foreach (var item in moduleList)
  780. {
  781. if(Enum.TryParse(item, out ModuleName moduleName))
  782. {
  783. if (ModuleHelper.IsInstalled(moduleName))
  784. {
  785. modules.Add(item);
  786. }
  787. }
  788. }
  789. return modules;
  790. }
  791. private bool FsmEnterAutoRunning(object[] objs)
  792. {
  793. return true;
  794. }
  795. private bool FsmExitAutoTransfer(object[] objs)
  796. {
  797. _jobCycle.Clear();
  798. return true;
  799. }
  800. private bool FsmExitTransfer(object[] objs)
  801. {
  802. return true;
  803. }
  804. private bool FsmExitReturnWafer(object[] objs)
  805. {
  806. return true;
  807. }
  808. private bool FsmError(object[] objs)
  809. {
  810. return true;
  811. }
  812. private bool FsmAbort(object[] objs)
  813. {
  814. //_manualTransfer.Clear();
  815. //_returnWafer.Clear();
  816. //_jobCycle.Clear();
  817. AlarmListManager.Instance.ClearAllAlarm();
  818. return _jobCycle.SystemAbort();
  819. }
  820. private bool FsmStartAutoTransfer(object[] objs)
  821. {
  822. return _jobCycle.Start(objs) == RState.Running;
  823. }
  824. private bool FsmAutoTransfer(object[] objs)
  825. {
  826. if (_jobCycle.CheckJobJustDone(out string jobInfo))
  827. {
  828. //EV.PostPopDialogMessage(EventLevel.InformationNoDelay, "Job complete", jobInfo);
  829. LOG.Write(eEvent.EV_ROUTER, ModuleName.System, $"Job complete,{jobInfo}");
  830. }
  831. if (_jobCycle.CheckAllJobDone())
  832. {
  833. if (!CheckToPostMessage((int)MSG.JobDone))
  834. return false;
  835. }
  836. RState ret = _jobCycle.Monitor();
  837. if (ret == RState.Failed)
  838. {
  839. if (!CheckToPostMessage((int)MSG.ERROR))
  840. return false;
  841. }
  842. return ret == RState.End;
  843. }
  844. private bool FsmAbortAutoTransfer(object[] objs)
  845. {
  846. _jobCycle.Clear();
  847. return true;
  848. }
  849. private bool FsmJobDone(object[] objs)
  850. {
  851. return true;
  852. }
  853. private bool FsmCreateJob(object[] objs)
  854. {
  855. return _jobCycle.CreateJob((Dictionary<string, object>)objs[0],out string reason);
  856. }
  857. private bool FsmStartJob(object[] objs)
  858. {
  859. return _jobCycle.StartJob((string)objs[0],out string reason);
  860. }
  861. private bool FsmPauseJob(object[] objs)
  862. {
  863. return _jobCycle.PauseJob((string)objs[0],out string reason);
  864. }
  865. private bool FsmResumeJob(object[] objs)
  866. {
  867. return _jobCycle.ResumeJob((string)objs[0],out string reason);
  868. }
  869. private bool FsmPauseAllJobs(object[] objs)
  870. {
  871. return _jobCycle.PauseAllJobs();
  872. }
  873. private bool FsmResumeAllJobs(object[] objs)
  874. {
  875. return _jobCycle.ResumeAllJobs();
  876. }
  877. private bool FsmStopJob(object[] objs)
  878. {
  879. return _jobCycle.StopJob((string)objs[0], out string reason);
  880. }
  881. /// <summary>
  882. /// 重试
  883. /// </summary>
  884. /// <param name="objs"></param>
  885. /// <returns></returns>
  886. private bool FsmRetry(object[] objs)
  887. {
  888. string moduleName = objs[0].ToString();
  889. IModuleEntity moduleEntity = GetModule<IModuleEntity>(moduleName);
  890. moduleEntity.Invoke("Retry");
  891. return true;
  892. }
  893. /// <summary>
  894. /// 重试
  895. /// </summary>
  896. /// <param name="objs"></param>
  897. /// <returns></returns>
  898. private bool FsmConfirmComplete(object[] objs)
  899. {
  900. string moduleName = objs[0].ToString();
  901. IModuleEntity moduleEntity = GetModule<IModuleEntity>(moduleName);
  902. moduleEntity.Invoke("ConfirmComplete");
  903. return true;
  904. }
  905. private bool FsmMonitorAutoIdle(object[] objs)
  906. {
  907. RState ret = _jobCycle.Monitor();
  908. return ret == RState.End;
  909. }
  910. private bool FsmStartAbortingSetManualMode(object[] objs)
  911. {
  912. return _jobCycle.RemoveAllJob();
  913. }
  914. private bool FsmStartSetManualMode(object[] objs)
  915. {
  916. if (_jobCycle.HasJobRunning)
  917. {
  918. LOG.Write(eEvent.WARN_ROUTER, "System", "Can not change to manual mode, abort running job first");
  919. return false;
  920. }
  921. return true;
  922. }
  923. /// <summary>
  924. /// 重置Wafers
  925. /// </summary>
  926. /// <param name="objs"></param>
  927. /// <returns></returns>
  928. private bool ResetWafers(object[] objs)
  929. {
  930. return WaferHolderManager.Instance.ResetLayoutWafers();
  931. }
  932. /// <summary>
  933. /// 获取模块对象
  934. /// </summary>
  935. /// <typeparam name="T"></typeparam>
  936. /// <param name="name"></param>
  937. /// <returns></returns>
  938. public T GetModule<T>(string name) where T : class, IModuleEntity
  939. {
  940. return _moduleEntitiesDic.ContainsKey(name)?_moduleEntitiesDic[name] as T:default(T);
  941. }
  942. /// <summary>
  943. /// 根据模块类型获取模块集合
  944. /// </summary>
  945. /// <param name="type"></param>
  946. /// <returns></returns>
  947. public List<IModuleEntity> GetModulesByModuleType(ModuleType type)
  948. {
  949. return _modultTypeEntitiesDic.ContainsKey(type) ? _modultTypeEntitiesDic[type] : new List<IModuleEntity>();
  950. }
  951. }
  952. }