WaferHolderTask.cs 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  1. using Aitex.Core.RT.Log;
  2. using Aitex.Core.Util;
  3. using MECF.Framework.Common.Equipment;
  4. using MECF.Framework.Common.SubstrateTrackings;
  5. using MECF.Framework.Common.WaferHolder;
  6. using CyberX8_Core;
  7. using CyberX8_RT.Modules.Loader;
  8. using CyberX8_RT.Modules.PUF;
  9. using CyberX8_RT.Modules;
  10. using CyberX8_RT.Schedulers;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.ComponentModel;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using System.Windows.Documents;
  18. using Aitex.Core.Common;
  19. using MECF.Framework.Common.CommonData;
  20. using MECF.Framework.Common.Jobs;
  21. using Aitex.Core.RT.Fsm;
  22. using MECF.Framework.Common.RecipeCenter;
  23. using MECF.Framework.Common.ToolLayout;
  24. using Aitex.Core.RT.Routine;
  25. using CyberX8_RT.Schedulers.Transporter;
  26. using CyberX8_RT.Modules.Rinse;
  27. using Aitex.Core.RT.SCCore;
  28. using CyberX8_RT.Modules.Prewet;
  29. namespace CyberX8_RT.Dispatch
  30. {
  31. public enum WaferHolderTaskState
  32. {
  33. Created,
  34. Processing,
  35. End,
  36. Error,
  37. Canceled
  38. }
  39. /// <summary>
  40. /// WaferHolder
  41. /// </summary>
  42. /// <param name="info"></param>
  43. /// <param name="schedulerSequence"></param>
  44. public delegate void WaferHolderSchedulerComplete(WaferHolderInfo info, SchedulerSequence schedulerSequence);
  45. /// <summary>
  46. /// WaferHolderTask完成
  47. /// </summary>
  48. /// <param name="id"></param>
  49. public delegate void WaferHolderTaskComplete(string id);
  50. public class WaferHolderTask
  51. {
  52. #region 常量
  53. private const string PWT = "PWT";
  54. #endregion
  55. #region 内部变量
  56. /// <summary>
  57. /// 调度步骤
  58. /// </summary>
  59. private List<SchedulerSequence> _schedulerSequences;
  60. /// <summary>
  61. /// 当前步骤索引
  62. /// </summary>
  63. private int _currentSequenceIndex = 0;
  64. /// <summary>
  65. /// PUF实例
  66. /// </summary>
  67. private PUFEntity _puf1Entity;
  68. /// <summary>
  69. /// PUF实例
  70. /// </summary>
  71. private PUFEntity _puf2Entity;
  72. /// <summary>
  73. /// 是否开始执行
  74. /// </summary>
  75. private bool _isStart = false;
  76. /// <summary>
  77. /// 暂停时的索引
  78. /// </summary>
  79. private int _pausedIndex = -1;
  80. /// <summary>
  81. /// 错误上升触发
  82. /// </summary>
  83. private R_TRIG _sequenceErrorTigger = new R_TRIG();
  84. /// <summary>
  85. /// Sequence类型
  86. /// </summary>
  87. private string _sequenceType = "";
  88. /// <summary>
  89. /// FA回复
  90. /// </summary>
  91. private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();
  92. #endregion
  93. #region 属性
  94. /// <summary>
  95. /// ID
  96. /// </summary>
  97. public string ID { get;private set; }
  98. /// <summary>
  99. /// WaferHolder属性
  100. /// </summary>
  101. public WaferHolderInfo WaferHolderInfo { get;private set; }
  102. /// <summary>
  103. /// Process Job信息
  104. /// </summary>
  105. public ProcessJobInfo ProcessJobInfo { get;private set; }
  106. /// <summary>
  107. /// 状态
  108. /// </summary>
  109. public WaferHolderTaskState State { get; private set; }
  110. /// <summary>
  111. /// 步骤完成事件
  112. /// </summary>
  113. public event WaferHolderSchedulerComplete OnSchedulerComplete;
  114. /// <summary>
  115. /// 任务完成事件
  116. /// </summary>
  117. public event WaferHolderTaskComplete OnTaskComplete;
  118. /// <summary>
  119. /// 调度集合
  120. /// </summary>
  121. public List<SchedulerSequence> SchedulerSequences { get { return _schedulerSequences; } }
  122. #endregion
  123. /// <summary>
  124. /// 构造函数
  125. /// </summary>
  126. /// <param name="waferHolderInfo"></param>
  127. /// <param name="schedulerSequences"></param>
  128. public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo)
  129. {
  130. ID=Guid.NewGuid().ToString();
  131. WaferHolderInfo=waferHolderInfo;
  132. WaferHolderInfo.Status = WaferHolderStatus.Normal;
  133. if (processJobInfo != null)
  134. {
  135. WaferHolderInfo.SequenceId = processJobInfo.SequenceRecipe.Ppid;
  136. WaferHolderInfo.SequenceRecipe = processJobInfo.SequenceRecipe;
  137. _sequenceType = processJobInfo.SequenceRecipe.SequenceType;
  138. WaferHolderInfo.CurrentControlJobId = processJobInfo.ControlJobName;
  139. WaferHolderInfo.LotId = processJobInfo.LotName;
  140. }
  141. else
  142. {
  143. AnalyseProductionProcessJobInfo();
  144. }
  145. ProcessJobInfo=processJobInfo;
  146. State = WaferHolderTaskState.Created;
  147. _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
  148. _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
  149. }
  150. /// <summary>
  151. /// 初始化调度步骤
  152. /// </summary>
  153. /// <param name="schedulers"></param>
  154. public void InitialSchedulers(List<SchedulerSequence> schedulers)
  155. {
  156. _schedulerSequences = schedulers;
  157. }
  158. /// <summary>
  159. /// 分析生产片的ProcessJob信息
  160. /// </summary>
  161. private void AnalyseProductionProcessJobInfo()
  162. {
  163. if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))
  164. {
  165. WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);
  166. if (waferAInfo != null && waferAInfo.WaferType == WaferType.Production)
  167. {
  168. ProcessJobInfo = waferAInfo.ProcessJob;
  169. _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;
  170. WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;
  171. WaferHolderInfo.LotId = ProcessJobInfo.LotName;
  172. WaferHolderInfo.SequenceRecipe = ProcessJobInfo.SequenceRecipe;
  173. return;
  174. }
  175. }
  176. if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))
  177. {
  178. WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);
  179. if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production)
  180. {
  181. ProcessJobInfo = waferBInfo.ProcessJob;
  182. _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;
  183. WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;
  184. WaferHolderInfo.LotId = ProcessJobInfo.LotName;
  185. WaferHolderInfo.SequenceRecipe = ProcessJobInfo.SequenceRecipe;
  186. }
  187. }
  188. }
  189. /// <summary>
  190. /// 执行
  191. /// </summary>
  192. public void Run()
  193. {
  194. if(_currentSequenceIndex>=_schedulerSequences.Count)
  195. {
  196. State = WaferHolderTaskState.End;
  197. if(OnTaskComplete!=null)
  198. {
  199. OnTaskComplete(ID);
  200. }
  201. FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);
  202. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
  203. return;
  204. }
  205. if (!_isStart)
  206. {
  207. bool preCondition = CheckStartCondition();
  208. if (!preCondition)
  209. {
  210. return;
  211. }
  212. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} prepare Start {_currentSequenceIndex + 1} sequence");
  213. _isStart = true;
  214. if (WaferHolderInfo.SchedulerModules == null)
  215. {
  216. WaferHolderInfo.SchedulerModules = new List<string>();
  217. }
  218. WaferHolderInfo.SchedulerModules.Clear();
  219. }
  220. SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
  221. //暂停中
  222. if (sequence.State == RState.Init && _currentSequenceIndex >= _pausedIndex && _pausedIndex != -1)
  223. {
  224. return;
  225. }
  226. if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End)
  227. {
  228. State=WaferHolderTaskState.End;
  229. if (OnTaskComplete != null)
  230. {
  231. OnTaskComplete(ID);
  232. }
  233. FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);
  234. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
  235. return;
  236. }
  237. if(_currentSequenceIndex<_schedulerSequences.Count)
  238. {
  239. if(sequence.State==RState.Init)
  240. {
  241. if(sequence.SchedulerModule==null)
  242. {
  243. return;
  244. }
  245. if(!BufferWaferHolderJudgeResource(sequence))
  246. {
  247. return;
  248. }
  249. string reason = "";
  250. bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex, sequence.Parameters,WaferHolderInfo.Id,ref reason);
  251. if (sequeceCondition)
  252. {
  253. bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters, sequence.SynchronousModuleMessages);
  254. if (result)
  255. {
  256. if (State == WaferHolderTaskState.Created)
  257. {
  258. State = WaferHolderTaskState.Processing;
  259. FaModuleNotifier.Instance.NotifyWaferShuttleJobStart(WaferHolderInfo);
  260. }
  261. if (sequence.ModuleType == ModuleType.Rinse)
  262. {
  263. SchedulerQdrTimeManager.Instance.UpdateQdrStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex, DateTime.Now);
  264. }
  265. if (sequence.ModuleType == ModuleType.Metal)
  266. {
  267. SchedulerMetalTimeManager.Instance.UpdateMetalStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex, DateTime.Now);
  268. }
  269. if (sequence.ModuleType == ModuleType.Dryer)
  270. {
  271. SchedulerDryerTimeManager.Instance.UpdateDryerStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex, DateTime.Now);
  272. }
  273. if (sequence.ModuleName == ModuleName.Transporter1)
  274. {
  275. SchedulerTransporterTimeManager.Instance.UpdateTransporterStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex, DateTime.Now);
  276. }
  277. sequence.State = RState.Running;
  278. sequence.StartTime = DateTime.Now;
  279. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}");
  280. }
  281. else
  282. {
  283. if (sequence.ModuleName == ModuleName.Transporter1&&sequence.NextModuleType==ModuleType.Metal)
  284. {
  285. if (!CheckAfterMetalAvaible())
  286. {
  287. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} has no avaible metal");
  288. TransporterAction action = sequence.Parameters as TransporterAction;
  289. if (action.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)
  290. {
  291. WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
  292. waferHolderMoveItem.DestModuleType = ModuleType.Dryer;
  293. waferHolderMoveItem.DestModule = ModuleName.Unknown;
  294. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} next sequence changed to dryer");
  295. }
  296. }
  297. }
  298. }
  299. }
  300. else
  301. {
  302. _sequenceErrorTigger.CLK = !sequeceCondition;
  303. if (_sequenceErrorTigger.Q)
  304. {
  305. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}");
  306. }
  307. }
  308. }
  309. else if(sequence.State==RState.Running)
  310. {
  311. sequence.SchedulerModule.MonitorProcess(sequence,false);
  312. _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError;
  313. if (sequence.SchedulerModule.IsError)
  314. {
  315. //用于LoadTransporter取的WaferHolder Id不一致,则取消当前WaferHolderTask
  316. if (sequence.ModuleName == ModuleName.Transporter2)
  317. {
  318. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,task canceled");
  319. State = WaferHolderTaskState.Canceled;
  320. return;
  321. }
  322. if (_sequenceErrorTigger.Q)
  323. {
  324. AnalyseSchedulerErrorState(sequence);
  325. }
  326. }
  327. else if(sequence.SchedulerModule.IsIdle)
  328. {
  329. sequence.EndTime = DateTime.Now;
  330. sequence.State = RState.End;
  331. sequence.ProcessMilliSeconds=sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  332. if(sequence.IsProcessSequece)
  333. {
  334. UpdateWaferHolderProcessingStatus();
  335. }
  336. if(sequence.IsLastProcessSequence)
  337. {
  338. UpdateWaferHolderProcessComplete();
  339. }
  340. if (OnSchedulerComplete != null)
  341. {
  342. OnSchedulerComplete(WaferHolderInfo, sequence);
  343. }
  344. UpdateLoaderToBufferWaferHolderToloaderStatus(sequence);
  345. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");
  346. _currentSequenceIndex++;
  347. AutoChangeLoaderTransporterScheduler();
  348. //检验rinse后面是否存在可用的Metal
  349. if (sequence.ModuleType == ModuleType.Rinse)
  350. {
  351. SchedulerQdrTimeManager.Instance.RemoveQdrStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex - 1);
  352. AnalyseRinseAfterMetalAvaible(sequence);
  353. }
  354. else if (sequence.ModuleType == ModuleType.Prewet)
  355. {
  356. AnalysePrewetAfterMetalAvaible(sequence);
  357. }
  358. else if (sequence.ModuleType == ModuleType.Metal)
  359. {
  360. SchedulerMetalTimeManager.Instance.RemoveMetalStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex - 1);
  361. }
  362. else if (sequence.ModuleType == ModuleType.Dryer)
  363. {
  364. SchedulerDryerTimeManager.Instance.RemoveDryerStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex - 1);
  365. SchedulerWaferHolderTimeManager.Instance.RemoveWaferHolderTime(WaferHolderInfo.Id);
  366. }
  367. else if (sequence.ModuleName == ModuleName.Transporter1)
  368. {
  369. SchedulerTransporterTimeManager.Instance.RemoveTransporterStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex - 1);
  370. }
  371. }
  372. }
  373. else if (sequence.State == RState.End)
  374. {
  375. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence is End");
  376. _currentSequenceIndex++;
  377. }
  378. }
  379. }
  380. /// <summary>
  381. /// 更新任务结束
  382. /// </summary>
  383. public void UpdateDryerLastSchedulerComplete()
  384. {
  385. SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
  386. sequence.EndTime = DateTime.Now;
  387. sequence.State = RState.End;
  388. sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  389. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex+1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");
  390. State = WaferHolderTaskState.End;
  391. if (OnTaskComplete != null)
  392. {
  393. OnTaskComplete(ID);
  394. }
  395. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
  396. }
  397. /// <summary>
  398. /// 更新从Loader到Buffer的WaferHolder更新为不可以拉回至Loader
  399. /// </summary>
  400. /// <param name="sequence"></param>
  401. private void UpdateLoaderToBufferWaferHolderToloaderStatus(SchedulerSequence sequence)
  402. {
  403. string currentLocation = WaferHolderInfo.CurrentLocation;
  404. if(!Enum.TryParse(currentLocation,out ModuleName locationName))
  405. {
  406. return;
  407. }
  408. if (!ModuleHelper.IsBuffer(locationName))
  409. {
  410. return;
  411. }
  412. if (sequence.ModuleName == ModuleName.Transporter2)
  413. {
  414. TransporterAction transporterAction = sequence.Parameters as TransporterAction;
  415. if (transporterAction.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)
  416. {
  417. WaferHolderMoveItem waferHolderMoveItem = transporterAction.Parameter as WaferHolderMoveItem;
  418. if (waferHolderMoveItem.SourceModule == ModuleName.Loader1 && waferHolderMoveItem.DestModuleType == ModuleType.Buffer)
  419. {
  420. WaferHolderInfo.IsToLoader = false;
  421. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to false;");
  422. }
  423. else if (waferHolderMoveItem.DestModuleType == ModuleType.Buffer && waferHolderMoveItem.SourceModuleType != ModuleType.Loader)
  424. {
  425. WaferHolderInfo.IsToLoader = true;
  426. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true;");
  427. }
  428. }
  429. }
  430. }
  431. /// <summary>
  432. /// 分析错误状态下的调度
  433. /// </summary>
  434. private void AnalyseSchedulerErrorState(SchedulerSequence sequence)
  435. {
  436. if (sequence.ModuleType == ModuleType.Prewet)
  437. {
  438. AnalyseSchedulerPrewetErrorState(sequence);
  439. }
  440. else if (sequence.ModuleType == ModuleType.Dryer)
  441. {
  442. AnalyseSchedulerDryerErrorState(sequence);
  443. }
  444. else if (sequence.ModuleType == ModuleType.Rinse)
  445. {
  446. RinseItem rinseItem = RinseItemManager.Instance.GetRinseItem(sequence.ModuleName.ToString());
  447. if (rinseItem == null)
  448. {
  449. return;
  450. }
  451. if (rinseItem.SubType != PWT)
  452. {
  453. AnalyseSchedulerRinseErrorState(sequence);
  454. }
  455. else
  456. {
  457. AnalyseSchedulerPrewetErrorState(sequence);
  458. }
  459. }
  460. else if (sequence.ModuleType == ModuleType.Metal)
  461. {
  462. AnalyseSchedulerMetalErrorState(sequence);
  463. }
  464. }
  465. /// <summary>
  466. /// 判定Buffer中WaferHolder的后面工序是否存在可用资源,不存在的话,则Task直接结束
  467. /// </summary>
  468. /// <param name="sequence"></param>
  469. private bool BufferWaferHolderJudgeResource(SchedulerSequence sequence)
  470. {
  471. string currentLocation = WaferHolderInfo.CurrentLocation;
  472. if (Enum.TryParse(currentLocation, out ModuleName moduleName))
  473. {
  474. //当前WaferHolder处于Buffer中,当前步骤不是第一步,当前调度模块为transporter2
  475. if (ModuleHelper.IsBuffer(moduleName)&&_currentSequenceIndex!=0&&sequence.ModuleName==ModuleName.Transporter2)
  476. {
  477. if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(WaferHolderInfo.SequenceRecipe, false))
  478. {
  479. for (int i = _currentSequenceIndex; i < _schedulerSequences.Count; i++)
  480. {
  481. SchedulerSequence item = _schedulerSequences[i];
  482. item.State = RState.End;
  483. }
  484. _currentSequenceIndex = _schedulerSequences.Count - 1;
  485. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} exist no avaible cell");
  486. WaferHolderInfo.IsToLoader = true;
  487. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true");
  488. RemoveWaferHolderSRDScheduler();
  489. UpdateWaferHolderMisProcessedStatus();
  490. return false;
  491. }
  492. }
  493. }
  494. return true;
  495. }
  496. /// <summary>
  497. /// 检验Prewet后面的Metal是否存在可用
  498. /// </summary>
  499. private void AnalysePrewetAfterMetalAvaible(SchedulerSequence schedulerSequence)
  500. {
  501. //获取可用的Metal以及Rinse
  502. if (!CheckAfterMetalAvaible())
  503. {
  504. LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after prewet");
  505. SkipAfterMetal(schedulerSequence,true);
  506. RemoveWaferHolderSRDScheduler();
  507. UpdateWaferHolderMisProcessedStatus();
  508. //SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex];
  509. //if (nextSchedulerSequence.ModuleName != ModuleName.Transporter1)
  510. //{
  511. // return;
  512. //}
  513. //WaferHolderMoveItem waferHolderMoveItem = nextSchedulerSequence.Parameters as WaferHolderMoveItem;
  514. //waferHolderMoveItem.DestModuleType = ModuleType.Dryer;
  515. //waferHolderMoveItem.DestModule = ModuleName.Unknown;
  516. }
  517. }
  518. /// <summary>
  519. /// 检验Rinse后面的Metal是否存在可用
  520. /// </summary>
  521. /// <returns></returns>
  522. private void AnalyseRinseAfterMetalAvaible(SchedulerSequence schedulerSequence)
  523. {
  524. //获取可用的Metal以及Rinse
  525. if(!CheckAfterMetalAvaible())
  526. {
  527. LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after rinse");
  528. SkipAfterMetal(schedulerSequence,true);
  529. RemoveWaferHolderSRDScheduler();
  530. UpdateWaferHolderMisProcessedStatus();
  531. }
  532. }
  533. /// <summary>
  534. /// 检验后续Metal可用性
  535. /// </summary>
  536. /// <returns></returns>
  537. private bool CheckAfterMetalAvaible()
  538. {
  539. for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
  540. {
  541. SchedulerSequence sequence = _schedulerSequences[i];
  542. if (sequence.ModuleType != ModuleType.Metal)
  543. {
  544. continue ;
  545. }
  546. if (sequence.Recipe == null || !(sequence.Recipe is DepRecipe))
  547. {
  548. continue;
  549. }
  550. DepRecipe depRecipe = (DepRecipe)sequence.Recipe;
  551. bool result= SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, sequence.SequenceType,sequence.WaferSize);
  552. if (!result)
  553. {
  554. return false;
  555. }
  556. }
  557. return true;
  558. }
  559. #region Analyse ErrorState Scheduler
  560. /// <summary>
  561. /// Prewet出错重新调度
  562. /// </summary>
  563. /// <param name="sequence"></param>
  564. private void AnalyseSchedulerPrewetErrorState(SchedulerSequence sequence)
  565. {
  566. SkipAfterSchedulerToDry(ModuleName.Transporter2, sequence);
  567. sequence.State = RState.End;
  568. sequence.EndTime = DateTime.Now;
  569. sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  570. RemoveWaferHolderSRDScheduler();
  571. UpdateWaferHolderMisProcessedStatus();
  572. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Prewet meet error,scheduler changed to transporter2");
  573. }
  574. /// <summary>
  575. /// 路过后面调度直接至Dryer
  576. /// </summary>
  577. private void SkipAfterSchedulerToDry(ModuleName transporterName, SchedulerSequence sequence)
  578. {
  579. for (int i = _currentSequenceIndex=1; i < _schedulerSequences.Count; i++)
  580. {
  581. SchedulerSequence item = _schedulerSequences[i];
  582. if (item.ModuleName != ModuleName.Transporter1)
  583. {
  584. item.State = RState.End;
  585. item.ProcessMilliSeconds = 0;
  586. }
  587. else
  588. {
  589. if (item.Parameters is TransporterAction)
  590. {
  591. TransporterAction action= (TransporterAction)item.Parameters;
  592. if (action.ActionMsg == Modules.Transporter.TransporterMSG.Transfer)
  593. {
  594. WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
  595. if (waferHolderMoveItem.DestModuleType == ModuleType.Dryer)
  596. {
  597. _currentSequenceIndex = i;
  598. item.SchedulerModule = SchedulerManager.Instance.GetScheduler(transporterName);
  599. waferHolderMoveItem.SourceModule = sequence.ModuleName;
  600. waferHolderMoveItem.SourceModuleType = sequence.ModuleType;
  601. break;
  602. }
  603. else
  604. {
  605. item.State = RState.End;
  606. item.ProcessMilliSeconds = 0;
  607. }
  608. }
  609. }
  610. }
  611. }
  612. }
  613. /// <summary>
  614. /// Dryer出错重新调度,上一步调度修改为transporter2,同时tranporter2搬运源目标为当前Module,目标类型也是Dryer
  615. /// </summary>
  616. /// <param name="sequence"></param>
  617. private void AnalyseSchedulerDryerErrorState(SchedulerSequence sequence)
  618. {
  619. if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType,ModuleType.Dryer)!=ModuleName.Unknown)
  620. {
  621. SchedulerDryerTimeManager.Instance.RemoveDryerStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex);
  622. sequence.State = RState.Init;
  623. SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();
  624. preSchedulerSequence.State = RState.Init;
  625. preSchedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2);
  626. TransporterAction action = preSchedulerSequence.Parameters as TransporterAction;
  627. if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
  628. {
  629. return;
  630. }
  631. WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
  632. waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;
  633. waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;
  634. waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;
  635. waferHolderMoveItem.DestModule = ModuleName.Unknown;
  636. sequence.SchedulerModule = null;
  637. sequence.ModuleName = ModuleName.Unknown;
  638. SchedulerWaferHolderTimeManager.Instance.RemoveAllWaferHolderDryerCell(WaferHolderInfo.Id);
  639. SchedulerWaferHolderTimeManager.Instance.ResetScheduler(WaferHolderInfo.Id, DateTime.Now);
  640. _currentSequenceIndex--;
  641. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler changed to transporter2");
  642. }
  643. else
  644. {
  645. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler has no avaible dryer");
  646. }
  647. }
  648. /// <summary>
  649. /// Rinse出错重新调度,回退至上一步调度
  650. /// </summary>
  651. /// <param name="sequence"></param>
  652. private void AnalyseSchedulerRinseErrorState(SchedulerSequence sequence)
  653. {
  654. ModuleName metalName = SchedulerSequenceManager.Instance.GetPreMetalModuleName(_currentSequenceIndex, _schedulerSequences);
  655. if (metalName == ModuleName.Unknown)
  656. {
  657. return;
  658. }
  659. if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType, ModuleType.Rinse,metalName) != ModuleName.Unknown)
  660. {
  661. SchedulerQdrTimeManager.Instance.RemoveQdrStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex);
  662. sequence.State = RState.Init;
  663. SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();
  664. preSchedulerSequence.State = RState.Init;
  665. TransporterAction action = preSchedulerSequence.Parameters as TransporterAction;
  666. if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
  667. {
  668. return;
  669. }
  670. WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
  671. waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;
  672. waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;
  673. waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;
  674. waferHolderMoveItem.DestModule = ModuleName.Unknown;
  675. sequence.SchedulerModule = null;
  676. sequence.ModuleName = ModuleName.Unknown;
  677. SchedulerWaferHolderTimeManager.Instance.RemoveOtherWaferHolderAfterCell(WaferHolderInfo.Id, true);
  678. SchedulerWaferHolderTimeManager.Instance.ResetScheduler(WaferHolderInfo.Id, DateTime.Now);
  679. _currentSequenceIndex--;
  680. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,scheduler changed to transporter1");
  681. }
  682. else
  683. {
  684. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,rescheduler has no avaible rinse");
  685. }
  686. }
  687. /// <summary>
  688. /// Metal出错重新调度,回退至上一步调度
  689. /// </summary>
  690. /// <param name="sequence"></param>
  691. private void AnalyseSchedulerMetalErrorState(SchedulerSequence sequence)
  692. {
  693. //当前步骤结束,WaferHolder状态
  694. UpdateWaferHolderErrorStatus();
  695. sequence.EndTime = DateTime.Now;
  696. sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  697. sequence.State = RState.End;
  698. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Metal meet error,rescheduler changed to next module");
  699. SchedulerMetalTimeManager.Instance.RemoveMetalStartTime(sequence.ModuleName.ToString(), WaferHolderInfo.Id, _currentSequenceIndex);
  700. //跳过后面的metal
  701. SkipAfterMetal(sequence,false);
  702. //移除SRD调度
  703. RemoveWaferHolderSRDScheduler();
  704. SchedulerWaferHolderTimeManager.Instance.RemoveOtherWaferHolderAfterCell(WaferHolderInfo.Id, false);
  705. SchedulerWaferHolderTimeManager.Instance.ResetScheduler(WaferHolderInfo.Id, DateTime.Now);
  706. _currentSequenceIndex++;
  707. }
  708. /// <summary>
  709. /// 跳过后面的Metal
  710. /// </summary>
  711. private void SkipAfterMetal(SchedulerSequence schedulerSequence,bool isSetLastSequenceSourceModule)
  712. {
  713. int startIndex = -1;
  714. int endIndex = -1;
  715. //从下一个Metal直到碰到Dryer
  716. for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
  717. {
  718. SchedulerSequence item = _schedulerSequences[i];
  719. if (item.ModuleType == ModuleType.Metal && startIndex == -1)
  720. {
  721. startIndex = i;
  722. }
  723. if (item.ModuleType == ModuleType.Dryer)
  724. {
  725. endIndex = i - 1;//Dryer前一步骤为Transporter,保留Dryer前面的transporter
  726. break;
  727. }
  728. }
  729. //将后面的Metal的步骤直接跳过,包含gh g 后面的transporter
  730. if (startIndex != -1)
  731. {
  732. for (int i = startIndex - 1; i < endIndex; i++)
  733. {
  734. SchedulerSequence item = _schedulerSequences[i];
  735. item.State = RState.End;
  736. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} skip {i+1} sequence {item.ModuleType}");
  737. }
  738. }
  739. //是否设置最后调度的源模块
  740. if (isSetLastSequenceSourceModule)
  741. {
  742. SchedulerSequence lastSchedulerSequence = _schedulerSequences[endIndex];
  743. if (lastSchedulerSequence.ModuleType == ModuleType.Transporter)
  744. {
  745. TransporterAction action = lastSchedulerSequence.Parameters as TransporterAction;
  746. if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
  747. {
  748. return;
  749. }
  750. WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
  751. if (schedulerSequence.SchedulerModule != null)
  752. {
  753. waferHolderMoveItem.SourceModule = schedulerSequence.ModuleName;
  754. waferHolderMoveItem.SourceModuleType = schedulerSequence.ModuleType;
  755. }
  756. }
  757. }
  758. }
  759. /// <summary>
  760. /// 移除SRD调度
  761. /// </summary>
  762. private void RemoveWaferHolderSRDScheduler()
  763. {
  764. WaferTask waferATask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferAId);
  765. if (waferATask != null)
  766. {
  767. waferATask.RemoveSrdScheduler();
  768. }
  769. WaferTask waferBTask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferBId);
  770. if (waferBTask != null)
  771. {
  772. waferBTask.RemoveSrdScheduler();
  773. }
  774. }
  775. #endregion
  776. /// <summary>
  777. /// 自动更新LoaderTransporter的工序
  778. /// </summary>
  779. private void AutoChangeLoaderTransporterScheduler()
  780. {
  781. if(_currentSequenceIndex>=_schedulerSequences.Count)
  782. {
  783. return;
  784. }
  785. if(_currentSequenceIndex+2>=_schedulerSequences.Count)
  786. {
  787. return;
  788. }
  789. SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex];
  790. if (schedulerSequence == null)
  791. {
  792. return;
  793. }
  794. if(schedulerSequence.ModuleName==ModuleName.Transporter2)
  795. {
  796. if (schedulerSequence.Parameters == null || !(schedulerSequence.Parameters is TransporterAction))
  797. {
  798. return;
  799. }
  800. TransporterAction action = (TransporterAction)schedulerSequence.Parameters;
  801. if (action.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
  802. {
  803. return;
  804. }
  805. WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;
  806. if(waferHolderMoveItem.DestModuleType!=ModuleType.Buffer)
  807. {
  808. return;
  809. }
  810. SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex + 1];
  811. if(nextSchedulerSequence.ModuleName!=ModuleName.Transporter2)
  812. {
  813. return;
  814. }
  815. if(nextSchedulerSequence.Parameters==null||!(nextSchedulerSequence.Parameters is TransporterAction))
  816. {
  817. return;
  818. }
  819. TransporterAction nextAction = nextSchedulerSequence.Parameters as TransporterAction;
  820. if (nextAction.ActionMsg != Modules.Transporter.TransporterMSG.Transfer)
  821. {
  822. return;
  823. }
  824. WaferHolderMoveItem nextWaferHolderMoveItem = (WaferHolderMoveItem)nextAction.Parameter;
  825. if(nextWaferHolderMoveItem.DestModule==ModuleName.Unknown)
  826. {
  827. if (ProcessJobInfo != null && ProcessJobInfo.SequenceRecipe != null)
  828. {
  829. //后面不存在资源,搬运至Buffer中,而不是进后面cell
  830. if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))
  831. {
  832. return;
  833. }
  834. }
  835. if (CheckBufferHasUnProcessedWaferHolder())
  836. {
  837. return;
  838. }
  839. //若Buffer后面的cell存在资源,则直接搬运至Cell中
  840. ModuleName avaibleModuleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(nextWaferHolderMoveItem.DestModuleType,_sequenceType);
  841. if(avaibleModuleName==ModuleName.Unknown)
  842. {
  843. return;
  844. }
  845. else
  846. {
  847. bool result = true;
  848. if (nextWaferHolderMoveItem.DestModuleType == ModuleType.Prewet && SchedulerManager.Instance.IsQdrCheckConflict)
  849. {
  850. PrewetEntity prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(ModuleName.Prewet1.ToString());
  851. if (_currentSequenceIndex + 2 >= _schedulerSequences.Count)
  852. {
  853. return;
  854. }
  855. SchedulerSequence pwtSequence = _schedulerSequences[_currentSequenceIndex + 2];
  856. if (pwtSequence.ModuleType != ModuleType.Prewet)
  857. {
  858. return;
  859. }
  860. PwtRecipe pwtRecipe = pwtSequence.Recipe as PwtRecipe;
  861. int recipeTime = prewetEntity.CalculateRecipeTime(pwtRecipe);
  862. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  863. DateTime startTime = DateTime.Now.AddSeconds(transporterTransferSeconds).AddSeconds(recipeTime);
  864. result = SchedulerModuleTimeManager.Instance.ConfirmAllMetalQdrAndDryer(_schedulerSequences, WaferHolderInfo.Id, _currentSequenceIndex, true, startTime);
  865. if (result)
  866. {
  867. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Wafer shuttle {WaferHolderInfo.Id} has avaible cells after Prewet");
  868. }
  869. }
  870. if (result)
  871. {
  872. schedulerSequence.State = RState.End;
  873. _currentSequenceIndex++;
  874. nextWaferHolderMoveItem.DestModule = avaibleModuleName;
  875. nextWaferHolderMoveItem.SourceModule = ModuleName.Loader1;
  876. nextWaferHolderMoveItem.SourceModuleType = ModuleType.Loader;
  877. UpdateNextSequenceModule(_currentSequenceIndex + 1, avaibleModuleName);
  878. }
  879. }
  880. }
  881. //下一步是QDR
  882. else if (nextWaferHolderMoveItem.DestModuleType == ModuleType.Rinse && nextWaferHolderMoveItem.DestModule != ModuleName.Unknown)
  883. {
  884. RinseEntity rinseEntity = Singleton<RouteManager>.Instance.GetModule<RinseEntity>(nextWaferHolderMoveItem.DestModule.ToString());
  885. if (rinseEntity != null && rinseEntity.IsAuto && rinseEntity.IsIdle && rinseEntity.WaferHolderInfo == null)
  886. {
  887. bool result = true;
  888. if (SchedulerManager.Instance.IsQdrCheckConflict)
  889. {
  890. if (_currentSequenceIndex + 2 >= _schedulerSequences.Count)
  891. {
  892. return;
  893. }
  894. SchedulerSequence qdrSequence = _schedulerSequences[_currentSequenceIndex + 2];
  895. if (qdrSequence.ModuleType != ModuleType.Rinse)
  896. {
  897. return;
  898. }
  899. QdrRecipe qdrRecipe = qdrSequence.Recipe as QdrRecipe;
  900. int recipeTime = qdrRecipe.CalculateRunRecipeTime();
  901. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  902. DateTime startTime = DateTime.Now.AddSeconds(transporterTransferSeconds).AddSeconds(recipeTime);
  903. result = SchedulerModuleTimeManager.Instance.ConfirmAllMetalQdrAndDryer(_schedulerSequences, WaferHolderInfo.Id, _currentSequenceIndex, true, startTime);
  904. }
  905. if (result)
  906. {
  907. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Wafer shuttle {WaferHolderInfo.Id} has avaible cells after QDR Prewet");
  908. schedulerSequence.State = RState.End;
  909. _currentSequenceIndex++;
  910. nextWaferHolderMoveItem.SourceModule = ModuleName.Loader1;
  911. nextWaferHolderMoveItem.SourceModuleType = ModuleType.Loader;
  912. UpdateNextSequenceModule(_currentSequenceIndex + 1, nextWaferHolderMoveItem.DestModule);
  913. }
  914. }
  915. }
  916. else if(nextWaferHolderMoveItem.DestModule==ModuleName.Loader1)
  917. {
  918. LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  919. if(loaderEntity==null)
  920. {
  921. return;
  922. }
  923. if(loaderEntity.WaferHolderInfo!=null)
  924. {
  925. return;
  926. }
  927. if(loaderEntity.IsBusy)
  928. {
  929. return;
  930. }
  931. schedulerSequence.State = RState.End;
  932. _currentSequenceIndex++;
  933. nextWaferHolderMoveItem.SourceModule = waferHolderMoveItem.SourceModule;
  934. nextWaferHolderMoveItem.SourceModuleType = waferHolderMoveItem.SourceModuleType;
  935. }
  936. }
  937. }
  938. /// <summary>
  939. /// 检验Buffer中是否存在未处理的WaferHolder
  940. /// </summary>
  941. /// <returns></returns>
  942. private bool CheckBufferHasUnProcessedWaferHolder()
  943. {
  944. List<string> bufferModules = BufferItemManager.Instance.InstalledModules;
  945. foreach (string module in bufferModules)
  946. {
  947. WaferHolderInfo item = WaferHolderManager.Instance.GetWaferHolder(module);
  948. if (item == null)
  949. {
  950. continue;
  951. }
  952. if (string.IsNullOrEmpty(item.WaferAId))
  953. {
  954. continue;
  955. }
  956. if (string.IsNullOrEmpty(item.WaferBId))
  957. {
  958. continue;
  959. }
  960. WaferInfo waferA=WaferManager.Instance.GetWaferByWaferId(item.WaferAId);
  961. if (waferA == null)
  962. {
  963. continue;
  964. }
  965. if (waferA.ProcessState == EnumWaferProcessStatus.Idle&&waferA.WaferType==WaferType.Production)
  966. {
  967. return true;
  968. }
  969. WaferInfo waferB = WaferManager.Instance.GetWaferByWaferId(item.WaferBId);
  970. if(waferB == null)
  971. {
  972. continue;
  973. }
  974. if (waferB.ProcessState == EnumWaferProcessStatus.Idle && waferB.WaferType == WaferType.Production)
  975. {
  976. return true;
  977. }
  978. }
  979. return false;
  980. }
  981. /// <summary>
  982. /// 更新下一工序的调度模块
  983. /// </summary>
  984. /// <param name="sequenceIndex"></param>
  985. /// <param name="moduleName"></param>
  986. private void UpdateNextSequenceModule(int sequenceIndex,ModuleName moduleName)
  987. {
  988. if(sequenceIndex<_schedulerSequences.Count)
  989. {
  990. SchedulerSequence schedulerSequence = _schedulerSequences[sequenceIndex];
  991. if(schedulerSequence!=null&&schedulerSequence.SchedulerModule==null)
  992. {
  993. schedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
  994. schedulerSequence.ModuleName = moduleName;
  995. }
  996. }
  997. }
  998. /// <summary>
  999. /// 更新WaferHolder工序完成Wafer状态
  1000. /// </summary>
  1001. private void UpdateWaferHolderProcessComplete()
  1002. {
  1003. if (WaferHolderInfo.Status != WaferHolderStatus.Completed)
  1004. {
  1005. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Completed);
  1006. WaferHolderInfo.Status = WaferHolderStatus.Completed;
  1007. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");
  1008. }
  1009. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  1010. }
  1011. /// <summary>
  1012. /// 更新WaferHolder工序正在加工
  1013. /// </summary>
  1014. private void UpdateWaferHolderProcessingStatus()
  1015. {
  1016. if (WaferHolderInfo.Status == WaferHolderStatus.Normal)
  1017. {
  1018. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.InProcess);
  1019. WaferHolderInfo.Status = WaferHolderStatus.Processing;
  1020. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");
  1021. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  1022. }
  1023. }
  1024. /// <summary>
  1025. /// 更新WaferHolder工序错误状态
  1026. /// </summary>
  1027. /// <param name="sequence"></param>
  1028. private void UpdateWaferHolderErrorStatus()
  1029. {
  1030. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Failed);
  1031. WaferHolderInfo.Status = WaferHolderStatus.Failed;
  1032. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  1033. }
  1034. /// <summary>
  1035. /// 更新WaferHolder工序MisProcessed状态
  1036. /// </summary>
  1037. /// <param name="sequence"></param>
  1038. private void UpdateWaferHolderMisProcessedStatus()
  1039. {
  1040. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.MisProcessed);
  1041. WaferHolderInfo.Status = WaferHolderStatus.MisProcessed;
  1042. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  1043. }
  1044. /// <summary>
  1045. /// 更新WaferHolder处理状态
  1046. /// </summary>
  1047. /// <param name="sequence"></param>
  1048. /// <param name="processStatus"></param>
  1049. private void UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus processStatus)
  1050. {
  1051. if (Enum.TryParse(WaferHolderInfo.CurrentLocation, out ModuleName moduleName))
  1052. {
  1053. if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))
  1054. {
  1055. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);
  1056. if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
  1057. {
  1058. WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 0, processStatus);
  1059. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");
  1060. }
  1061. }
  1062. if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))
  1063. {
  1064. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);
  1065. if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
  1066. {
  1067. WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 1, processStatus);
  1068. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");
  1069. }
  1070. }
  1071. }
  1072. }
  1073. /// <summary>
  1074. /// 检验前置条件
  1075. /// </summary>
  1076. /// <returns></returns>
  1077. private bool CheckStartCondition()
  1078. {
  1079. LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  1080. if (loaderEntity.WaferHolderInfo != null)
  1081. {
  1082. return false;
  1083. }
  1084. //if (ProcessJobInfo != null)
  1085. //{
  1086. // if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))
  1087. // {
  1088. // _currentSequenceIndex = _schedulerSequences.Count;
  1089. // LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"WaferHolder {WaferHolderInfo.Id} start scheduler meet no avaible cell");
  1090. // return false;
  1091. // }
  1092. //}
  1093. return true;
  1094. }
  1095. /// <summary>
  1096. /// 释放资源
  1097. /// </summary>
  1098. public void Dispose()
  1099. {
  1100. _schedulerSequences.Clear();
  1101. }
  1102. /// <summary>
  1103. /// 暂停
  1104. /// </summary>
  1105. public void Pause()
  1106. {
  1107. _pausedIndex = _currentSequenceIndex;
  1108. }
  1109. /// <summary>
  1110. /// 恢复
  1111. /// </summary>
  1112. public void Resume()
  1113. {
  1114. _pausedIndex = -1;
  1115. }
  1116. /// <summary>
  1117. /// 获取任务索引
  1118. /// </summary>
  1119. /// <returns></returns>
  1120. public int GetCurrentSchedulerIndex()
  1121. {
  1122. return _currentSequenceIndex;
  1123. }
  1124. /// <summary>
  1125. /// 获取当前调度阶段
  1126. /// </summary>
  1127. /// <returns></returns>
  1128. public SchedulerSequence GetCurrentSchedulerSequence()
  1129. {
  1130. return GetSchedulerSequenceByIndex(_currentSequenceIndex);
  1131. }
  1132. /// <summary>
  1133. /// 获取前一个调度阶段
  1134. /// </summary>
  1135. /// <returns></returns>
  1136. public SchedulerSequence GetPreSchedulerSequence()
  1137. {
  1138. return GetSchedulerSequenceByIndex(_currentSequenceIndex-1);
  1139. }
  1140. /// <summary>
  1141. /// 根据索引获取调度阶段对象
  1142. /// </summary>
  1143. /// <param name="index"></param>
  1144. /// <returns></returns>
  1145. public SchedulerSequence GetSchedulerSequenceByIndex(int index)
  1146. {
  1147. if (index == -1 || index >= _schedulerSequences.Count)
  1148. {
  1149. return null;
  1150. }
  1151. return _schedulerSequences[index];
  1152. }
  1153. /// <summary>
  1154. /// 获取下一个Metal sequence
  1155. /// </summary>
  1156. /// <param name="index"></param>
  1157. /// <returns></returns>
  1158. public SchedulerSequence GetNextMetalSequence(int index)
  1159. {
  1160. for (int i = index; i < _schedulerSequences.Count; i++)
  1161. {
  1162. SchedulerSequence sequence = _schedulerSequences[i];
  1163. if (sequence.ModuleType == ModuleType.Metal)
  1164. {
  1165. return sequence;
  1166. }
  1167. }
  1168. return null;
  1169. }
  1170. /// <summary>
  1171. /// 获取下一个Metal sequence
  1172. /// </summary>
  1173. /// <param name="index"></param>
  1174. /// <returns></returns>
  1175. public SchedulerSequence GetNextTransporterSequence(int index)
  1176. {
  1177. for (int i = index; i < _schedulerSequences.Count; i++)
  1178. {
  1179. SchedulerSequence sequence = _schedulerSequences[i];
  1180. if (sequence.ModuleType == ModuleType.Transporter)
  1181. {
  1182. return sequence;
  1183. }
  1184. }
  1185. return null;
  1186. }
  1187. /// <summary>
  1188. /// 是否调度完成Loader调度
  1189. /// </summary>
  1190. /// <returns></returns>
  1191. public bool IsNotPassLoader()
  1192. {
  1193. return _currentSequenceIndex <= 1;
  1194. }
  1195. }
  1196. }