将ControlJobManager引入AutoTransfer对象,并修改CJ相关代码。【未测试】
This commit is contained in:
parent
ddeb6bc7dd
commit
3b830c03d8
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using Aitex.Core.Common;
|
||||
using Aitex.Core.RT.DataCenter;
|
||||
using Aitex.Core.RT.Device;
|
||||
using Aitex.Core.RT.Device.Unit;
|
||||
using Aitex.Core.RT.Event;
|
||||
using Aitex.Core.RT.Log;
|
||||
using Aitex.Core.RT.OperationCenter;
|
||||
|
@ -12,7 +13,6 @@ using Aitex.Core.RT.Routine;
|
|||
using Aitex.Core.RT.SCCore;
|
||||
using Aitex.Core.Util;
|
||||
using Aitex.Sorter.Common;
|
||||
using Mainframe.UnLoads;
|
||||
using MECF.Framework.Common.DBCore;
|
||||
using MECF.Framework.Common.Equipment;
|
||||
using MECF.Framework.Common.Jobs;
|
||||
|
@ -35,9 +35,12 @@ namespace SicRT.Modules
|
|||
public int TrayProcessCount { get; set; }
|
||||
}
|
||||
|
||||
private List<ControlJobInfoEx> _lstNeedMapJob = new List<ControlJobInfoEx>();
|
||||
private List<ControlJobInfoEx> _lstControlJobs = new List<ControlJobInfoEx>();
|
||||
private List<ProcessJobInfo> _lstProcessJobs = new List<ProcessJobInfo>();
|
||||
//private List<ControlJobInfoEx> _lstNeedMapJob = new List<ControlJobInfoEx>();
|
||||
|
||||
private readonly ControlJobManager _cjManager;
|
||||
|
||||
//rivate List<ControlJobInfoEx> _lstControlJobs = new List<ControlJobInfoEx>();
|
||||
//private List<ProcessJobInfo> _lstProcessJobs = new List<ProcessJobInfo>();
|
||||
private List<TrayInfo> _lstProcessedTrayInfo = new List<TrayInfo>(); //保存石墨盘的进入腔体的信息(最多4次工艺需要换盘)
|
||||
|
||||
private int _maxTrayCount = 2; //可以同时运行的石墨盘总数
|
||||
|
@ -116,7 +119,7 @@ namespace SicRT.Modules
|
|||
DATA.Subscribe("Scheduler.WhichCondition", () => WhichCondition);
|
||||
|
||||
//DATA.Subscribe("CassAL.SlotSequenceList", () => currentSlotSequenceList["CassAL"]);
|
||||
DATA.Subscribe("CassAL.LocalJobName", () =>
|
||||
/*DATA.Subscribe("CassAL.LocalJobName", () =>
|
||||
{
|
||||
var jb = _lstControlJobs.FirstOrDefault(x => x.Module == "CassAL");
|
||||
if (jb != null)
|
||||
|
@ -144,7 +147,7 @@ namespace SicRT.Modules
|
|||
if (jb != null)
|
||||
return jb.State.ToString();
|
||||
return "";
|
||||
});
|
||||
});*/
|
||||
|
||||
OP.Subscribe($"{ModuleName.TM}.ResetTask", (string cmd, object[] args) =>
|
||||
{
|
||||
|
@ -172,9 +175,11 @@ namespace SicRT.Modules
|
|||
});
|
||||
|
||||
_signalTower = DEVICE.GetDevice<SicPM.Devices.IoSignalTower>("PM1.SignalTower");
|
||||
|
||||
_cjManager = new ControlJobManager();
|
||||
}
|
||||
|
||||
public bool HasJobRunning => _lstControlJobs.Count > 0;
|
||||
public bool HasJobRunning => _cjManager.InQueueJobCount > 0;
|
||||
|
||||
|
||||
public void Clear()
|
||||
|
@ -184,8 +189,7 @@ namespace SicRT.Modules
|
|||
sch.ResetTask();
|
||||
}
|
||||
|
||||
_lstControlJobs.Clear();
|
||||
_lstProcessJobs.Clear();
|
||||
_cjManager.ClearAll();
|
||||
_bufferWaferInfo.Clear();
|
||||
}
|
||||
|
||||
|
@ -237,13 +241,14 @@ namespace SicRT.Modules
|
|||
EV.PostWarningLog(LogSource, reason);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(jobId))
|
||||
{
|
||||
jobId = "CJ_Local_" + module + DateTime.Now;
|
||||
}
|
||||
|
||||
if (_lstControlJobs.Exists(x => x.Name == jobId))
|
||||
// 检查指定名称的CJ是否存在。
|
||||
if (_cjManager.TryFindByName(jobId, out _))
|
||||
{
|
||||
reason = $"LotID : {jobId} already created";
|
||||
EV.PostWarningLog(LogSource, reason);
|
||||
|
@ -375,12 +380,9 @@ namespace SicRT.Modules
|
|||
}
|
||||
|
||||
foreach (var pj in pjs)
|
||||
{
|
||||
cj.ProcessJobList.Add(pj);
|
||||
_lstProcessJobs.Add(pj);
|
||||
}
|
||||
|
||||
_lstControlJobs.Add(cj);
|
||||
_cjManager.Add(cj);
|
||||
|
||||
var totalWafer = 0;
|
||||
foreach (var pj in pjs)
|
||||
|
@ -564,29 +566,18 @@ namespace SicRT.Modules
|
|||
// EV.PostWarningLog(LogSource, $"stop job rejected, not found job with id {jobName}");
|
||||
// return;
|
||||
//}
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
{
|
||||
if (pj.ControlJobName == cj.Name)
|
||||
{
|
||||
pj.SetState(EnumProcessJobState.Stopping);
|
||||
}
|
||||
}
|
||||
|
||||
if (_cycleSetPoint > 0)
|
||||
{
|
||||
_cycleSetPoint = _cycledCount;
|
||||
}
|
||||
}
|
||||
_cjManager.StopAllJob();
|
||||
if (_cycleSetPoint > 0)
|
||||
_cycleSetPoint = _cycledCount;
|
||||
}
|
||||
|
||||
internal void AbortJob(string jobName)
|
||||
internal void AbortJob()
|
||||
{
|
||||
var cj = _lstControlJobs.Find(x => x.Name == jobName);
|
||||
_cjManager.AbortJob(out var cj);
|
||||
|
||||
if (cj == null)
|
||||
{
|
||||
EV.PostWarningLog(LogSource, $"abort job rejected, not found job with id {jobName}");
|
||||
EV.PostWarningLog(LogSource, $"abort job rejected, the current cj is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -594,7 +585,7 @@ namespace SicRT.Modules
|
|||
int aborted_cj = 0;
|
||||
|
||||
var pjAbortList = new List<ProcessJobInfo>();
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (pj.ControlJobName == cj.Name)
|
||||
{
|
||||
|
@ -617,57 +608,24 @@ namespace SicRT.Modules
|
|||
JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pj in pjAbortList)
|
||||
{
|
||||
_lstProcessJobs.Remove(pj);
|
||||
}
|
||||
|
||||
_lstControlJobs.Remove(cj);
|
||||
|
||||
|
||||
_dbCallback.LotFinished(cj);
|
||||
JobDataRecorder.EndCJ(cj.InnerId.ToString(), aborted_cj, unprocessed_cj);
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
public void ResumeJob(string jobName)
|
||||
public void ResumeJob()
|
||||
{
|
||||
//ControlJobInfoEx cj = _lstControlJobs.Find(x => x.Name == jobName);
|
||||
//if (cj == null)
|
||||
//{
|
||||
// EV.PostWarningLog(LogSource, $"resume job rejected, not found job with id {jobName}");
|
||||
// return;
|
||||
//}
|
||||
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Paused)
|
||||
{
|
||||
cj.SetState(EnumControlJobState.Executing);
|
||||
}
|
||||
}
|
||||
_cjManager.ResumeJob();
|
||||
}
|
||||
|
||||
internal void PauseJob(string jobName)
|
||||
internal void PauseJob()
|
||||
{
|
||||
//ControlJobInfoEx cj = _lstControlJobs.Find(x => x.Name == jobName);
|
||||
//if (cj == null)
|
||||
//{
|
||||
// EV.PostWarningLog(LogSource, $"pause job rejected, not found job with id {jobName}");
|
||||
// return;
|
||||
//}
|
||||
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
{
|
||||
cj.SetState(EnumControlJobState.Paused);
|
||||
}
|
||||
}
|
||||
_cjManager.PauseJob();
|
||||
}
|
||||
|
||||
internal void StartJob(string jobName)
|
||||
internal void StartJob()
|
||||
{
|
||||
GetConfig();
|
||||
|
||||
|
@ -686,18 +644,13 @@ namespace SicRT.Modules
|
|||
// _cycledCount = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
foreach (var cj in _lstControlJobs)
|
||||
|
||||
_cjManager.StartJob(cj =>
|
||||
{
|
||||
if (cj.State == EnumControlJobState.WaitingForStart)
|
||||
{
|
||||
cj.BeginTime = DateTime.Now;
|
||||
cj.LotInnerId = Guid.NewGuid();
|
||||
_dbCallback.LotCreated(cj);
|
||||
|
||||
cj.SetState(EnumControlJobState.Executing);
|
||||
}
|
||||
}
|
||||
cj.BeginTime = DateTime.Now;
|
||||
cj.LotInnerId = Guid.NewGuid();
|
||||
_dbCallback.LotCreated(cj);
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -759,12 +712,10 @@ namespace SicRT.Modules
|
|||
{
|
||||
EV.PostAlarmLog("System", "Tray ProcessCount Exhausted , No Tray for next Process !");
|
||||
}
|
||||
|
||||
ControlJobInfoEx cjActive = _lstControlJobs.Find(x => x.State == EnumControlJobState.Executing);
|
||||
if (cjActive != null)
|
||||
{
|
||||
|
||||
// 如果有CJ正在执行,则轮询所有Modules。
|
||||
if ( _cjManager.ExecutingCj != null)
|
||||
MonitorModuleTasks();
|
||||
}
|
||||
|
||||
MonitorModuleError();
|
||||
|
||||
|
@ -865,7 +816,11 @@ namespace SicRT.Modules
|
|||
|
||||
private void UpdateProcessJobStatus()
|
||||
{
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
var executingCj = _cjManager.ExecutingCj;
|
||||
if (executingCj == null)
|
||||
return;
|
||||
|
||||
foreach (var pj in executingCj.ProcessJobList)
|
||||
{
|
||||
if (pj.State == EnumProcessJobState.Processing)
|
||||
{
|
||||
|
@ -902,183 +857,73 @@ namespace SicRT.Modules
|
|||
|
||||
private void UpdateControlJobStatus()
|
||||
{
|
||||
if (_lstControlJobs.Count == 0)
|
||||
if (_cjManager.InQueueJobCount == 0)
|
||||
return;
|
||||
|
||||
var allControlJobComplete = true;
|
||||
var cjRemoveList = new List<ControlJobInfoEx>();
|
||||
foreach (var cj in _lstControlJobs)
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return;
|
||||
|
||||
// 检查是否所有的PJ已执行完毕。
|
||||
if (_cjManager.CheckCjDone())
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
{
|
||||
bool allPjCompleted = true;
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (pj == null)
|
||||
{
|
||||
LOG.Error($"Not find pj named {pj} in {cj.Name}");
|
||||
continue;
|
||||
}
|
||||
if (pj.State != EnumProcessJobState.Complete && pj.State != EnumProcessJobState.ProcessingComplete)
|
||||
{
|
||||
allPjCompleted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cj.SetState(EnumControlJobState.Completed);
|
||||
|
||||
if (allPjCompleted)
|
||||
{
|
||||
cj.SetState(EnumControlJobState.Completed);
|
||||
int unprocessed_cj = 0;
|
||||
int aborted_cj = 0;
|
||||
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
{
|
||||
if (pj.ControlJobName == cj.Name)
|
||||
{
|
||||
int unprocessed = 0;
|
||||
int aborted = 0;
|
||||
WaferInfo[] wafers = WaferManager.Instance.GetWaferByProcessJob(pj.Name);
|
||||
foreach (var waferInfo in wafers)
|
||||
{
|
||||
waferInfo.ProcessJob = null;
|
||||
waferInfo.NextSequenceStep = 0;
|
||||
if (waferInfo.ProcessState != EnumWaferProcessStatus.Completed)
|
||||
{
|
||||
unprocessed++;
|
||||
unprocessed_cj++;
|
||||
}
|
||||
}
|
||||
JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
|
||||
}
|
||||
}
|
||||
|
||||
JobDataRecorder.EndCJ(cj.InnerId.ToString(), aborted_cj, unprocessed_cj);
|
||||
_dbCallback.LotFinished(cj);
|
||||
}
|
||||
}
|
||||
|
||||
if (cj.State == EnumControlJobState.Completed)
|
||||
{
|
||||
cjRemoveList.Add(cj);
|
||||
}
|
||||
|
||||
allControlJobComplete = allControlJobComplete && cj.State == EnumControlJobState.Completed;
|
||||
}
|
||||
|
||||
if (_isCycleMode && _cycledCount < _cycleSetPoint)
|
||||
{
|
||||
int countPerCycle = 0;
|
||||
int countProcessed = 0;
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
{
|
||||
foreach (var pjSlotWafer in pj.SlotWafers)
|
||||
{
|
||||
countPerCycle++;
|
||||
WaferInfo wafer = GetModule(pjSlotWafer.Item1).GetWaferInfo(pjSlotWafer.Item2);
|
||||
if (!wafer.IsEmpty && !GetModule(pjSlotWafer.Item1).CheckWaferNeedProcess(pjSlotWafer.Item2))
|
||||
countProcessed++;
|
||||
}
|
||||
}
|
||||
|
||||
_cycledWafer = _cycledCount * countPerCycle + countProcessed;
|
||||
//StatsDataManager.Instance.SetValue(StatsNameTotalRunningWafer, _totalWaferWhenStart + _cycledWafer);
|
||||
|
||||
|
||||
if (allControlJobComplete)
|
||||
{
|
||||
_cycledCount++;
|
||||
|
||||
if (_cycledCount < _cycleSetPoint)
|
||||
{
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
cj.SetState(EnumControlJobState.Executing);
|
||||
}
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
{
|
||||
pj.SetState(EnumProcessJobState.Queued);
|
||||
pj.InnerId = Guid.NewGuid();
|
||||
foreach (var pjSlotWafer in pj.SlotWafers)
|
||||
{
|
||||
WaferInfo wafer = GetModule(pjSlotWafer.Item1).GetWaferInfo(pjSlotWafer.Item2);
|
||||
|
||||
wafer.ProcessJob = null;
|
||||
wafer.NextSequenceStep = 0;
|
||||
wafer.ProcessState = EnumWaferProcessStatus.Idle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (var cj in cjRemoveList)
|
||||
{
|
||||
var pjRemoveList = new List<ProcessJobInfo>();
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (pj.ControlJobName == cj.Name)
|
||||
pjRemoveList.Add(pj);
|
||||
{
|
||||
int unprocessed = 0;
|
||||
int aborted = 0;
|
||||
WaferInfo[] wafers = WaferManager.Instance.GetWaferByProcessJob(pj.Name);
|
||||
foreach (var waferInfo in wafers)
|
||||
{
|
||||
waferInfo.ProcessJob = null;
|
||||
waferInfo.NextSequenceStep = 0;
|
||||
if (waferInfo.ProcessState != EnumWaferProcessStatus.Completed)
|
||||
{
|
||||
unprocessed++;
|
||||
}
|
||||
}
|
||||
|
||||
JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pj in pjRemoveList)
|
||||
{
|
||||
_lstProcessJobs.Remove(pj);
|
||||
}
|
||||
|
||||
_lstControlJobs.Remove(cj);
|
||||
}
|
||||
|
||||
ControlJobInfoEx cjActived = null;
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
{
|
||||
cjActived = cj;
|
||||
break;
|
||||
}
|
||||
JobDataRecorder.EndCJ(cj.InnerId.ToString(), 0, _cjManager.InQueueJobCount - 1);
|
||||
_cjManager.FinishJob();
|
||||
_dbCallback.LotFinished(cj);
|
||||
}
|
||||
}
|
||||
|
||||
private void StartNewJob()
|
||||
{
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
{
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (pj == null)
|
||||
{
|
||||
LOG.Error($"Not find pj named {pj} in {cj.Name}");
|
||||
continue;
|
||||
}
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return;
|
||||
|
||||
if (pj.State == EnumProcessJobState.Queued)
|
||||
{
|
||||
ActiveProcessJob(pj);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (pj == null)
|
||||
{
|
||||
LOG.Error($"some pj in {cj.Name} is null.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pj.State == EnumProcessJobState.Queued)
|
||||
{
|
||||
ActiveProcessJob(cj, pj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckAllJobDone()
|
||||
{
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing || cj.State == EnumControlJobState.Paused)
|
||||
return false;
|
||||
}
|
||||
if (_lstControlJobs.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return _cjManager.InQueueJobCount == 0;
|
||||
}
|
||||
|
||||
private bool ActiveProcessJob(ProcessJobInfo pj)
|
||||
private bool ActiveProcessJob(ControlJobInfoEx cj, ProcessJobInfo pj)
|
||||
{
|
||||
//_lstPms.Clear();
|
||||
//for (int i = 0; i < pj.Sequence.Steps.Count; i++)
|
||||
|
@ -1101,9 +946,7 @@ namespace SicRT.Modules
|
|||
|
||||
WaferDataRecorder.SetPjInfo(wafer.InnerId.ToString(), pj.InnerId.ToString());
|
||||
}
|
||||
|
||||
ControlJobInfoEx cj = _lstControlJobs.Find(x => x.Name == pj.ControlJobName);
|
||||
|
||||
|
||||
CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
|
||||
JobDataRecorder.StartPJ(pj.InnerId.ToString(), null, cj.InnerId.ToString(), pj.Name, cj.Module, cj.Module, pj.SlotWafers.Count);
|
||||
pj.SetState(EnumProcessJobState.Processing);
|
||||
|
@ -2847,7 +2690,12 @@ namespace SicRT.Modules
|
|||
|
||||
public bool CheckBufferWaferHasJob()
|
||||
{
|
||||
WaferInfo wafer = SchBuffer.GetWaferInfo(0);
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return false;
|
||||
|
||||
|
||||
var wafer = SchBuffer.GetWaferInfo(0);
|
||||
|
||||
if (wafer.IsEmpty)
|
||||
{
|
||||
|
@ -2858,7 +2706,7 @@ namespace SicRT.Modules
|
|||
return false;
|
||||
}
|
||||
|
||||
ProcessJobInfo pj = _lstProcessJobs.Find(x => x.InnerId == wafer.ProcessJob.InnerId);
|
||||
var pj = cj.ProcessJobList.Find(x => x.InnerId == wafer.ProcessJob.InnerId);
|
||||
if (pj == null)
|
||||
{
|
||||
return false;
|
||||
|
@ -2907,22 +2755,21 @@ namespace SicRT.Modules
|
|||
|
||||
private SlotItem GetWaferInJobQueue()
|
||||
{
|
||||
foreach (var cj in _lstControlJobs)
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return null;
|
||||
|
||||
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
|
||||
{
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
foreach (var pjSlotWafer in pj.SlotWafers)
|
||||
{
|
||||
if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
|
||||
if (pjSlotWafer.Item1 == ModuleName.CassAL || pjSlotWafer.Item1 == ModuleName.CassAR)
|
||||
{
|
||||
foreach (var pjSlotWafer in pj.SlotWafers)
|
||||
{
|
||||
if (pjSlotWafer.Item1 == ModuleName.CassAL || pjSlotWafer.Item1 == ModuleName.CassAR)
|
||||
{
|
||||
if (GetModule(pjSlotWafer.Item1).CheckWaferNeedProcess(pjSlotWafer.Item2))
|
||||
return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
|
||||
}
|
||||
}
|
||||
if (GetModule(pjSlotWafer.Item1).CheckWaferNeedProcess(pjSlotWafer.Item2))
|
||||
return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2945,19 +2792,19 @@ namespace SicRT.Modules
|
|||
|
||||
private SlotItem GetTraySlot(int slotCount)
|
||||
{
|
||||
foreach (var cj in _lstControlJobs)
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return null;
|
||||
|
||||
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
if (SchCassBL.HasTrayAndNotExceedProcessCount(i))
|
||||
{
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
{
|
||||
if (SchCassBL.HasTrayAndNotExceedProcessCount(i))
|
||||
{
|
||||
return new SlotItem(ModuleName.CassBL, i);
|
||||
}
|
||||
}
|
||||
return new SlotItem(ModuleName.CassBL, i);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -2996,30 +2843,31 @@ namespace SicRT.Modules
|
|||
/// <returns></returns>
|
||||
private SlotItem GetEmptyBufferSlot(WaferInfo wafer)
|
||||
{
|
||||
foreach (var cj in _lstControlJobs)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
{
|
||||
string strSots = wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["SlotSelection"].ToString();
|
||||
if (strSots == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return null;
|
||||
|
||||
string[] slots = strSots.Split(',');
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
|
||||
var strSots = wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["SlotSelection"]
|
||||
.ToString();
|
||||
if (strSots == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var slots = strSots.Split(',');
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
{
|
||||
int slot = 0;
|
||||
if (Int32.TryParse(slots[i], out slot))
|
||||
{
|
||||
if (SchBuffer.NoTray(slot - 1))
|
||||
{
|
||||
int slot = 0;
|
||||
if (Int32.TryParse(slots[i], out slot))
|
||||
{
|
||||
if (SchBuffer.NoTray(slot - 1))
|
||||
{
|
||||
return new SlotItem(ModuleName.Buffer, slot - 1);
|
||||
}
|
||||
}
|
||||
return new SlotItem(ModuleName.Buffer, slot - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -3103,23 +2951,23 @@ namespace SicRT.Modules
|
|||
{
|
||||
int waferCountDiv = 0;
|
||||
int cassWaferCount = 0;
|
||||
foreach (var cj in _lstControlJobs)
|
||||
|
||||
var cj = _cjManager.ExecutingCj;
|
||||
if (cj == null)
|
||||
return 0;
|
||||
|
||||
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
|
||||
{
|
||||
foreach (var pj in _lstProcessJobs)
|
||||
cassWaferCount += pj.SlotWafers.Count;
|
||||
foreach (var pjSlotWafer in pj.SlotWafers)
|
||||
{
|
||||
if (pj.ControlJobName == cj.Name && pj.State == EnumProcessJobState.Processing)
|
||||
var module = GetModule(pjSlotWafer.Item1);
|
||||
if (module.HasWafer(pjSlotWafer.Item2) && !module.CheckWaferNeedProcess(pjSlotWafer.Item2))
|
||||
{
|
||||
cassWaferCount += pj.SlotWafers.Count;
|
||||
foreach (var pjSlotWafer in pj.SlotWafers)
|
||||
{
|
||||
var module = GetModule(pjSlotWafer.Item1);
|
||||
if (module.HasWafer(pjSlotWafer.Item2) && !module.CheckWaferNeedProcess(pjSlotWafer.Item2))
|
||||
{
|
||||
waferCountDiv++;
|
||||
}
|
||||
}
|
||||
waferCountDiv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3223,11 +3071,13 @@ namespace SicRT.Modules
|
|||
bool controlJobExecuting = false;
|
||||
bool isModuleBusy = false;
|
||||
|
||||
/*
|
||||
foreach (var controlJob in _lstControlJobs)
|
||||
{
|
||||
if (controlJob.State == EnumControlJobState.Executing)
|
||||
|
||||
controlJobExecuting = true;
|
||||
}
|
||||
} */
|
||||
|
||||
//if (!controlJobExecuting)
|
||||
// return Result.RUN;
|
||||
|
@ -3301,7 +3151,7 @@ namespace SicRT.Modules
|
|||
private bool CheckModuleHaveWaferWithNoJob(out string reason)
|
||||
{
|
||||
reason = "";
|
||||
if (_lstControlJobs.Count > 0)
|
||||
if (_cjManager.InQueueJobCount > 0)
|
||||
{
|
||||
reason = "lstControlJobs.Count > 0";
|
||||
return false;
|
||||
|
|
|
@ -21,10 +21,20 @@ namespace SicRT.Equipments.Job
|
|||
|
||||
public List<ProcessJobInfo> ProcessJobList { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 将CJ标记为已移除。
|
||||
/// <para>ConcurrentQueue不支持Remove方法,因此需要通过标记判断。</para>
|
||||
/// </summary>
|
||||
public bool IsRemoved { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void SetAsRemoved()
|
||||
{
|
||||
IsRemoved = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using Aitex.Core.Util;
|
||||
using MECF.Framework.Common.DBCore;
|
||||
using MECF.Framework.Common.Equipment;
|
||||
using MECF.Framework.Common.Jobs;
|
||||
using SicRT.Modules.Schedulers;
|
||||
|
||||
namespace SicRT.Equipments.Job
|
||||
{
|
||||
|
@ -7,6 +13,9 @@ namespace SicRT.Equipments.Job
|
|||
{
|
||||
#region Variables
|
||||
|
||||
/// <summary>
|
||||
/// ConcurrentQueue允许多个UI同时创建Job。
|
||||
/// </summary>
|
||||
private readonly ConcurrentQueue<ControlJobInfoEx> _qControlJobs;
|
||||
|
||||
#endregion
|
||||
|
@ -20,25 +29,177 @@ namespace SicRT.Equipments.Job
|
|||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// 返回列队中的CJ总数。
|
||||
/// </summary>
|
||||
public int InQueueJobCount => _qControlJobs.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 返回正在运行的ControlJob。
|
||||
/// </summary>
|
||||
public ControlJobInfoEx ExecutingCj
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_qControlJobs.TryPeek(out var cj) || cj.State != EnumControlJobState.Executing)
|
||||
return null;
|
||||
|
||||
return cj;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// 创建ControlJob
|
||||
/// </summary>
|
||||
public void CreateJob()
|
||||
public void Add(ControlJobInfoEx cj)
|
||||
{
|
||||
|
||||
if (TryFindByName(cj.Name, out _))
|
||||
throw new Exception($"{cj.Name} has been added.");
|
||||
|
||||
_qControlJobs.Enqueue(cj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除指定的Job。
|
||||
/// </summary>
|
||||
/// <param name="jobUid"></param>
|
||||
public void DeleteJob(string jobUid)
|
||||
/// <param name="name"></param>
|
||||
public void DeleteJob(string name)
|
||||
{
|
||||
|
||||
if(!TryFindByName(name, out var cj))
|
||||
throw new Exception($"unable to find cj with name {cj.Name}.");
|
||||
|
||||
cj.SetState(EnumControlJobState.Completed);
|
||||
cj.SetAsRemoved();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动CJ。
|
||||
/// </summary>
|
||||
public void StartJob(Action<ControlJobInfoEx> doBeforeStart = null)
|
||||
{
|
||||
if (!_qControlJobs.TryPeek(out var cj))
|
||||
throw new Exception($"unable to peek the current cj.");
|
||||
|
||||
if (cj.State == EnumControlJobState.WaitingForStart)
|
||||
{
|
||||
// 启动CJ前执行指定的程序。
|
||||
doBeforeStart?.Invoke(cj);
|
||||
cj.SetState(EnumControlJobState.Executing);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CJ完成,从列队中移除。
|
||||
/// </summary>
|
||||
public void FinishJob()
|
||||
{
|
||||
if (!_qControlJobs.TryPeek(out var cj))
|
||||
throw new Exception($"unable to peek the current cj.");
|
||||
|
||||
if (cj.State == EnumControlJobState.Completed)
|
||||
{
|
||||
if (!_qControlJobs.TryDequeue(out _))
|
||||
throw new Exception("Unable to dequeue the first cj in queue.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 暂停CJ。
|
||||
/// </summary>
|
||||
public void PauseJob()
|
||||
{
|
||||
if (!_qControlJobs.TryPeek(out var cj))
|
||||
throw new Exception($"unable to peek the current cj.");
|
||||
|
||||
if (cj.State == EnumControlJobState.Executing)
|
||||
cj.SetState(EnumControlJobState.Paused);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 恢复运行暂停的CJ。
|
||||
/// </summary>
|
||||
public void ResumeJob()
|
||||
{
|
||||
if (!_qControlJobs.TryPeek(out var cj))
|
||||
throw new Exception($"unable to peek the current cj.");
|
||||
|
||||
if (cj.State == EnumControlJobState.Paused)
|
||||
cj.SetState(EnumControlJobState.Executing);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 停止所有CJ.
|
||||
/// </summary>
|
||||
public void StopAllJob()
|
||||
{
|
||||
foreach (var cj in _qControlJobs)
|
||||
{
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
{
|
||||
pj.SetState(EnumProcessJobState.Stopping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终止当前正在运行的CJ。
|
||||
/// </summary>
|
||||
public void AbortJob(out ControlJobInfoEx cjAborted)
|
||||
{
|
||||
if(!_qControlJobs.TryDequeue(out var cj))
|
||||
throw new Exception($"unable to dequeue the current cj.");
|
||||
|
||||
foreach (var pj in cj.ProcessJobList)
|
||||
pj.SetState(EnumProcessJobState.Aborting);
|
||||
|
||||
cjAborted = cj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有的CJ。
|
||||
/// </summary>
|
||||
public void ClearAll()
|
||||
{
|
||||
while (_qControlJobs.TryDequeue(out _))
|
||||
{
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查当前运行的Cj是否已经执行完毕。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool CheckCjDone()
|
||||
{
|
||||
var cj = ExecutingCj;
|
||||
if (cj == null)
|
||||
return false;
|
||||
|
||||
return !cj.ProcessJobList.Any(x =>
|
||||
x.State != EnumProcessJobState.Complete && x.State != EnumProcessJobState.ProcessingComplete);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过名称查找CJ。
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="cj"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryFindByName(string name, out ControlJobInfoEx cj)
|
||||
{
|
||||
cj = _qControlJobs.FirstOrDefault(x => x.Name == name);
|
||||
return cj != null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -856,7 +856,7 @@ namespace SicRT.Equipments.Systems
|
|||
|
||||
private bool FsmAbortJob(object[] param)
|
||||
{
|
||||
_auto.AbortJob((string)param[0]);
|
||||
_auto.AbortJob();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -868,19 +868,19 @@ namespace SicRT.Equipments.Systems
|
|||
|
||||
private bool FsmResumeJob(object[] param)
|
||||
{
|
||||
_auto.ResumeJob((string)param[0]);
|
||||
_auto.ResumeJob();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool FsmPauseJob(object[] param)
|
||||
{
|
||||
_auto.PauseJob((string)param[0]);
|
||||
_auto.PauseJob();
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool FsmStartJob(object[] param)
|
||||
{
|
||||
_auto.StartJob((string)param[0]);
|
||||
_auto.StartJob();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.4.6")]
|
||||
[assembly: AssemblyVersion("1.0.4.7")]
|
||||
//[assembly: AssemblyFileVersion("1.0.3.3")]
|
||||
|
|
Loading…
Reference in New Issue