RouteManager.cs 41 KB

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