RouteManager.cs 38 KB

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