RouteManager.cs 38 KB

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