SchedulerModuleTimeManager.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using Aitex.Core.RT.Fsm;
  2. using Aitex.Core.RT.IOCore;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using PunkHPX8_RT.Modules;
  7. using MECF.Framework.Common.CommonData;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.RecipeCenter;
  10. using SecsGem.Core.ItemModel;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using System.Reflection;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. namespace PunkHPX8_RT.Schedulers
  18. {
  19. public class SchedulerModuleTimeManager : Singleton<SchedulerModuleTimeManager>
  20. {
  21. /// <summary>
  22. /// 确定后面所有PlatingCell、Qdr和Dryer资源
  23. /// </summary>
  24. /// <param name="schedulerSequences"></param>
  25. /// <param name="waferHolderId"></param>
  26. /// <param name="waferHolderMoveItem"></param>
  27. /// <param name="sequenceIndex"></param>
  28. /// <param name="materialId"></param>
  29. /// <param name="existEnableCell"></param>
  30. public bool ConfirmAllPlatingCellQdrAndDryer(List<SchedulerSequence> schedulerSequences, string waferHolderId, int sequenceIndex,bool checkConflict,DateTime startTime)
  31. {
  32. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  33. var avaibleResults = AnalyseAfterAvaibleCell(schedulerSequences, startTime, waferHolderId, sequenceIndex,checkConflict);
  34. if (!avaibleResults.success)
  35. {
  36. return false;
  37. }
  38. if (avaibleResults.results.Count == 0 && avaibleResults.rinseResults.Item2 == ModuleName.Unknown && avaibleResults.dryerResults.Item2 == ModuleName.Unknown)
  39. {
  40. return false;
  41. }
  42. SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime();
  43. SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime();
  44. SchedulerModulePartTime dryerPartTime = new SchedulerModulePartTime();
  45. //处理metal和Rinse
  46. for (int i = 0; i < avaibleResults.results.Count; i++)
  47. {
  48. var item = avaibleResults.results[i];
  49. int index = item.Item1;
  50. SchedulerSequence sequence = schedulerSequences[index];
  51. if (sequence.State == PunkHPX8_Core.RState.End)
  52. {
  53. continue;
  54. }
  55. SchedulerSequence metalSequence = schedulerSequences[index + 1];
  56. if (metalSequence.ModuleType != ModuleType.PlatingCell)
  57. {
  58. continue;
  59. }
  60. DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe;
  61. QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe;
  62. int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime();
  63. int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime();
  64. DateTime metalStartTime = item.Item4.AddSeconds(transporterTransferSeconds);
  65. if (metalSequence.SchedulerModule == null)
  66. {
  67. metalSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item2);
  68. metalSequence.ModuleName = item.Item2;
  69. }
  70. if (!checkConflict)
  71. {
  72. SchedulerTime lastSchedulerTime = SchedulerPlatingCellTimeManager.Instance.GetLastSchedulerTime(item.Item2.ToString());
  73. DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, metalPartTime, item.Item2.ToString(), depRecipeTimeLength, transporterTransferSeconds);
  74. if (lastSchedulerEndTime > metalStartTime)
  75. {
  76. metalStartTime = lastSchedulerEndTime;
  77. }
  78. }
  79. SchedulerPlatingCellTimeManager.Instance.AddPlatingCellScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime,
  80. depRecipeTimeLength, false);
  81. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item2.ToString(), ModuleType.PlatingCell, index + 1,
  82. metalStartTime, depRecipeTimeLength);
  83. metalPartTime.AddScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime, depRecipeTimeLength);
  84. if (index + 3 >= schedulerSequences.Count)
  85. {
  86. continue;
  87. }
  88. SchedulerSequence qdrSequence = schedulerSequences[index + 3];
  89. if (qdrSequence.ModuleType != ModuleType.Rinse)
  90. {
  91. continue;
  92. }
  93. if (qdrSequence.SchedulerModule == null)
  94. {
  95. qdrSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item3);
  96. qdrSequence.ModuleName = item.Item3;
  97. }
  98. DateTime schedulerQdrStartTime = SchedulerQdrTimeManager.Instance.CalculateQdrSchedulerStartTime(metalStartTime, depRecipeTimeLength);
  99. if (!checkConflict)
  100. {
  101. SchedulerTime lastSchedulerTime = SchedulerQdrTimeManager.Instance.GetLastSchedulerTime(item.Item3.ToString());
  102. DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, qdrPartTime, item.Item3.ToString(), qdrRecipeTimeLength, transporterTransferSeconds);
  103. if (lastSchedulerEndTime > schedulerQdrStartTime)
  104. {
  105. schedulerQdrStartTime = lastSchedulerEndTime;
  106. }
  107. }
  108. SchedulerQdrTimeManager.Instance.AddQdrScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength, false);
  109. SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item3.ToString(),ModuleType.Rinse, index + 3,
  110. schedulerQdrStartTime, qdrRecipeTimeLength);
  111. qdrPartTime.AddScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength);
  112. }
  113. //处理单独Rinse
  114. if (avaibleResults.rinseResults.Item2 != ModuleName.Unknown)
  115. {
  116. int transporterIndex = avaibleResults.rinseResults.Item1;
  117. SchedulerSequence transporterSequence = schedulerSequences[transporterIndex];
  118. }
  119. //处理Dryer
  120. if (avaibleResults.dryerResults.Item2 != ModuleName.Unknown)
  121. {
  122. int transporterIndex = avaibleResults.dryerResults.Item1;
  123. SchedulerSequence transporterSequence = schedulerSequences[transporterIndex];
  124. }
  125. SchedulerPlatingCellTimeManager.Instance.WritePlatingCellSchedulerTimeLog();
  126. SchedulerQdrTimeManager.Instance.WriteQdrSchedulerTimeLog();
  127. SchedulerDryerTimeManager.Instance.WriteDryerSchedulerTimeLog();
  128. SchedulerTransporterTimeManager.Instance.WriteTransporterSchedulerTimeLog();
  129. SchedulerWaferHolderTimeManager.Instance.WriteSchedulerTimeLog(waferHolderId);
  130. qdrPartTime.Dispose();
  131. metalPartTime.Dispose();
  132. dryerPartTime.Dispose();
  133. return true;
  134. }
  135. /// <summary>
  136. /// 获取最新调度时间
  137. /// </summary>
  138. /// <param name="schedulerTime"></param>
  139. /// <param name="partTime"></param>
  140. /// <param name="module"></param>
  141. /// <param name="recipeLength"></param>
  142. /// <param name="transporterTransferSeconds"></param>
  143. /// <returns></returns>
  144. private DateTime GetModuleLastSchedulerEndTime(SchedulerTime schedulerTime,SchedulerModulePartTime partTime,string module,int recipeLength,int transporterTransferSeconds)
  145. {
  146. DateTime lastSchedulerEndTime = DateTime.MinValue;
  147. if (schedulerTime != null)
  148. {
  149. lastSchedulerEndTime = schedulerTime.ScheduleStartTime.AddSeconds(recipeLength).AddSeconds(transporterTransferSeconds);
  150. }
  151. DateTime lastPartTime = partTime.GetLastSchedulerTime(module);
  152. if (lastPartTime.AddSeconds(transporterTransferSeconds) > lastSchedulerEndTime)
  153. {
  154. lastSchedulerEndTime = lastPartTime.AddSeconds(transporterTransferSeconds);
  155. }
  156. return lastSchedulerEndTime;
  157. }
  158. /// <summary>
  159. /// 分析后面所有Cell可用资源
  160. /// sequenceIndex为transporter对应的索引
  161. /// </summary>
  162. /// <param name="schedulerSequences"></param>
  163. /// <param name="waferHolderId"></param>
  164. /// <param name="sequenceIndex"></param>
  165. /// <returns></returns>
  166. public (bool success,List<(int, ModuleName, ModuleName, DateTime)> results, (int, ModuleName, DateTime) rinseResults,(int, ModuleName, DateTime) dryerResults) AnalyseAfterAvaibleCell(List<SchedulerSequence> schedulerSequences,
  167. DateTime startTime, string waferHolderId, int sequenceIndex,bool checkConflict)
  168. {
  169. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  170. List<(int, ModuleName, ModuleName, DateTime)> results = new List<(int, ModuleName, ModuleName, DateTime)>();
  171. var dryerResults = new ValueTuple<int, ModuleName, DateTime>();
  172. dryerResults.Item2 = ModuleName.Unknown;
  173. var rinseResults = new ValueTuple<int, ModuleName, DateTime>();
  174. rinseResults.Item2 = ModuleName.Unknown;
  175. SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime();
  176. SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime();
  177. for (int i = sequenceIndex; i < schedulerSequences.Count; i++)
  178. {
  179. SchedulerSequence sequence = schedulerSequences[i];
  180. if (sequence.State == PunkHPX8_Core.RState.End)
  181. {
  182. continue;
  183. }
  184. SchedulerSequence metalSequence = schedulerSequences[i + 1];
  185. if (metalSequence.Recipe == null || !(metalSequence.Recipe is DepRecipe))
  186. {
  187. continue;
  188. }
  189. DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe;
  190. QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe;
  191. int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime();
  192. int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime();
  193. startTime = startTime.AddSeconds(transporterTransferSeconds).AddSeconds(depRecipeTimeLength)
  194. .AddSeconds(transporterTransferSeconds).AddSeconds(qdrRecipeTimeLength);
  195. i += 3;
  196. }
  197. metalPartTime.Dispose();
  198. qdrPartTime.Dispose();
  199. return (true, results,rinseResults, dryerResults);
  200. }
  201. }
  202. }