| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 | using Aitex.Core.RT.Fsm;using Aitex.Core.RT.IOCore;using Aitex.Core.RT.Log;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using PunkHPX8_RT.Modules;using MECF.Framework.Common.CommonData;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.RecipeCenter;using SecsGem.Core.ItemModel;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;namespace PunkHPX8_RT.Schedulers{    public class SchedulerModuleTimeManager : Singleton<SchedulerModuleTimeManager>    {        /// <summary>        /// 确定后面所有PlatingCell、Qdr和Dryer资源        /// </summary>        /// <param name="schedulerSequences"></param>        /// <param name="waferHolderId"></param>        /// <param name="waferHolderMoveItem"></param>        /// <param name="sequenceIndex"></param>        /// <param name="materialId"></param>        /// <param name="existEnableCell"></param>        public bool ConfirmAllPlatingCellQdrAndDryer(List<SchedulerSequence> schedulerSequences, string waferHolderId, int sequenceIndex,bool checkConflict,DateTime startTime)        {            int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");            var avaibleResults = AnalyseAfterAvaibleCell(schedulerSequences, startTime, waferHolderId, sequenceIndex,checkConflict);            if (!avaibleResults.success)            {                return false;            }            if (avaibleResults.results.Count == 0 && avaibleResults.rinseResults.Item2 == ModuleName.Unknown && avaibleResults.dryerResults.Item2 == ModuleName.Unknown)            {                return false;            }            SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime();            SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime();            SchedulerModulePartTime dryerPartTime = new SchedulerModulePartTime();            //处理metal和Rinse            for (int i = 0; i < avaibleResults.results.Count; i++)            {                var item = avaibleResults.results[i];                int index = item.Item1;                SchedulerSequence sequence = schedulerSequences[index];                if (sequence.State == PunkHPX8_Core.RState.End)                {                    continue;                }                SchedulerSequence metalSequence = schedulerSequences[index + 1];                if (metalSequence.ModuleType != ModuleType.PlatingCell)                {                    continue;                }                DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe;                QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe;                int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime();                int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime();                DateTime metalStartTime = item.Item4.AddSeconds(transporterTransferSeconds);                if (metalSequence.SchedulerModule == null)                {                    metalSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item2);                    metalSequence.ModuleName = item.Item2;                                    }                if (!checkConflict)                {                    SchedulerTime lastSchedulerTime = SchedulerPlatingCellTimeManager.Instance.GetLastSchedulerTime(item.Item2.ToString());                    DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, metalPartTime, item.Item2.ToString(), depRecipeTimeLength, transporterTransferSeconds);                    if (lastSchedulerEndTime > metalStartTime)                    {                        metalStartTime = lastSchedulerEndTime;                    }                }                SchedulerPlatingCellTimeManager.Instance.AddPlatingCellScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime,                        depRecipeTimeLength, false);                SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item2.ToString(), ModuleType.PlatingCell, index + 1,                    metalStartTime, depRecipeTimeLength);                metalPartTime.AddScheduler(item.Item2.ToString(), waferHolderId, index + 1, metalStartTime, depRecipeTimeLength);                if (index + 3 >= schedulerSequences.Count)                {                    continue;                }                SchedulerSequence qdrSequence = schedulerSequences[index + 3];                if (qdrSequence.ModuleType != ModuleType.Rinse)                {                    continue;                }                if (qdrSequence.SchedulerModule == null)                {                    qdrSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(item.Item3);                    qdrSequence.ModuleName = item.Item3;                }                DateTime schedulerQdrStartTime = SchedulerQdrTimeManager.Instance.CalculateQdrSchedulerStartTime(metalStartTime, depRecipeTimeLength);                if (!checkConflict)                {                    SchedulerTime lastSchedulerTime = SchedulerQdrTimeManager.Instance.GetLastSchedulerTime(item.Item3.ToString());                    DateTime lastSchedulerEndTime = GetModuleLastSchedulerEndTime(lastSchedulerTime, qdrPartTime, item.Item3.ToString(), qdrRecipeTimeLength, transporterTransferSeconds);                    if (lastSchedulerEndTime > schedulerQdrStartTime)                    {                        schedulerQdrStartTime = lastSchedulerEndTime;                    }                }                SchedulerQdrTimeManager.Instance.AddQdrScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength, false);                SchedulerWaferHolderTimeManager.Instance.AddWaferHolderTime(waferHolderId, item.Item3.ToString(),ModuleType.Rinse, index + 3,                    schedulerQdrStartTime, qdrRecipeTimeLength);                qdrPartTime.AddScheduler(item.Item3.ToString(), waferHolderId, index + 3, schedulerQdrStartTime, qdrRecipeTimeLength);                            }            //处理单独Rinse            if (avaibleResults.rinseResults.Item2 != ModuleName.Unknown)            {                int transporterIndex = avaibleResults.rinseResults.Item1;                SchedulerSequence transporterSequence = schedulerSequences[transporterIndex];            }            //处理Dryer            if (avaibleResults.dryerResults.Item2 != ModuleName.Unknown)            {                int transporterIndex = avaibleResults.dryerResults.Item1;                SchedulerSequence transporterSequence = schedulerSequences[transporterIndex];            }            SchedulerPlatingCellTimeManager.Instance.WritePlatingCellSchedulerTimeLog();            SchedulerQdrTimeManager.Instance.WriteQdrSchedulerTimeLog();            SchedulerDryerTimeManager.Instance.WriteDryerSchedulerTimeLog();            SchedulerTransporterTimeManager.Instance.WriteTransporterSchedulerTimeLog();            SchedulerWaferHolderTimeManager.Instance.WriteSchedulerTimeLog(waferHolderId);            qdrPartTime.Dispose();            metalPartTime.Dispose();            dryerPartTime.Dispose();            return true;        }        /// <summary>        /// 获取最新调度时间        /// </summary>        /// <param name="schedulerTime"></param>        /// <param name="partTime"></param>        /// <param name="module"></param>        /// <param name="recipeLength"></param>        /// <param name="transporterTransferSeconds"></param>        /// <returns></returns>        private DateTime GetModuleLastSchedulerEndTime(SchedulerTime schedulerTime,SchedulerModulePartTime partTime,string module,int recipeLength,int transporterTransferSeconds)        {            DateTime lastSchedulerEndTime = DateTime.MinValue;            if (schedulerTime != null)            {                lastSchedulerEndTime = schedulerTime.ScheduleStartTime.AddSeconds(recipeLength).AddSeconds(transporterTransferSeconds);            }            DateTime lastPartTime = partTime.GetLastSchedulerTime(module);            if (lastPartTime.AddSeconds(transporterTransferSeconds) > lastSchedulerEndTime)            {                lastSchedulerEndTime = lastPartTime.AddSeconds(transporterTransferSeconds);            }            return lastSchedulerEndTime;        }        /// <summary>        /// 分析后面所有Cell可用资源        /// sequenceIndex为transporter对应的索引        /// </summary>        /// <param name="schedulerSequences"></param>        /// <param name="waferHolderId"></param>        /// <param name="sequenceIndex"></param>        /// <returns></returns>        public (bool success,List<(int, ModuleName, ModuleName, DateTime)> results, (int, ModuleName, DateTime) rinseResults,(int, ModuleName, DateTime) dryerResults) AnalyseAfterAvaibleCell(List<SchedulerSequence> schedulerSequences,            DateTime startTime, string waferHolderId, int sequenceIndex,bool checkConflict)        {            int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");            List<(int, ModuleName, ModuleName, DateTime)> results = new List<(int, ModuleName, ModuleName, DateTime)>();            var dryerResults = new ValueTuple<int, ModuleName, DateTime>();            dryerResults.Item2 = ModuleName.Unknown;            var rinseResults = new ValueTuple<int, ModuleName, DateTime>();            rinseResults.Item2 = ModuleName.Unknown;            SchedulerModulePartTime metalPartTime = new SchedulerModulePartTime();            SchedulerModulePartTime qdrPartTime = new SchedulerModulePartTime();            for (int i = sequenceIndex; i < schedulerSequences.Count; i++)            {                SchedulerSequence sequence = schedulerSequences[i];                if (sequence.State == PunkHPX8_Core.RState.End)                {                    continue;                }                SchedulerSequence metalSequence = schedulerSequences[i + 1];                if (metalSequence.Recipe == null || !(metalSequence.Recipe is DepRecipe))                {                    continue;                }                DepRecipe depRecipe = (DepRecipe)metalSequence.Recipe;                QdrRecipe qdrRecipe = (QdrRecipe)metalSequence.NextRecipe;                int depRecipeTimeLength = depRecipe.CalculateRecipeTotalTime();                int qdrRecipeTimeLength = qdrRecipe.CalculateRunRecipeTime();                startTime = startTime.AddSeconds(transporterTransferSeconds).AddSeconds(depRecipeTimeLength)                    .AddSeconds(transporterTransferSeconds).AddSeconds(qdrRecipeTimeLength);                i += 3;            }            metalPartTime.Dispose();            qdrPartTime.Dispose();            return (true, results,rinseResults, dryerResults);        }    }}
 |