SchedulerRinse.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. using Aitex.Common.Util;
  2. using Aitex.Core.RT.Fsm;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.Util;
  5. using CyberX8_Core;
  6. using CyberX8_RT.Modules;
  7. using CyberX8_RT.Modules.Dryer;
  8. using CyberX8_RT.Modules.Loader;
  9. using CyberX8_RT.Modules.Prewet;
  10. using CyberX8_RT.Modules.Rinse;
  11. using MECF.Framework.Common.CommonData;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.RecipeCenter;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. namespace CyberX8_RT.Schedulers.Rinse
  20. {
  21. public class SchedulerRinse : SchedulerModule
  22. {
  23. #region 内部变量
  24. private RinseEntity _rinseEntity;
  25. private bool _isStartRunRecipe = false;
  26. #endregion
  27. #region 属性
  28. /// <summary>
  29. /// 是否空闲
  30. /// </summary>
  31. public override bool IsIdle
  32. {
  33. get { return _state == RState.End; }
  34. }
  35. /// <summary>
  36. /// 是否错误
  37. /// </summary>
  38. public override bool IsError
  39. {
  40. get { return _state == RState.Failed || _state == RState.Timeout; }
  41. }
  42. #endregion
  43. /// <summary>
  44. /// 构造函数
  45. /// </summary>
  46. /// <param name="module"></param>
  47. public SchedulerRinse(ModuleName moduleName) : base(moduleName.ToString())
  48. {
  49. _rinseEntity = Singleton<RouteManager>.Instance.GetModule<RinseEntity>(moduleName.ToString());
  50. }
  51. /// <summary>
  52. /// 执行
  53. /// </summary>
  54. /// <param name="parameter"></param>
  55. /// <returns></returns>
  56. public override bool RunProcess(object recipe, object parameter, List<SchedulerSyncModuleMessage> syncModuleMessages)
  57. {
  58. if (!(recipe is QdrRecipe))
  59. {
  60. _state = RState.Failed;
  61. LOG.WriteLog(eEvent.ERR_RINSE, Module.ToString(), "recipe is invalid");
  62. return false;
  63. }
  64. _isStartRunRecipe = false;
  65. QdrRecipe qdrRecipe = (QdrRecipe)recipe;
  66. bool result = _rinseEntity.CheckToPostMessage<RinseState, RinseMsg>(eEvent.ERR_RINSE, Module.ToString(), (int)RinseMsg.RunRecipe, qdrRecipe,1);
  67. if (result)
  68. {
  69. _state = RState.Running;
  70. }
  71. return result;
  72. }
  73. /// <summary>
  74. /// 监控执行
  75. /// </summary>
  76. /// <returns></returns>
  77. public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
  78. {
  79. if (!_isStartRunRecipe)
  80. {
  81. _isStartRunRecipe = _rinseEntity.State == (int)RinseState.RunReciping;
  82. }
  83. if (_rinseEntity.IsError)
  84. {
  85. _state = RState.Failed;
  86. _isStartRunRecipe = false;
  87. }
  88. if (_isStartRunRecipe && _rinseEntity.IsIdle)
  89. {
  90. _state = RState.End;
  91. _isStartRunRecipe = false;
  92. }
  93. if(_rinseEntity.State==(int)RinseState.RunRecipeComplete||_rinseEntity.State==(int)RinseState.KeepWeting)
  94. {
  95. if (schedulerSequence.NextModuleType != ModuleType.Metal)
  96. {
  97. NotifyRinseComplete();
  98. }
  99. else
  100. {
  101. bool exsitEnableCell = false;
  102. DepRecipe depRecipe = schedulerSequence.NextRecipe as DepRecipe;
  103. ModuleName moduleName = SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry,
  104. Module.ToString(),schedulerSequence.SequenceType,ref exsitEnableCell);
  105. if (moduleName != ModuleName.Unknown)
  106. {
  107. IModuleEntity moduleEntity = Singleton<RouteManager>.Instance.GetModule<IModuleEntity>(moduleName.ToString());
  108. if (SchedulerSequenceManager.Instance.CheckMetalCellRecipeTimeAvaible(moduleEntity, depRecipe))
  109. {
  110. NotifyRinseComplete();
  111. }
  112. else
  113. {
  114. NotifyRinseKeepWet();
  115. }
  116. }
  117. else
  118. {
  119. if (exsitEnableCell)
  120. {
  121. NotifyRinseKeepWet();
  122. }
  123. else
  124. {
  125. NotifyRinseComplete();
  126. }
  127. }
  128. }
  129. }
  130. return true;
  131. }
  132. /// <summary>
  133. /// 通知Rinse完成
  134. /// </summary>
  135. private void NotifyRinseComplete()
  136. {
  137. _rinseEntity.CheckToPostMessage<RinseState, RinseMsg>(eEvent.INFO_RINSE, Module.ToString(), (int)RinseMsg.RecipeComplete);
  138. }
  139. /// <summary>
  140. /// 通知Rinse准备Keep Wet
  141. /// </summary>
  142. private void NotifyRinseKeepWet()
  143. {
  144. if (_rinseEntity.State == (int)RinseState.KeepWeting)
  145. {
  146. return;
  147. }
  148. _rinseEntity.CheckToPostMessage<RinseState, RinseMsg>(eEvent.WARN_PREWET, Module.ToString(),
  149. (int)RinseMsg.Keepwet);
  150. }
  151. /// <summary>
  152. /// 检验前置条件
  153. /// </summary>
  154. /// <param name="sequenceIndex"></param>
  155. /// <param name="parameter"></param>
  156. /// <returns></returns>
  157. public override bool CheckPrecondition(List<SchedulerSequence> schedulerSequences, int sequenceIndex, object parameter, string materialId,ref string reason)
  158. {
  159. if (_state == RState.Running)
  160. {
  161. reason = "scheduler module is already running";
  162. return false;
  163. }
  164. if (_rinseEntity.IsBusy)
  165. {
  166. reason = $"{_rinseEntity.Module} is busy";
  167. return false;
  168. }
  169. if(_rinseEntity.WaferHolderInfo==null)
  170. {
  171. reason = $"{_rinseEntity.Module} has no wafer shuttle";
  172. return false;
  173. }
  174. if (_rinseEntity.WaferHolderInfo.Id != materialId)
  175. {
  176. reason = $"{_rinseEntity.Module} wafer shuttle {_rinseEntity.WaferHolderInfo.Id} is not matched with {materialId}";
  177. return false;
  178. }
  179. return true;
  180. }
  181. }
  182. }