RouteManager.cs 39 KB

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