RouteManager.cs 37 KB

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