SchedulerSequenceRecipeManager.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. using Aitex.Core.RT.Fsm;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.Util;
  4. using MECF.Framework.Common.Equipment;
  5. using MECF.Framework.Common.RecipeCenter;
  6. using MECF.Framework.Common.ToolLayout;
  7. using MECF.Framework.Common.WaferHolder;
  8. using CyberX8_RT.Modules;
  9. using CyberX8_RT.Modules.Dryer;
  10. using CyberX8_RT.Modules.Metal;
  11. using CyberX8_RT.Modules.Reservoir;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using CyberX8_RT.Modules.Rinse;
  18. namespace CyberX8_RT.Schedulers
  19. {
  20. public class SchedulerSequenceRecipeManager : Singleton<SchedulerSequenceRecipeManager>
  21. {
  22. /// <summary>
  23. /// 是否存在可用的cell
  24. /// </summary>
  25. /// <param name="sequenceRecipe"></param>
  26. /// <returns></returns>
  27. public bool ExistAvaibleProcessCell(SequenceRecipe sequenceRecipe, bool showError, bool checkSrd = false)
  28. {
  29. if (sequenceRecipe == null)
  30. {
  31. if (showError)
  32. {
  33. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", "sequence recipe is null");
  34. }
  35. return false;
  36. }
  37. int count = 0;
  38. for (int i = 0; i < sequenceRecipe.Recipes.Count; i++)
  39. {
  40. string item = sequenceRecipe.Recipes[i];
  41. if (string.IsNullOrEmpty(item))
  42. {
  43. continue;
  44. }
  45. if (item.ToLower().EndsWith("srd.rcp") && !checkSrd)
  46. {
  47. continue;
  48. }
  49. if (item.ToLower().EndsWith("srd.rcp") && !checkSrd)
  50. {
  51. continue;
  52. }
  53. if (i == 0 && item.ToLower().EndsWith("qdr.rcp"))
  54. {
  55. RinseItem rinseItem = RinseItemManager.Instance.GetPrewetRinseItem();
  56. if (rinseItem == null)
  57. {
  58. if (showError)
  59. {
  60. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequence {sequenceRecipe.Ppid} has no pwt rinse cell");
  61. }
  62. return false;
  63. }
  64. RinseEntity rinseEntity = Singleton<RouteManager>.Instance.GetModule<RinseEntity>(rinseItem.ModuleName.ToString());
  65. if (rinseEntity == null)
  66. {
  67. if (showError)
  68. {
  69. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequence {sequenceRecipe.Ppid} has no pwt rinse entity");
  70. }
  71. return false;
  72. }
  73. if (!rinseEntity.IsAuto)
  74. {
  75. if (showError)
  76. {
  77. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequence {sequenceRecipe.Ppid} {rinseEntity.Module} is not avaible");
  78. }
  79. return false;
  80. }
  81. if (rinseEntity.IsError)
  82. {
  83. if (showError)
  84. {
  85. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequence {sequenceRecipe.Ppid} {rinseEntity.Module} is in error state");
  86. }
  87. return false;
  88. }
  89. }
  90. ModuleType moduleType = SequenceRecipeManager.Instance.GetModuleType(item);
  91. if (moduleType == ModuleType.None)
  92. {
  93. if (showError)
  94. {
  95. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequence {sequenceRecipe.Ppid} item {item} is invalid type");
  96. }
  97. return false;
  98. }
  99. if (moduleType == ModuleType.Metal)
  100. {
  101. DepRecipe depRecipe =(DepRecipe)SequenceRecipeManager.Instance.LoadSequenceTypeRecipe(sequenceRecipe.SequenceType,item, RecipeType.DEP);
  102. if (depRecipe == null)
  103. {
  104. if (showError)
  105. {
  106. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequece {sequenceRecipe.Ppid} metal recipe {depRecipe.Ppid} is invalid ");
  107. }
  108. return false;
  109. }
  110. List<MetalEntity> metals = SchedulerSequenceManager.Instance.GetAvaibleMetalList(depRecipe.Chemistry,sequenceRecipe.SequenceType,sequenceRecipe.SubstrateSize,false);
  111. if(metals.Count==0)
  112. {
  113. if (showError)
  114. {
  115. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequece {sequenceRecipe.Ppid} metal recipe {depRecipe.Ppid} chemistry {depRecipe.Chemistry} has not avaible metal cell");
  116. }
  117. return false;
  118. }
  119. if (i < sequenceRecipe.Recipes.Count - 1)
  120. {
  121. MetalEntity metal = metals[0];
  122. string nextModuleType = sequenceRecipe.Recipes[i + 1];
  123. ModuleType nextModuleTypeEnum = SequenceRecipeManager.Instance.GetModuleType(nextModuleType);
  124. if (nextModuleTypeEnum==ModuleType.Rinse)
  125. {
  126. ModuleName rinseModule= SchedulerSequenceManager.Instance.GetAvaibleModuleCell(sequenceRecipe.SequenceType,
  127. nextModuleTypeEnum, metal.Module);
  128. if (rinseModule == ModuleName.Unknown)
  129. {
  130. if (showError)
  131. {
  132. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequece {sequenceRecipe.Ppid} metal {metal.Module} has not avaible {nextModuleTypeEnum} cell");
  133. }
  134. return false;
  135. }
  136. }
  137. }
  138. }
  139. else
  140. {
  141. ModuleName moduleName= SchedulerSequenceManager.Instance.GetAvaibleModuleCell(sequenceRecipe.SequenceType,moduleType);
  142. if(moduleName==ModuleName.Unknown)
  143. {
  144. if (showError)
  145. {
  146. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequece {sequenceRecipe.Ppid} has not avaible {moduleType} module");
  147. }
  148. return false;
  149. }
  150. }
  151. count++;
  152. }
  153. if (count == 0)
  154. {
  155. if (showError)
  156. {
  157. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", $"sequece {sequenceRecipe.Ppid} not set avaible cell");
  158. }
  159. return false;
  160. }
  161. return true;
  162. }
  163. /// <summary>
  164. /// 获取sequence的化学液
  165. /// </summary>
  166. /// <param name="sequenceRecipe"></param>
  167. /// <returns></returns>
  168. public List<string> GetSequenceChemistry(SequenceRecipe sequenceRecipe)
  169. {
  170. List<string> chemistries = new List<string>();
  171. for (int i = 0; i < sequenceRecipe.Recipes.Count; i++)
  172. {
  173. string item = sequenceRecipe.Recipes[i];
  174. if (string.IsNullOrEmpty(item))
  175. {
  176. continue;
  177. }
  178. ModuleType moduleType = SequenceRecipeManager.Instance.GetModuleType(item);
  179. if (moduleType == ModuleType.Metal)
  180. {
  181. DepRecipe depRecipe = (DepRecipe)SequenceRecipeManager.Instance.LoadSequenceTypeRecipe(sequenceRecipe.SequenceType, item, RecipeType.DEP);
  182. if (!chemistries.Contains(depRecipe.Chemistry))
  183. {
  184. chemistries.Add(depRecipe.Chemistry);
  185. }
  186. }
  187. }
  188. return chemistries;
  189. }
  190. /// <summary>
  191. /// 是否Sequence Recipe是否可用
  192. /// </summary>
  193. /// <param name="sequenceRecipe"></param>
  194. /// <returns></returns>
  195. public bool CheckSequenceRecipeAvaible(SequenceRecipe sequenceRecipe,ref string reason)
  196. {
  197. if (sequenceRecipe == null)
  198. {
  199. reason = "sequence recipe is null";
  200. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", reason);
  201. return false;
  202. }
  203. for (int i = 0; i < sequenceRecipe.Recipes.Count; i++)
  204. {
  205. string item = sequenceRecipe.Recipes[i];
  206. if (string.IsNullOrEmpty(item))
  207. {
  208. continue;
  209. }
  210. RecipeType recipeType= SequenceRecipeManager.Instance.GetRecipeType(item);
  211. object recipe = SequenceRecipeManager.Instance.LoadSequenceTypeRecipe(sequenceRecipe.SequenceType, item, recipeType);
  212. if (recipe == null)
  213. {
  214. reason = $"{item} is not in {sequenceRecipe.SequenceType}";
  215. LOG.WriteLog(eEvent.ERR_SEQUENCE, "System", reason);
  216. return false;
  217. }
  218. }
  219. return true;
  220. }
  221. }
  222. }