RouteManager.cs 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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 Aitex.Core.RT.Device;
  22. using MECF.Framework.Common.ToolLayout;
  23. using MECF.Framework.Common.Routine;
  24. using PunkHPX8_RT.Dispatch;
  25. using PunkHPX8_RT.Modules.Reservoir;
  26. using System.IO;
  27. using PunkHPX8_RT.Modules.Transporter;
  28. using PunkHPX8_RT.Devices.SRD;
  29. using MECF.Framework.Common.Alarm;
  30. using System.Diagnostics;
  31. using PunkHPX8_RT.Schedulers;
  32. using MECF.Framework.Common.ProcessCell;
  33. using System.Reflection;
  34. using PunkHPX8_RT.Modules.VpwMain;
  35. using PunkHPX8_RT.Modules.PlatingCell;
  36. using PunkHPX8_RT.Devices.EFEM;
  37. namespace PunkHPX8_RT.Modules
  38. {
  39. class RouteManager : Entity, IEntity
  40. {
  41. public enum MSG
  42. {
  43. MoveWafer,
  44. ReturnWafer,
  45. HomeUnit,
  46. PauseAuto,
  47. ResumeAuto,
  48. Stop,
  49. StartCycle,
  50. StopCycle,
  51. HOME,
  52. RESET,
  53. ABORT,
  54. ERROR,
  55. SetAutoMode,
  56. SetManualMode,
  57. ResetIdleCleanTime,
  58. ResetIdlePurgeTime,
  59. CreateJob,
  60. PauseJob,
  61. PauseAllJobs,
  62. ResumeJob,
  63. ResumeAllJobs,
  64. StartJob,
  65. StopJob,
  66. AbortJob,
  67. JobDone,
  68. CassetteLeave, //For unload light control off afer job done
  69. Map,
  70. ReturnAllWafer,
  71. TMCycle,
  72. Retry,
  73. ConfirmComplete,
  74. ResetWafers,
  75. FaStartJob,
  76. FaStopJob,
  77. }
  78. #region 属性
  79. public string Name { get; set; }
  80. public bool IsAutoMode
  81. {
  82. get
  83. {
  84. return fsm.State == (int)RtState.AutoRunning || fsm.State == (int)RtState.AutoIdle||fsm.State==(int)RtState.AutoAborting;
  85. }
  86. }
  87. public bool IsFaAutoMode
  88. {
  89. get
  90. {
  91. return fsm.State == (int)RtState.AutoRunning || fsm.State == (int)RtState.AutoIdle;
  92. }
  93. }
  94. public bool IsInit
  95. {
  96. get { return fsm.State == (int)RtState.Init; }
  97. }
  98. public bool IsIdle
  99. {
  100. get { return fsm.State == (int)RtState.Idle || fsm.State == (int)RtState.AutoIdle; }
  101. }
  102. public bool IsAlarm
  103. {
  104. get { return fsm.State == (int)RtState.Error; }
  105. }
  106. public bool IsPaused
  107. {
  108. get { return _jobCycle.CycleState == RState.Paused; }
  109. }
  110. public bool IsRunning
  111. {
  112. get
  113. {
  114. return !IsInit && !IsAlarm && !IsIdle;
  115. }
  116. }
  117. /// <summary>
  118. /// 是否AutoRunning
  119. /// </summary>
  120. public bool IsAutoRunning
  121. {
  122. get { return fsm.State == (int)RtState.AutoRunning||fsm.State==(int)RtState.AutoAborting; }
  123. }
  124. /// <summary>
  125. /// 是否
  126. /// </summary>
  127. public bool IsAutoIdle
  128. {
  129. get { return fsm.State == (int)RtState.AutoIdle; }
  130. }
  131. /// <summary>
  132. /// EFEM实体
  133. /// </summary>
  134. public EfemEntity EFEM { get; }
  135. public WaferSize WaferSize { get; private set; }
  136. #endregion
  137. #region 内部变量
  138. private string _systemControlIp;
  139. private ICycle _jobCycle;
  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. /// <summary>
  153. ///
  154. /// </summary>
  155. private List<ReservoirCellHomeRoutine> _reservoirCellRoutines = new List<ReservoirCellHomeRoutine>();
  156. #endregion
  157. /// <summary>
  158. /// 构造函数
  159. /// </summary>
  160. public RouteManager()
  161. {
  162. Name = "System";
  163. WaferSize = (WaferSize)SC.GetValue<int>("System.WaferSize");
  164. if (ModuleHelper.IsInstalled(ModuleName.EFEM))
  165. {
  166. EFEM = new EfemEntity();
  167. EFEM.Initialize();
  168. _moduleEntitiesDic[ModuleName.EFEM.ToString()] = EFEM;
  169. }
  170. InitialModuleList(VpwMainItemManager.Instance.InstalledModules, typeof(VpwMainEntity), ModuleType.VpwMain);
  171. InitialModuleList(VpwCellItemManager.Instance.InstalledModules, typeof(VpwCellEntity), ModuleType.VPW);
  172. InitialModuleList(SrdItemManager.Instance.InstalledModules, typeof(SRDEntity), ModuleType.SRD);
  173. InitialModuleList(ReservoirItemManager.Instance.InstalledModules, typeof(ReservoirEntity), ModuleType.Reservoir);
  174. InitialModuleList(PlatingCellItemManager.Instance.InstalledModules, typeof(PlatingCellEntity), ModuleType.PlatingCell);
  175. InitialPlatingCellVerticalModuleList();
  176. fsm = new StateMachine<RouteManager>(Name, (int)RtState.Init, 200);
  177. SubscribeOperation();
  178. SubscribeDataVariable();
  179. }
  180. /// <summary>
  181. /// 初始化模块集合
  182. /// </summary>
  183. /// <param name="lst"></param>
  184. /// <param name="entityType"></param>
  185. private void InitialModuleList(List<string> lst,Type entityType,ModuleType moduleType)
  186. {
  187. foreach(string item in lst)
  188. {
  189. InitialModule(item, entityType,moduleType);
  190. }
  191. }
  192. /// <summary>
  193. /// 初始化PlatingCellVertical
  194. /// </summary>
  195. private void InitialPlatingCellVerticalModuleList()
  196. {
  197. List<string> lst = ModuleMatcherManager.Instance.GetAllPlatingCellVertialList();
  198. InitialModuleList(lst,typeof(PlatingCellVerticalEntity),ModuleType.PlatingCellVertical);
  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.SetWaferSize", (string cmd, object[] args) =>
  354. {
  355. string module = (string)args[0];
  356. string size = (string)args[1];
  357. switch (size)
  358. {
  359. case "3":
  360. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS3);
  361. break;
  362. case "4":
  363. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS4);
  364. break;
  365. case "6":
  366. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS6);
  367. break;
  368. default:
  369. EV.PostWarningLog("System", $"wafer size {size} not valid");
  370. break;
  371. }
  372. return true;
  373. });
  374. //OP.Subscribe("System.CassetteLeave", (string cmd, object[] args) =>
  375. //{
  376. // return CheckToPostMessage((int)MSG.CassetteLeave);
  377. //});
  378. OP.Subscribe("System.Retry", (string cmd, object[] args) =>
  379. {
  380. return CheckToPostMessage((int)MSG.Retry, args[0]);
  381. });
  382. OP.Subscribe("System.ConfirmComplete", (string cmd, object[] args) =>
  383. {
  384. return CheckToPostMessage((int)MSG.ConfirmComplete, args[0]);
  385. });
  386. OP.Subscribe("WaferHolder.ResetLayoutWafers", (string cmd, object[] args) =>
  387. {
  388. return CheckToPostMessage((int)MSG.ResetWafers, args);
  389. });
  390. }
  391. /// <summary>
  392. /// 申请系统控制权
  393. /// </summary>
  394. /// <param name="cmd"></param>
  395. /// <param name="args"></param>
  396. /// <returns></returns>
  397. private bool ApplySystemControl(string cmd, object[] args)
  398. {
  399. if (args[0].ToString() == "")
  400. {
  401. LOG.WriteLog(eEvent.WARN_ROUTER, "System", $"Current IP does not allow the application of UI control permissions");
  402. return false;
  403. }
  404. string applyIp = args[0].ToString();
  405. if (string.IsNullOrEmpty(_systemControlIp))
  406. {
  407. _systemControlIp = applyIp;
  408. LOG.WriteLog(eEvent.EV_ROUTER, "System", $"{_systemControlIp} apply system control success");
  409. return true;
  410. }
  411. else if(_systemControlIp!=applyIp)
  412. {
  413. LOG.WriteLog(eEvent.WARN_ROUTER, "System", $"{_systemControlIp} already has system control permission");
  414. return false;
  415. }
  416. return false;
  417. }
  418. /// <summary>
  419. /// 释放系统控制权
  420. /// </summary>
  421. /// <param name="cmd"></param>
  422. /// <param name="args"></param>
  423. /// <returns></returns>
  424. private bool ReleaseSystemControl(string cmd, object[] args)
  425. {
  426. string releaseIp = args[0].ToString();
  427. if (_systemControlIp == releaseIp)
  428. {
  429. LOG.WriteLog(eEvent.EV_ROUTER, "System", $"{releaseIp} release system control success");
  430. _systemControlIp = "";
  431. }
  432. else
  433. {
  434. LOG.WriteLog(eEvent.ERR_ROUTER, "System", $"{releaseIp} is not SystemControlIp");
  435. }
  436. return false;
  437. }
  438. /// <summary>
  439. /// 检验Secsgem在线情况
  440. /// </summary>
  441. /// <param name="controlState"></param>
  442. /// <returns></returns>
  443. private bool CheckSecsGemOnline(SecsGem.Core.EnumData.ControlState controlState)
  444. {
  445. if (controlState == SecsGem.Core.EnumData.ControlState.OnlineLocal || controlState == SecsGem.Core.EnumData.ControlState.OnlineRemote)
  446. {
  447. return true;
  448. }
  449. return false;
  450. }
  451. public bool CheckToPostMessage(int msg, params object[] args)
  452. {
  453. if (!fsm.FindTransition(fsm.State, msg))
  454. {
  455. LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, $"System is in {(RtState)fsm.State} state,can not do {(MSG)msg}");
  456. return false;
  457. }
  458. Running = true;
  459. fsm.PostMsg(msg, args);
  460. return true;
  461. }
  462. private bool InvokeCreateWafer(string arg1, object[] args)
  463. {
  464. ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
  465. int slot = (int)args[1];
  466. WaferStatus state = WaferStatus.Normal;
  467. WaferType waferType = WaferType.Production;
  468. WaferSize waferSize = WaferSize.WS8;
  469. if (ModuleHelper.IsDummy(chamber))
  470. {
  471. waferType = WaferType.Assit;
  472. DummyDevice dummyDevice = Singleton<RouteManager>.Instance.EFEM.GetDummyDevice((int)chamber-(int)ModuleName.Dummy1);
  473. waferSize = dummyDevice.WaferSize;
  474. }
  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,waferType,waferSize) != 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. protected override bool Init()
  517. {
  518. _jobCycle = new JobDispatcher();
  519. Singleton<FaRemoteManager>.Instance.JobCycle = _jobCycle;
  520. BuildTransitionTable();
  521. return true;
  522. }
  523. private void BuildTransitionTable()
  524. {
  525. //Init sequence
  526. Transition(RtState.Init, MSG.HOME, FsmStartHome, RtState.Initializing);
  527. Transition(RtState.Idle, MSG.HOME, FsmStartHome, RtState.Initializing);
  528. Transition(RtState.Error, MSG.HOME, FsmStartHome, RtState.Initializing);
  529. EnterExitTransition<RtState, FSM_MSG>(RtState.AutoRunning, FsmEnterAutoRunning, FSM_MSG.NONE, FsmExitAutoTransfer);
  530. EnterExitTransition<RtState, FSM_MSG>(RtState.Transfer, null, FSM_MSG.NONE, FsmExitTransfer);
  531. EnterExitTransition<RtState, FSM_MSG>(RtState.ReturnWafer, null, FSM_MSG.NONE, FsmExitReturnWafer);
  532. AnyStateTransition(MSG.ERROR, FsmError, RtState.Error);
  533. Transition(RtState.Idle, FSM_MSG.TIMER, FsmMonitor, RtState.Idle);
  534. Transition(RtState.Init, FSM_MSG.TIMER, FsmMonitor, RtState.Init);
  535. Transition(RtState.Init, MSG.ABORT, FsmAbort, RtState.Init);
  536. Transition(RtState.Error, MSG.ABORT, FsmAbort, RtState.Init);
  537. Transition(RtState.Idle, MSG.ABORT, FsmAbort, RtState.Idle);
  538. Transition(RtState.Initializing, MSG.ABORT, FsmAbort, RtState.Init);
  539. Transition(RtState.Initializing, FSM_MSG.TIMER, FsmMonitorHome, RtState.Idle);
  540. Transition(RtState.Initializing, MSG.ERROR, FsmError, RtState.Error);
  541. //Auto/manual
  542. Transition(RtState.Idle, MSG.SetAutoMode, FsmStartAutoTransfer, RtState.AutoIdle);
  543. Transition(RtState.AutoAborting, FSM_MSG.TIMER, FsmAutoTransfer, RtState.AutoIdle);
  544. Transition(RtState.AutoRunning, FSM_MSG.TIMER, FsmAutoTransfer, RtState.AutoIdle);
  545. Transition(RtState.AutoRunning, MSG.ABORT, FsmAbort, RtState.AutoAborting);
  546. Transition(RtState.AutoAborting, MSG.SetManualMode, FsmStartAbortingSetManualMode, RtState.Idle);
  547. //Transition(RtState.AutoRunning, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
  548. Transition(RtState.AutoRunning, MSG.JobDone, FsmJobDone, RtState.AutoIdle);
  549. //Transition(RtState.AutoRunning, MSG.CassetteLeave, fCassetteLeave, RtState.AutoRunning); //For unload light control off afer job done
  550. Transition(RtState.AutoRunning, MSG.CreateJob, FsmCreateJob, RtState.AutoRunning);
  551. Transition(RtState.AutoRunning, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
  552. Transition(RtState.AutoRunning, MSG.PauseJob, FsmPauseJob, RtState.AutoRunning);
  553. Transition(RtState.AutoRunning, MSG.PauseAllJobs, FsmPauseAllJobs, RtState.AutoRunning);
  554. Transition(RtState.AutoRunning, MSG.ResumeJob, FsmResumeJob, RtState.AutoRunning);
  555. Transition(RtState.AutoRunning, MSG.ResumeAllJobs, FsmResumeAllJobs, RtState.AutoRunning);
  556. Transition(RtState.AutoRunning, MSG.StopJob, FsmStopJob, RtState.AutoRunning);
  557. Transition(RtState.AutoRunning, MSG.Retry, FsmRetry, RtState.AutoRunning);
  558. Transition(RtState.AutoRunning, MSG.ConfirmComplete, FsmConfirmComplete, RtState.AutoRunning);
  559. Transition(RtState.AutoIdle, FSM_MSG.TIMER, FsmMonitorAutoIdle, RtState.AutoIdle);
  560. Transition(RtState.AutoIdle, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
  561. Transition(RtState.AutoIdle, MSG.CreateJob, FsmCreateJob, RtState.AutoIdle);
  562. Transition(RtState.AutoIdle, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
  563. Transition(RtState.AutoIdle, MSG.PauseJob, FsmPauseJob, RtState.AutoIdle);
  564. Transition(RtState.AutoIdle, MSG.PauseAllJobs, FsmPauseAllJobs, RtState.AutoIdle);
  565. Transition(RtState.AutoIdle, MSG.ResumeJob, FsmResumeJob, RtState.AutoIdle);
  566. Transition(RtState.AutoIdle, MSG.ResumeAllJobs, FsmResumeAllJobs, RtState.AutoIdle);
  567. Transition(RtState.AutoIdle, MSG.StopJob, FsmStopJob, RtState.AutoIdle);
  568. Transition(RtState.AutoIdle, MSG.FaStartJob, FsmEnterAutoRunning, RtState.AutoRunning);
  569. Transition(RtState.AutoRunning, MSG.FaStartJob, FsmEnterAutoRunning, RtState.AutoRunning);
  570. }
  571. private bool FsmMonitor(object[] objs)
  572. {
  573. return true;
  574. }
  575. /// <summary>
  576. /// 检验前置条件
  577. /// </summary>
  578. /// <returns></returns>
  579. private bool CheckPreCondition()
  580. {
  581. if (ModuleHelper.IsInstalled(ModuleName.SRD1))
  582. {
  583. SrdCommonDevice srdCommonDevice = DEVICE.GetDevice<SrdCommonDevice>($"{ModuleName.SRD1}.Common");
  584. if (srdCommonDevice.CommonData.ChuckVacuum)
  585. {
  586. LOG.WriteLog(eEvent.ERR_AXIS, ModuleName.SRD1.ToString(), "Vacuum is on");
  587. return false;
  588. }
  589. }
  590. if (ModuleHelper.IsInstalled(ModuleName.SRD2))
  591. {
  592. SrdCommonDevice srdCommonDevice = DEVICE.GetDevice<SrdCommonDevice>($"{ModuleName.SRD2}.Common");
  593. if (srdCommonDevice.CommonData.ChuckVacuum)
  594. {
  595. LOG.WriteLog(eEvent.ERR_AXIS, ModuleName.SRD2.ToString(), "Vacuum is on");
  596. return false;
  597. }
  598. }
  599. return true;
  600. }
  601. private bool FsmStartHome(object[] objs)
  602. {
  603. if (!CheckPreCondition())
  604. {
  605. return false;
  606. }
  607. List<string> keys = _moduleEntitiesDic.Keys.ToList();
  608. foreach (string item in keys)
  609. {
  610. if(!Enum.TryParse(item, out ModuleName moduleName))
  611. {
  612. continue;
  613. }
  614. if (!NeedSequenceHome(item))
  615. {
  616. IModuleEntity entity = _moduleEntitiesDic[item];
  617. if (!entity.IsDisable&&!ModuleHelper.IsVPWCell(moduleName))
  618. {
  619. entity.Invoke("HomeAll");
  620. }
  621. }
  622. }
  623. _reservoirCellRoutines.Clear();
  624. foreach (string item in keys)
  625. {
  626. if (Enum.TryParse(item, out ModuleName moduleName))
  627. {
  628. if (ModuleHelper.IsReservoir(moduleName))
  629. {
  630. IModuleEntity moduleEntity = _moduleEntitiesDic[item];
  631. if (!moduleEntity.IsDisable)
  632. {
  633. ReservoirCellHomeRoutine reservoirCellHomeRoutine = new ReservoirCellHomeRoutine(item);
  634. _reservoirCellRoutines.Add(reservoirCellHomeRoutine);
  635. }
  636. }
  637. }
  638. }
  639. foreach (ReservoirCellHomeRoutine item in _reservoirCellRoutines)
  640. {
  641. item.Start();
  642. }
  643. _homeStopWatch.Restart();
  644. _jobCycle.RemoveAllJob();
  645. return true;
  646. }
  647. /// <summary>
  648. /// 需要按照顺序Home
  649. /// </summary>
  650. /// <returns></returns>
  651. private bool NeedSequenceHome(string item)
  652. {
  653. if(Enum.TryParse(item,out ModuleName moduleName))
  654. {
  655. if (!ModuleHelper.IsPlatingCell(moduleName)&&!ModuleHelper.IsReservoir(moduleName))
  656. {
  657. return false;
  658. }
  659. }
  660. return true;
  661. }
  662. private bool FsmMonitorHome(object[] objs)
  663. {
  664. if (_homeStopWatch.ElapsedMilliseconds <= 500)
  665. {
  666. return false;
  667. }
  668. List<string> keys = LoadInitializeCheckModuleList();
  669. int idleCount = 0;
  670. foreach (string item in keys)
  671. {
  672. IModuleEntity ModuleEntity = _moduleEntitiesDic[item];
  673. if (ModuleEntity.IsError)
  674. {
  675. LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"{ModuleEntity.Module} home error");
  676. PostMsg(MSG.ERROR);
  677. return true;
  678. }
  679. else if (ModuleEntity.IsIdle)
  680. {
  681. idleCount++;
  682. }
  683. }
  684. int homeCount = 0;
  685. foreach (ReservoirCellHomeRoutine item in _reservoirCellRoutines)
  686. {
  687. RState ret = item.Monitor();
  688. if (ret != RState.Running)
  689. {
  690. homeCount++;
  691. }
  692. }
  693. if (homeCount != _reservoirCellRoutines.Count)
  694. {
  695. return false;
  696. }
  697. if (idleCount == keys.Count)
  698. {
  699. return true;
  700. }
  701. else
  702. {
  703. return false;
  704. }
  705. }
  706. /// <summary>
  707. /// 加载初始化检验模块集合
  708. /// </summary>
  709. /// <returns></returns>
  710. private List<string> LoadInitializeCheckModuleList()
  711. {
  712. string checkModuleList = SC.GetStringValue("System.InitializeCheckModuleList");
  713. List<string> moduleList= checkModuleList.Split(',').ToList();
  714. List<string> modules = new List<string>();
  715. foreach (var item in moduleList)
  716. {
  717. if(Enum.TryParse(item, out ModuleName moduleName))
  718. {
  719. if (ModuleHelper.IsInstalled(moduleName))
  720. {
  721. modules.Add(item);
  722. }
  723. }
  724. }
  725. return modules;
  726. }
  727. private bool FsmEnterAutoRunning(object[] objs)
  728. {
  729. return true;
  730. }
  731. private bool FsmExitAutoTransfer(object[] objs)
  732. {
  733. _jobCycle.Clear();
  734. return true;
  735. }
  736. private bool FsmExitTransfer(object[] objs)
  737. {
  738. return true;
  739. }
  740. private bool FsmExitReturnWafer(object[] objs)
  741. {
  742. return true;
  743. }
  744. private bool FsmError(object[] objs)
  745. {
  746. return true;
  747. }
  748. private bool FsmAbort(object[] objs)
  749. {
  750. //_manualTransfer.Clear();
  751. //_returnWafer.Clear();
  752. //_jobCycle.Clear();
  753. AlarmListManager.Instance.ClearAllAlarm();
  754. return _jobCycle.SystemAbort();
  755. }
  756. private bool FsmStartAutoTransfer(object[] objs)
  757. {
  758. bool result= _jobCycle.Start(objs) == RState.Running;
  759. if (result)
  760. {
  761. SchedulerSequenceManager.Instance.ConfirmVPW();
  762. }
  763. return result;
  764. }
  765. private bool FsmAutoTransfer(object[] objs)
  766. {
  767. if (_jobCycle.CheckJobJustDone(out string jobInfo))
  768. {
  769. //EV.PostPopDialogMessage(EventLevel.InformationNoDelay, "Job complete", jobInfo);
  770. LOG.Write(eEvent.EV_ROUTER, ModuleName.System, $"Job complete,{jobInfo}");
  771. }
  772. if (_jobCycle.CheckAllJobDone())
  773. {
  774. if (!CheckToPostMessage((int)MSG.JobDone))
  775. return false;
  776. }
  777. RState ret = _jobCycle.Monitor();
  778. if (ret == RState.Failed)
  779. {
  780. if (!CheckToPostMessage((int)MSG.ERROR))
  781. return false;
  782. }
  783. return ret == RState.End;
  784. }
  785. private bool FsmAbortAutoTransfer(object[] objs)
  786. {
  787. _jobCycle.Clear();
  788. return true;
  789. }
  790. private bool FsmJobDone(object[] objs)
  791. {
  792. return true;
  793. }
  794. private bool FsmCreateJob(object[] objs)
  795. {
  796. return _jobCycle.CreateJob((Dictionary<string, object>)objs[0],out string reason);
  797. }
  798. private bool FsmStartJob(object[] objs)
  799. {
  800. return _jobCycle.StartJob((string)objs[0],out string reason);
  801. }
  802. private bool FsmPauseJob(object[] objs)
  803. {
  804. return _jobCycle.PauseJob((string)objs[0],out string reason);
  805. }
  806. private bool FsmResumeJob(object[] objs)
  807. {
  808. return _jobCycle.ResumeJob((string)objs[0],out string reason);
  809. }
  810. private bool FsmPauseAllJobs(object[] objs)
  811. {
  812. return _jobCycle.PauseAllJobs();
  813. }
  814. private bool FsmResumeAllJobs(object[] objs)
  815. {
  816. return _jobCycle.ResumeAllJobs();
  817. }
  818. private bool FsmStopJob(object[] objs)
  819. {
  820. return _jobCycle.StopJob((string)objs[0], out string reason);
  821. }
  822. /// <summary>
  823. /// 重试
  824. /// </summary>
  825. /// <param name="objs"></param>
  826. /// <returns></returns>
  827. private bool FsmRetry(object[] objs)
  828. {
  829. string moduleName = objs[0].ToString();
  830. IModuleEntity moduleEntity = GetModule<IModuleEntity>(moduleName);
  831. moduleEntity.Invoke("Retry");
  832. return true;
  833. }
  834. /// <summary>
  835. /// 重试
  836. /// </summary>
  837. /// <param name="objs"></param>
  838. /// <returns></returns>
  839. private bool FsmConfirmComplete(object[] objs)
  840. {
  841. string moduleName = objs[0].ToString();
  842. IModuleEntity moduleEntity = GetModule<IModuleEntity>(moduleName);
  843. moduleEntity.Invoke("ConfirmComplete");
  844. return true;
  845. }
  846. private bool FsmMonitorAutoIdle(object[] objs)
  847. {
  848. RState ret = _jobCycle.Monitor();
  849. return ret == RState.End;
  850. }
  851. private bool FsmStartAbortingSetManualMode(object[] objs)
  852. {
  853. return _jobCycle.RemoveAllJob();
  854. }
  855. private bool FsmStartSetManualMode(object[] objs)
  856. {
  857. if (_jobCycle.HasJobRunning)
  858. {
  859. LOG.Write(eEvent.WARN_ROUTER, "System", "Can not change to manual mode, abort running job first");
  860. return false;
  861. }
  862. return true;
  863. }
  864. /// <summary>
  865. /// 获取模块对象
  866. /// </summary>
  867. /// <typeparam name="T"></typeparam>
  868. /// <param name="name"></param>
  869. /// <returns></returns>
  870. public T GetModule<T>(string name) where T : class, IModuleEntity
  871. {
  872. return _moduleEntitiesDic.ContainsKey(name)?_moduleEntitiesDic[name] as T:default(T);
  873. }
  874. /// <summary>
  875. /// 根据模块类型获取模块集合
  876. /// </summary>
  877. /// <param name="type"></param>
  878. /// <returns></returns>
  879. public List<IModuleEntity> GetModulesByModuleType(ModuleType type)
  880. {
  881. return _modultTypeEntitiesDic.ContainsKey(type) ? _modultTypeEntitiesDic[type] : new List<IModuleEntity>();
  882. }
  883. }
  884. }