Sic.Framework-Nanjing-Baishi/MECF.Framework.Common/MECF/Framework/Common/SubstrateTrackings/WaferManager.cs

1726 lines
63 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Aitex.Core.Common;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using FabConnect.SecsGemInterface.Common;
using MECF.Framework.Common.DBCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Utilities;
namespace MECF.Framework.Common.SubstrateTrackings
{
public class WaferManager : Singleton<WaferManager>, ISerializable
{
#region Constant Def
private const string EventWaferLeft = "WAFER_LEFT_POSITION";
private const string EventWaferArrive = "WAFER_ARRIVE_POSITION";
private const string Event_STS_AtSourcs = "STS_ATSOURCE";
private const string Event_STS_AtWork = "STS_ATWORK";
private const string Event_STS_AtDestination = "STS_ATDESTINATION";
private const string Event_STS_Deleted = "STS_DELETED";
private const string Event_STS_NeedProcessing = "STS_NEEDPROCESSING";
private const string Event_STS_InProcessing = "STS_INPROCESSING";
private const string Event_STS_Processed = "STS_PROCESSED";
private const string Event_STS_Aborted = "STS_ABORTED";
private const string Event_STS_Stopped = "STS_STOPPED";
private const string Event_STS_Rejected = "STS_REJECTED";
private const string Event_STS_Lost = "STS_LOST";
private const string Event_STS_Skipped = "STS_SKIPPED";
private const string Event_STS_Nostate = "STS_NOSTATE";
public const string LotID = "LotID";
public const string SubstDestination = "SubstDestination";
public const string SubstHistory = "SubstHistory";
public const string SubstID = "SubstID";
public const string SubstLocID = "SubstLocID";
public const string SubstLocState = "SubstLocState";
public const string SubstProcState = "SubstProcState";
public const string PrvSubstProcState = "PrvSubstProcState";
public const string SubstSource = "SubstSource";
public const string SubstState = "SubstState";
public const string PrvSubstState = "PrvSubstState";
public const string SubstType = "SubstType";
public const string SubstUsage = "SubstUsage";
public const string SubstMtrlStatus = "SubstMtrlStatus";
public const string SubstSourceSlot = "SourceSlot";
public const string SubstSourceCarrierID = "SourceCarrier";
public const string SubstCurrentSlot = "Slot";
#endregion
#region Variables
private readonly object _lockerWaferList = new();
private readonly Dictionary<string, WaferInfoRt> _dictWaferInfo;
private PeriodicJob _thread;
private bool _needSerialize;
#endregion
#region Constructors
public WaferManager()
{
OnlyWaferModule = new List<ModuleName>();
OnlyTrayModule = new List<ModuleName>();
WaferTrayModule = new List<ModuleName>();
_dictWaferInfo = new Dictionary<string, WaferInfoRt>();
AllLocationWafers = new SerializableDictionary<ModuleName, Dictionary<int, WaferInfoRt>>();
}
#endregion
#region Properties
public List<ModuleName> OnlyWaferModule { get; }
public List<ModuleName> OnlyTrayModule { get; }
public List<ModuleName> WaferTrayModule { get; }
public Dictionary<ModuleName, Dictionary<int, WaferInfoRt>> AllLocationWafers { get; private set; }
#endregion
#region Methods
public bool Serialize()
{
if (!_needSerialize)
{
return true;
}
_needSerialize = false;
try
{
if (AllLocationWafers != null)
{
BinarySerializer<Dictionary<ModuleName, Dictionary<int, WaferInfoRt>>>.ToStream(AllLocationWafers, "WaferManager");
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
return true;
}
public void Deserialize()
{
try
{
var dictionary = BinarySerializer<Dictionary<ModuleName, Dictionary<int, WaferInfoRt>>>.FromStream("WaferManager");
if (dictionary == null)
{
return;
}
2023-08-11 14:26:37 +08:00
2023-04-13 11:51:03 +08:00
AllLocationWafers = dictionary;
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
public void Initialize()
{
EV.Subscribe(new EventItem("Event", "WAFER_LEFT_POSITION", "Wafer Left"));
EV.Subscribe(new EventItem("Event", "WAFER_ARRIVE_POSITION", "Wafer Arrived"));
EV.Subscribe(new EventItem("Event", "STS_ATSOURCE", "Substrate transport state is AT_SOURCE."));
EV.Subscribe(new EventItem("Event", "STS_ATWORK", "Substrate transport state is AT_WORK."));
EV.Subscribe(new EventItem("Event", "STS_ATDESTINATION", "Substrate transport state is AT_DESTINATION."));
EV.Subscribe(new EventItem("Event", "STS_DELETED", "Substrate transport state is DELETED."));
EV.Subscribe(new EventItem("Event", "STS_NEEDPROCESSING", "Substrate process state is NEEDPROCESSING."));
EV.Subscribe(new EventItem("Event", "STS_INPROCESSING", "Substrate process state is INPROCESSING."));
EV.Subscribe(new EventItem("Event", "STS_PROCESSED", "Substrate process state is PROCESSED."));
EV.Subscribe(new EventItem("Event", "STS_ABORTED", "Substrate process state is ABORTED."));
EV.Subscribe(new EventItem("Event", "STS_STOPPED", "Substrate process state is STOPPED."));
EV.Subscribe(new EventItem("Event", "STS_REJECTED", "Substrate process state is REJECTED."));
EV.Subscribe(new EventItem("Event", "STS_LOST", "Substrate process state is LOST."));
EV.Subscribe(new EventItem("Event", "STS_SKIPPED", "Substrate process state is SKIPPED."));
EV.Subscribe(new EventItem("Event", "STS_NOSTATE", "Substrate process state is NOSTATE."));
Deserialize();
_thread = new PeriodicJob(1000, Serialize, "SerializeMonitorHandler", isStartNow: true);
}
public void SubscribeLocation(string module, int slotNumber, bool withWafer = true, bool withTray = true)
{
if (Enum.TryParse<ModuleName>(module, out var result))
{
if (withWafer && !withTray && !OnlyWaferModule.Contains(result))
{
OnlyWaferModule.Add(result);
}
2023-08-11 14:26:37 +08:00
else if (!withWafer && withTray && !OnlyTrayModule.Contains(result))
2023-04-13 11:51:03 +08:00
{
OnlyTrayModule.Add(result);
}
else if (withWafer && withTray && !WaferTrayModule.Contains(result))
{
WaferTrayModule.Add(result);
}
2023-08-11 14:26:37 +08:00
2023-04-13 11:51:03 +08:00
SubscribeLocation(result, slotNumber);
}
else
{
LOG.Write($"Failed SubscribeLocation, module name invalid, {module} ");
}
}
public void SubscribeLocation(ModuleName module, int slotNumber)
{
if (!AllLocationWafers.ContainsKey(module))
{
AllLocationWafers[module] = new Dictionary<int, WaferInfoRt>();
for (var i = 0; i < slotNumber; i++)
{
AllLocationWafers[module][i] = new WaferInfoRt();
}
}
2023-08-11 14:26:37 +08:00
2023-04-13 11:51:03 +08:00
DATA.Subscribe(module.ToString(), "ModuleWaferList", () => AllLocationWafers[module].Values.ToArray());
}
public void WaferMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
{
UpdateWaferHistory(moduleFrom, slotFrom, SubstAccessType.Left);
2023-08-10 14:20:55 +08:00
if (AllLocationWafers[moduleFrom][slotFrom].IsWaferEmpty && AllLocationWafers[moduleFrom][slotFrom].TrayState == TrayStatus.Empty)
2023-04-13 11:51:03 +08:00
{
LOG.Write($"Invalid wafer move, no wafer at source, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
2023-08-10 14:20:55 +08:00
if (!AllLocationWafers[moduleFrom][slotFrom].IsWaferEmpty && !AllLocationWafers[moduleTo][slotTo].IsWaferEmpty)
2023-04-13 11:51:03 +08:00
{
LOG.Write($"Invalid wafer move, destination has wafer, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
if (AllLocationWafers[moduleFrom][slotFrom].TrayState != 0 && AllLocationWafers[moduleTo][slotTo].TrayState != 0)
{
LOG.Write($"Invalid tray move, destination has tray, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
var trayState = AllLocationWafers[moduleFrom][slotFrom].TrayState;
var trayUsedForWhichPM = AllLocationWafers[moduleFrom][slotFrom].TrayUsedForWhichPM;
var trayOriginStation = AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation;
var trayOriginSlot = AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot;
var trayProcessCount = AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount;
var trayState2 = AllLocationWafers[moduleTo][slotTo].TrayState;
var trayUsedForWhichPM2 = AllLocationWafers[moduleTo][slotTo].TrayUsedForWhichPM;
var trayOriginStation2 = AllLocationWafers[moduleTo][slotTo].TrayOriginStation;
var trayOriginSlot2 = AllLocationWafers[moduleTo][slotTo].TrayOriginSlot;
var trayProcessCount2 = AllLocationWafers[moduleTo][slotTo].TrayProcessCount;
var waferOrigin = AllLocationWafers[moduleFrom][slotFrom].WaferOrigin;
2023-08-10 14:20:55 +08:00
var InnerIdForm= AllLocationWafers[moduleFrom][slotFrom].WaferInnerID;
var InnerIdTo = AllLocationWafers[moduleTo][slotTo].WaferInnerID;
var TrayBelongTo_Form = AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo;
var TrayBelongTo_To = AllLocationWafers[moduleTo][slotTo].TrayBelongTo;
2023-05-22 18:32:18 +08:00
var waferInfo = CopyWaferInfo(moduleTo, slotTo, AllLocationWafers[moduleFrom][slotFrom]);
2023-04-13 11:51:03 +08:00
UpdateWaferHistory(moduleTo, slotTo, SubstAccessType.Arrive);
DeleteWaferForMove(moduleFrom, slotFrom);
if (OnlyWaferModule.Contains(moduleTo) && WaferTrayModule.Contains(moduleFrom))//wafer回来
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleTo][slotTo].TrayState = TrayStatus.Empty;
2023-04-13 11:51:03 +08:00
AllLocationWafers[moduleTo][slotTo].TrayUsedForWhichPM = 0;
AllLocationWafers[moduleTo][slotTo].TrayOriginStation = 0;
AllLocationWafers[moduleTo][slotTo].TrayOriginSlot = 0;
AllLocationWafers[moduleTo][slotTo].TrayProcessCount = 0;
2023-05-22 18:32:18 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayState = trayState;
2023-04-13 11:51:03 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayUsedForWhichPM = trayUsedForWhichPM;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation = trayOriginStation;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot = trayOriginSlot;
AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount = trayProcessCount;
//新加的两个参数
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleFrom][slotFrom].WaferInnerID = InnerIdForm;
AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo = TrayBelongTo_Form;
AllLocationWafers[moduleTo][slotTo].TrayBelongTo = "";
}
else if (OnlyWaferModule.Contains(moduleFrom) && WaferTrayModule.Contains(moduleTo))//wafer出去
2023-04-13 11:51:03 +08:00
{
AllLocationWafers[moduleTo][slotTo].TrayState = trayState2;
AllLocationWafers[moduleTo][slotTo].TrayUsedForWhichPM = trayUsedForWhichPM2;
AllLocationWafers[moduleTo][slotTo].TrayOriginStation = trayOriginStation2;
AllLocationWafers[moduleTo][slotTo].TrayOriginSlot = trayOriginSlot2;
AllLocationWafers[moduleTo][slotTo].TrayProcessCount = trayProcessCount2;
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayState = TrayStatus.Empty;
2023-04-13 11:51:03 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayUsedForWhichPM = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount = 0;
//新加的两个参数
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleTo][slotTo].WaferInnerID = InnerIdTo;//目的地的信息被清了,重新赋值
AllLocationWafers[moduleTo][slotTo].TrayBelongTo = TrayBelongTo_To;
AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo = "";
}
2023-04-13 11:51:03 +08:00
else
{
AllLocationWafers[moduleTo][slotTo].TrayState = trayState;
AllLocationWafers[moduleTo][slotTo].TrayUsedForWhichPM = trayUsedForWhichPM;
AllLocationWafers[moduleTo][slotTo].TrayOriginStation = trayOriginStation;
AllLocationWafers[moduleTo][slotTo].TrayOriginSlot = trayOriginSlot;
AllLocationWafers[moduleTo][slotTo].TrayProcessCount = trayProcessCount;
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayState = TrayStatus.Empty;
2023-04-13 11:51:03 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayUsedForWhichPM = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount = 0;
//新加的两个参数
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleTo][slotTo].WaferInnerID = InnerIdForm;
AllLocationWafers[moduleTo][slotTo].TrayBelongTo = TrayBelongTo_Form;
AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo = "";
}
2023-04-13 11:51:03 +08:00
EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferMoved, waferOrigin, moduleFrom.ToString(), slotFrom + 1, moduleTo.ToString(), slotTo + 1);
2023-08-10 14:20:55 +08:00
WaferMoveHistoryRecorder.WaferMoved(waferInfo.WaferInnerID.ToString(), moduleTo.ToString(), slotTo, waferInfo.WaferStatus.ToString());
2023-04-13 11:51:03 +08:00
EV.Notify("WAFER_LEFT_POSITION", new SerializableDictionary<string, string>
{
{
"SLOT_NO",
(slotFrom + 1).ToString("D2")
},
{ "WAFER_ID", waferInfo.WaferID },
{ "LOT_ID", waferInfo.LotId },
{
"CAR_ID",
GetCarrierID(moduleFrom)
},
{
"LEFT_POS_NAME",
string.Format("{0}.{1}", moduleFrom, (slotFrom + 1).ToString("D2"))
}
});
if (ModuleHelper.IsLoadPort(moduleFrom))
{
UpdateWaferTransportState(waferInfo.WaferID, SubstrateTransportStatus.AtWork);
UpdateWaferE90State(waferInfo.WaferID, EnumE90Status.InProcess);
}
EV.Notify("WAFER_ARRIVE_POSITION", new SerializableDictionary<string, string>
{
{
"SLOT_NO",
(slotTo + 1).ToString("D2")
},
{ "WAFER_ID", waferInfo.WaferID },
{ "LOT_ID", waferInfo.LotId },
{
"CAR_ID",
GetCarrierID(moduleTo)
},
{
"ARRIVE_POS_NAME",
string.Format("{0}.{1}", moduleTo, (slotTo + 1).ToString("D2"))
}
});
if (ModuleHelper.IsLoadPort(moduleTo))
{
if (waferInfo.SubstE90Status == EnumE90Status.InProcess)
{
UpdateWaferE90State(waferInfo.WaferID, EnumE90Status.Processed);
}
2023-08-10 14:20:55 +08:00
if (moduleTo == (ModuleName)waferInfo.WaferOriginStation && waferInfo.SubstE90Status != EnumE90Status.Processed)
2023-04-13 11:51:03 +08:00
{
UpdateWaferTransportState(waferInfo.WaferID, SubstrateTransportStatus.AtSource);
}
else
{
UpdateWaferTransportState(waferInfo.WaferID, SubstrateTransportStatus.AtDestination);
}
}
LOG.Write($"WaferMoved From {moduleFrom} to {moduleTo} [{AllLocationWafers[moduleFrom][slotFrom].TrayState}_{AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation}_{AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot}_{AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount}]-->[{AllLocationWafers[moduleTo][slotTo].TrayState}_{AllLocationWafers[moduleTo][slotTo].TrayOriginStation}_{AllLocationWafers[moduleTo][slotTo].TrayOriginSlot}_{AllLocationWafers[moduleTo][slotTo].TrayProcessCount}]");
_needSerialize = true;
}
public void TrayMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
{
var trayState = AllLocationWafers[moduleFrom][slotFrom].TrayState;
UpdateWaferHistory(moduleFrom, slotFrom, SubstAccessType.Left);
2023-08-10 14:20:55 +08:00
if (AllLocationWafers[moduleFrom][slotFrom].TrayState == TrayStatus.Empty)
2023-04-13 11:51:03 +08:00
{
LOG.Write($"Invalid wafer move, no wafer at tray, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
if (AllLocationWafers[moduleTo][slotTo].TrayState != 0)
{
LOG.Write($"Invalid wafer move, destination has tray, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[moduleTo][slotTo].TrayState = trayState;
AllLocationWafers[moduleTo][slotTo].TrayUsedForWhichPM = AllLocationWafers[moduleFrom][slotFrom].TrayUsedForWhichPM;
AllLocationWafers[moduleTo][slotTo].TrayOriginStation = AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation;
AllLocationWafers[moduleTo][slotTo].TrayOriginSlot = AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot;
AllLocationWafers[moduleTo][slotTo].TrayProcessCount = AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount;
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleTo][slotTo].WaferInnerID = AllLocationWafers[moduleFrom][slotFrom].WaferInnerID;
AllLocationWafers[moduleTo][slotTo].TrayBelongTo = AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo;
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayState = TrayStatus.Empty;
2023-04-13 11:51:03 +08:00
AllLocationWafers[moduleFrom][slotFrom].TrayUsedForWhichPM = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot = 0;
AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount = 0;
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleFrom][slotFrom].WaferInnerID =Guid.Empty;
AllLocationWafers[moduleFrom][slotFrom].TrayBelongTo = "";
if (OnlyTrayModule.Contains(moduleTo))
2023-04-13 11:51:03 +08:00
{
AllLocationWafers[moduleTo][slotTo].WaferOrigin = $"{ModuleHelper.GetAbbr((ModuleName)AllLocationWafers[moduleTo][slotTo].TrayOriginStation)}.{AllLocationWafers[moduleTo][slotTo].TrayOriginSlot + 1:D2}";
2023-08-10 14:20:55 +08:00
AllLocationWafers[moduleTo][slotTo].WaferOriginSlot = AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot;
2023-04-13 11:51:03 +08:00
}
}
_needSerialize = true;
LOG.Write($"TrayMoved From {moduleFrom} to {moduleTo} [{AllLocationWafers[moduleFrom][slotFrom].TrayState}_{AllLocationWafers[moduleFrom][slotFrom].TrayOriginStation}_{AllLocationWafers[moduleFrom][slotFrom].TrayOriginSlot}_{AllLocationWafers[moduleFrom][slotFrom].TrayProcessCount}]-->[{AllLocationWafers[moduleTo][slotTo].TrayState}_{AllLocationWafers[moduleTo][slotTo].TrayOriginStation}_{AllLocationWafers[moduleTo][slotTo].TrayOriginSlot}_{AllLocationWafers[moduleTo][slotTo].TrayProcessCount}]");
}
public void WaferDuplicated(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo)
{
UpdateWaferHistory(moduleFrom, slotFrom, SubstAccessType.Left);
2023-08-10 14:20:55 +08:00
if (AllLocationWafers[moduleFrom][slotFrom].IsWaferEmpty)
2023-04-13 11:51:03 +08:00
{
LOG.Write($"Invalid wafer move, no wafer at source, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
2023-08-10 14:20:55 +08:00
if (!AllLocationWafers[moduleTo][slotTo].IsWaferEmpty)
2023-04-13 11:51:03 +08:00
{
LOG.Write($"Invalid wafer move, destination has wafer, {moduleFrom}{slotFrom + 1}=>{moduleTo}{slotTo + 1}");
return;
}
var waferOrigin = AllLocationWafers[moduleFrom][slotFrom].WaferOrigin;
var waferInfo = CopyWaferInfo(moduleTo, slotTo, AllLocationWafers[moduleFrom][slotFrom]);
UpdateWaferHistory(moduleTo, slotTo, SubstAccessType.Arrive);
EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferMoved, waferOrigin, moduleFrom.ToString(), slotFrom + 1, moduleTo.ToString(), slotTo + 1);
2023-08-10 14:20:55 +08:00
WaferMoveHistoryRecorder.WaferMoved(waferInfo.WaferInnerID.ToString(), moduleTo.ToString(), slotTo, waferInfo.WaferStatus.ToString());
2023-04-13 11:51:03 +08:00
EV.Notify("WAFER_LEFT_POSITION", new SerializableDictionary<string, string>
{
{
"SLOT_NO",
(slotFrom + 1).ToString("D2")
},
{
"Slot",
(slotFrom + 1).ToString("D2")
},
{ "WAFER_ID", waferInfo.WaferID },
{ "SubstID", waferInfo.WaferID },
{ "LOT_ID", waferInfo.LotId },
{ "LotID", waferInfo.LotId },
{
"CAR_ID",
GetCarrierID(moduleFrom)
},
{
"CarrierID",
GetCarrierID(moduleFrom)
},
{
"LEFT_POS_NAME",
string.Format("{0}.{1}", moduleFrom, (slotFrom + 1).ToString("D2"))
}
});
if (ModuleHelper.IsLoadPort(moduleFrom))
{
UpdateWaferTransportState(waferInfo.WaferID, SubstrateTransportStatus.AtWork);
UpdateWaferE90State(waferInfo.WaferID, EnumE90Status.InProcess);
}
EV.Notify("WAFER_ARRIVE_POSITION", new SerializableDictionary<string, string>
{
{
"SLOT_NO",
(slotTo + 1).ToString("D2")
},
{ "WAFER_ID", waferInfo.WaferID },
{ "SubstID", waferInfo.WaferID },
{ "LOT_ID", waferInfo.LotId },
{ "LotID", waferInfo.LotId },
{
"CAR_ID",
GetCarrierID(moduleTo)
},
{
"CarrierID",
GetCarrierID(moduleTo)
},
{
"ARRIVE_POS_NAME",
string.Format("{0}.{1}", moduleTo, (slotTo + 1).ToString("D2"))
}
});
if (ModuleHelper.IsLoadPort(moduleTo))
{
if (waferInfo.SubstE90Status == EnumE90Status.InProcess)
{
UpdateWaferE90State(waferInfo.WaferID, EnumE90Status.Processed);
}
2023-08-10 14:20:55 +08:00
if (moduleTo == (ModuleName)waferInfo.WaferOriginStation && waferInfo.SubstE90Status != EnumE90Status.Processed)
2023-04-13 11:51:03 +08:00
{
UpdateWaferTransportState(waferInfo.WaferID, SubstrateTransportStatus.AtSource);
}
else
{
UpdateWaferTransportState(waferInfo.WaferID, SubstrateTransportStatus.AtDestination);
}
}
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(moduleFrom, slotFrom, WaferProcessStatus.Failed);
UpdateWaferProcessStatus(moduleTo, slotTo, WaferProcessStatus.Failed);
2023-04-13 11:51:03 +08:00
_needSerialize = true;
}
private string GetCarrierID(ModuleName module)
{
if (!ModuleHelper.IsLoadPort(module))
{
return "";
}
return DATA.Poll(module.ToString() + ".CarrierId").ToString();
}
public bool IsWaferSlotLocationValid(ModuleName module, int slot)
{
return AllLocationWafers.ContainsKey(module) && AllLocationWafers[module].ContainsKey(slot);
}
public WaferInfoRt[] GetWafers(ModuleName module)
{
if (!AllLocationWafers.ContainsKey(module))
{
return null;
}
return AllLocationWafers[module].Values.ToArray();
}
public WaferInfoRt[] GetWaferByProcessJob(string jobName)
{
var list = new List<WaferInfoRt>();
foreach (var locationWafer in AllLocationWafers)
{
foreach (var item in locationWafer.Value)
{
2023-08-10 14:20:55 +08:00
if (item.Value != null && !item.Value.IsWaferEmpty && item.Value.ProcessJob != null && item.Value.ProcessJob.Name == jobName)
2023-04-13 11:51:03 +08:00
{
list.Add(item.Value);
}
}
}
return list.ToArray();
}
2023-04-13 11:51:03 +08:00
public WaferInfoRt[] GetWafer(string waferID)
{
var list = new List<WaferInfoRt>();
foreach (var locationWafer in AllLocationWafers)
{
foreach (var item in locationWafer.Value)
{
if (item.Value.WaferID == waferID)
{
list.Add(item.Value);
}
}
}
return list.ToArray();
}
public WaferInfoRt GetWafer(ModuleName module, int slot)
{
if (!AllLocationWafers.ContainsKey(module))
{
return null;
}
if (!AllLocationWafers[module].ContainsKey(slot))
{
return null;
}
return AllLocationWafers[module][slot];
}
public WaferInfoRt[] GetWafers(string Originalcarrier, int Originalslot)
{
var list = new List<WaferInfoRt>();
foreach (var locationWafer in AllLocationWafers)
{
foreach (var item in locationWafer.Value)
{
2023-08-10 14:20:55 +08:00
if (item.Value.OriginCarrierID == Originalcarrier && item.Value.WaferOriginSlot == Originalslot)
2023-04-13 11:51:03 +08:00
{
list.Add(item.Value);
}
}
}
return list.ToArray();
}
public string GetWaferID(ModuleName module, int slot)
{
return IsWaferSlotLocationValid(module, slot) ? AllLocationWafers[module][slot].WaferID : "";
}
public WaferSize GetWaferSize(ModuleName module, int slot)
{
return IsWaferSlotLocationValid(module, slot) ? AllLocationWafers[module][slot].Size : WaferSize.WS0;
}
public bool CheckNoWafer(ModuleName module, int slot)
{
2023-08-10 14:20:55 +08:00
return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].IsWaferEmpty;
2023-04-13 11:51:03 +08:00
}
public bool CheckNoWafer(string module, int slot)
{
return CheckNoWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot);
}
public bool CheckHasWafer(ModuleName module, int slot)
{
2023-08-10 14:20:55 +08:00
return IsWaferSlotLocationValid(module, slot) && !AllLocationWafers[module][slot].IsWaferEmpty;
2023-04-13 11:51:03 +08:00
}
public bool CheckWaferIsDummy(ModuleName module, int slot)
{
2023-08-10 14:20:55 +08:00
return IsWaferSlotLocationValid(module, slot) && !AllLocationWafers[module][slot].IsWaferEmpty && AllLocationWafers[module][slot].WaferStatus == WaferStatus.Dummy;
2023-04-13 11:51:03 +08:00
}
public bool CheckHasWafer(string module, int slot)
{
return CheckHasWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot);
}
public bool CheckNoTray(ModuleName module, int slot)
{
2023-08-10 14:20:55 +08:00
return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].TrayState == TrayStatus.Empty;
2023-04-13 11:51:03 +08:00
}
public bool CheckHasTray(ModuleName module, int slot)
{
2023-08-10 14:20:55 +08:00
return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].TrayState != TrayStatus.Empty;
2023-04-13 11:51:03 +08:00
}
public bool CheckWaferFull(ModuleName module)
{
var dictionary = AllLocationWafers[module];
foreach (var item in dictionary)
{
2023-08-10 14:20:55 +08:00
if (item.Value.IsWaferEmpty)
2023-04-13 11:51:03 +08:00
{
return false;
}
}
return true;
}
public bool CheckWaferEmpty(ModuleName module)
{
var dictionary = AllLocationWafers[module];
foreach (var item in dictionary)
{
2023-08-10 14:20:55 +08:00
if (!item.Value.IsWaferEmpty)
2023-04-13 11:51:03 +08:00
{
return false;
}
}
return true;
}
public bool CheckWafer(ModuleName module, int slot, WaferStatus state)
{
2023-08-10 14:20:55 +08:00
return IsWaferSlotLocationValid(module, slot) && AllLocationWafers[module][slot].WaferStatus == state;
2023-04-13 11:51:03 +08:00
}
public WaferInfoRt CreateWafer(ModuleName module, int slot, WaferStatus state)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Invalid wafer create, invalid parameter, {module}, {slot + 1}");
return null;
}
var carrierGuid = "";
var text = string.Empty;
if (ModuleHelper.IsLoadPort(module) || ModuleHelper.IsCassette(module))
{
var carrier = Singleton<CarrierManager>.Instance.GetCarrier(module.ToString());
if (carrier == null)
{
EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, $"No carrier at {module}, can not create wafer");
return null;
}
carrierGuid = carrier.InnerId.ToString();
text = carrier.CarrierId;
}
lock (_lockerWaferList)
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferStatus = state;
AllLocationWafers[module][slot].ProcessState = WaferProcessStatus.Idle;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].SubstE90Status = EnumE90Status.NeedProcessing;
AllLocationWafers[module][slot].WaferID = GenerateWaferId(module, slot, text);
AllLocationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot);
AllLocationWafers[module][slot].Station = (int)module;
AllLocationWafers[module][slot].Slot = slot;
//AllLocationWafers[module][slot].InnerId = Guid.NewGuid();
AllLocationWafers[module][slot].TrayBelongTo = "System";
AllLocationWafers[module][slot].TrayUsedForWhichPM = 0;
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferOriginStation = (int)module;
AllLocationWafers[module][slot].WaferOriginSlot = slot;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].OriginCarrierID = text;
AllLocationWafers[module][slot].LotId = "";
AllLocationWafers[module][slot].HostLaserMark1 = "";
AllLocationWafers[module][slot].HostLaserMark2 = "";
AllLocationWafers[module][slot].LaserMarker = "";
AllLocationWafers[module][slot].T7Code = "";
AllLocationWafers[module][slot].PPID = "";
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].TrayState = TrayStatus.Normal;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].TrayOriginStation = (int)module;
AllLocationWafers[module][slot].TrayOriginSlot = slot;
AllLocationWafers[module][slot].TrayProcessCount = (SC.ContainsItem("System.DefaultTrayProcessCount") ? SC.GetValue<int>("System.DefaultTrayProcessCount") : 10);
2023-08-10 14:20:55 +08:00
if (AllLocationWafers[module][slot].WaferInnerID == Guid.Empty)//创建时可能有Tray防位置GUID被覆盖
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();
}
if (OnlyTrayModule.Contains(module))
2023-04-13 11:51:03 +08:00
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferStatus = WaferStatus.Empty;
}
2023-04-13 11:51:03 +08:00
else if (OnlyWaferModule.Contains(module))
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();//单独出现Wafer地方必须创建,这里是EFEM版本
AllLocationWafers[module][slot].TrayState = TrayStatus.Empty;
}
2023-04-13 11:51:03 +08:00
var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, SubstAccessType.Create);
AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
_dictWaferInfo[AllLocationWafers[module][slot].WaferID] = AllLocationWafers[module][slot];
}
UpdateWaferE90State(AllLocationWafers[module][slot].WaferID, EnumE90Status.NeedProcessing);
UpdateWaferTransportState(AllLocationWafers[module][slot].WaferID, SubstrateTransportStatus.AtSource);
2023-08-10 14:20:55 +08:00
WaferDataRecorder.CreateWafer(AllLocationWafers[module][slot].WaferInnerID.ToString(), carrierGuid, module.ToString(), slot, AllLocationWafers[module][slot].WaferID, AllLocationWafers[module][slot].ProcessState.ToString());
2023-04-13 11:51:03 +08:00
_needSerialize = true;
return AllLocationWafers[module][slot];
}
public WaferInfoRt CreateWafer(ModuleName module, int slot, WaferStatus state, WaferSize wz)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Invalid wafer create, invalid parameter, {module}, {slot + 1}");
return null;
}
var carrierGuid = "";
var text = string.Empty;
if (ModuleHelper.IsLoadPort(module) || ModuleHelper.IsCassette(module))
{
var carrier = Singleton<CarrierManager>.Instance.GetCarrier(module.ToString());
if (carrier == null)
{
EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, $"No carrier at {module}, can not create wafer");
return null;
}
carrierGuid = carrier.InnerId.ToString();
text = carrier.CarrierId;
}
lock (_lockerWaferList)
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferStatus = state;
AllLocationWafers[module][slot].ProcessState = WaferProcessStatus.Idle;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].SubstE90Status = EnumE90Status.NeedProcessing;
AllLocationWafers[module][slot].WaferID = GenerateWaferId(module, slot, text);
AllLocationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot);
AllLocationWafers[module][slot].Station = (int)module;
AllLocationWafers[module][slot].Slot = slot;
//AllLocationWafers[module][slot].InnerId = Guid.NewGuid();
AllLocationWafers[module][slot].TrayBelongTo = "System";
AllLocationWafers[module][slot].TrayUsedForWhichPM = 0;
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferOriginStation = (int)module;
AllLocationWafers[module][slot].WaferOriginSlot = slot;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].OriginCarrierID = text;
AllLocationWafers[module][slot].LotId = "";
AllLocationWafers[module][slot].HostLaserMark1 = "";
AllLocationWafers[module][slot].HostLaserMark2 = "";
AllLocationWafers[module][slot].LaserMarker = "";
AllLocationWafers[module][slot].T7Code = "";
AllLocationWafers[module][slot].PPID = "";
AllLocationWafers[module][slot].Size = wz;
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].TrayState = TrayStatus.Normal;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].TrayOriginStation = (int)module;
AllLocationWafers[module][slot].TrayOriginSlot = slot;
AllLocationWafers[module][slot].TrayProcessCount = (SC.ContainsItem("System.DefaultTrayProcessCount") ? SC.GetValue<int>("System.DefaultTrayProcessCount") : 10);
2023-08-10 14:20:55 +08:00
if (AllLocationWafers[module][slot].WaferInnerID == Guid.Empty)//创建时可能有Tray防位置GUID被覆盖
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();
}
if (OnlyTrayModule.Contains(module))
2023-04-13 11:51:03 +08:00
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferStatus = WaferStatus.Empty;
}
2023-04-13 11:51:03 +08:00
else if (OnlyWaferModule.Contains(module))
{
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].TrayState = TrayStatus.Empty;
AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();//单独出现Wafer地方必须创建,这里是EFEM版本
}
var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, SubstAccessType.Create);
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
_dictWaferInfo[AllLocationWafers[module][slot].WaferID] = AllLocationWafers[module][slot];
}
UpdateWaferE90State(AllLocationWafers[module][slot].WaferID, EnumE90Status.NeedProcessing);
UpdateWaferTransportState(AllLocationWafers[module][slot].WaferID, SubstrateTransportStatus.AtSource);
2023-08-10 14:20:55 +08:00
WaferDataRecorder.CreateWafer(AllLocationWafers[module][slot].WaferInnerID.ToString(), carrierGuid, module.ToString(), slot, AllLocationWafers[module][slot].WaferID, AllLocationWafers[module][slot].ProcessState.ToString());
2023-04-13 11:51:03 +08:00
_needSerialize = true;
return AllLocationWafers[module][slot];
}
2023-08-10 14:20:55 +08:00
public WaferInfoRt CreateTray(ModuleName module, int slot, TrayStatus trayStatu = TrayStatus.Normal)
2023-04-13 11:51:03 +08:00
{
if (OnlyWaferModule.Contains(module))
{
return null;
}
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Invalid wafer create, invalid parameter, {module}, {slot + 1}");
return null;
}
var carrierGuid = "";
var text = string.Empty;
if (ModuleHelper.IsLoadPort(module) || ModuleHelper.IsCassette(module))
{
var carrier = Singleton<CarrierManager>.Instance.GetCarrier(module.ToString());
if (carrier == null)
{
EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, $"No carrier at {module}, can not create wafer");
return null;
}
carrierGuid = carrier.InnerId.ToString();
text = carrier.CarrierId;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].TrayBelongTo = "System";
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferStatus = WaferStatus.Empty;
AllLocationWafers[module][slot].ProcessState = WaferProcessStatus.Idle;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].SubstE90Status = EnumE90Status.NeedProcessing;
AllLocationWafers[module][slot].WaferID = GenerateWaferId(module, slot, text);
AllLocationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot);
AllLocationWafers[module][slot].Station = (int)module;
AllLocationWafers[module][slot].Slot = slot;
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferInnerID = Guid.NewGuid();
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].TrayUsedForWhichPM = 0;
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][slot].WaferOriginStation = (int)module;
AllLocationWafers[module][slot].WaferOriginSlot = slot;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][slot].OriginCarrierID = text;
AllLocationWafers[module][slot].LotId = "";
AllLocationWafers[module][slot].HostLaserMark1 = "";
AllLocationWafers[module][slot].HostLaserMark2 = "";
AllLocationWafers[module][slot].LaserMarker = "";
AllLocationWafers[module][slot].T7Code = "";
AllLocationWafers[module][slot].PPID = "";
AllLocationWafers[module][slot].TrayState = trayStatu;
AllLocationWafers[module][slot].TrayOriginStation = (int)module;
AllLocationWafers[module][slot].TrayOriginSlot = slot;
AllLocationWafers[module][slot].TrayProcessCount = (SC.ContainsItem("System.DefaultTrayProcessCount") ? SC.GetValue<int>("System.DefaultTrayProcessCount") : 10);
var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, SubstAccessType.Create);
AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
_dictWaferInfo[AllLocationWafers[module][slot].WaferID] = AllLocationWafers[module][slot];
}
UpdateWaferE90State(AllLocationWafers[module][slot].WaferID, EnumE90Status.NeedProcessing);
UpdateWaferTransportState(AllLocationWafers[module][slot].WaferID, SubstrateTransportStatus.AtSource);
2023-08-10 14:20:55 +08:00
WaferDataRecorder.CreateWafer(AllLocationWafers[module][slot].WaferInnerID.ToString(), carrierGuid, module.ToString(), slot, AllLocationWafers[module][slot].WaferID, AllLocationWafers[module][slot].ProcessState.ToString());
2023-04-13 11:51:03 +08:00
_needSerialize = true;
return AllLocationWafers[module][slot];
}
2023-08-11 14:26:37 +08:00
public void DeleteWafer(ModuleName module, int slotFrom, int count = 1)
2023-04-13 11:51:03 +08:00
{
lock (_lockerWaferList)
{
for (var i = 0; i < count; i++)
{
var num = slotFrom + i;
if (!IsWaferSlotLocationValid(module, num))
{
LOG.Write($"Invalid wafer delete, invalid parameter, {module}, {num + 1}");
continue;
}
2023-08-10 14:20:55 +08:00
UpdateWaferTrayStatus(module, num, TrayStatus.Empty);
2023-04-13 11:51:03 +08:00
UpdateWaferE90State(AllLocationWafers[module][num].WaferID, EnumE90Status.None);
UpdateWaferTransportState(AllLocationWafers[module][num].WaferID, SubstrateTransportStatus.None);
2023-08-10 14:20:55 +08:00
WaferDataRecorder.DeleteWafer(AllLocationWafers[module][num].WaferInnerID.ToString());
AllLocationWafers[module][num].SetWaferTrayEmpty();
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][num].SubstHists = null;
_dictWaferInfo.Remove(AllLocationWafers[module][num].WaferID);
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][num].WaferInnerID = Guid.Empty;
AllLocationWafers[module][num].TrayBelongTo = "";
}
2023-04-13 11:51:03 +08:00
}
_needSerialize = true;
}
public void DeleteWaferOnly(ModuleName module, int slotFrom, int count = 1)
{
lock (_lockerWaferList)
{
for (var i = 0; i < count; i++)
{
var num = slotFrom + i;
if (!IsWaferSlotLocationValid(module, num))
{
LOG.Write($"Invalid wafer delete, invalid parameter, {module}, {num + 1}");
continue;
}
if (OnlyTrayModule.Contains(module))
{
return;
}
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][num].WaferStatus = WaferStatus.Empty;
AllLocationWafers[module][num].ProcessState = WaferProcessStatus.Idle;
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][num].ProcessJobID = "";
AllLocationWafers[module][num].ProcessJob = null;
}
}
_needSerialize = true;
}
public void DeleteWaferForMove(ModuleName module, int slotFrom, int count = 1)
{
lock (_lockerWaferList)
{
for (var i = 0; i < count; i++)
{
var num = slotFrom + i;
if (!IsWaferSlotLocationValid(module, num))
{
LOG.Write($"Invalid wafer delete, invalid parameter, {module}, {num + 1}");
continue;
}
2023-08-10 14:20:55 +08:00
AllLocationWafers[module][num].SetWaferTrayEmpty();
2023-04-13 11:51:03 +08:00
AllLocationWafers[module][num].SubstHists = null;
_dictWaferInfo.Remove(AllLocationWafers[module][num].WaferID);
}
}
_needSerialize = true;
}
2023-08-10 14:20:55 +08:00
public void UpdateWaferProcessStatus(ModuleName module, int slot, WaferProcessStatus status)
2023-04-13 11:51:03 +08:00
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferProcessStatus, invalid parameter, {module}, {slot + 1}");
return;
}
2023-08-11 14:26:37 +08:00
2023-04-13 11:51:03 +08:00
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].ProcessState = status;
2023-08-10 14:20:55 +08:00
WaferDataRecorder.SetWaferStatus(AllLocationWafers[module][slot].WaferInnerID.ToString(), status.ToString());
2023-04-13 11:51:03 +08:00
}
_needSerialize = true;
}
public void UpdateWaferProcessStatus(ModuleName module, int slot, ProcessStatus status)
{
switch (status)
{
case ProcessStatus.Busy:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(module, slot, WaferProcessStatus.InProcess);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Completed:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(module, slot, WaferProcessStatus.Completed);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Failed:
case ProcessStatus.Abort:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(module, slot, WaferProcessStatus.Failed);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Idle:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(module, slot, WaferProcessStatus.Idle);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Wait:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(module, slot, WaferProcessStatus.InProcess);
2023-04-13 11:51:03 +08:00
break;
}
}
public void UpdateWaferProcessStatus(string waferID, ProcessStatus status)
{
switch (status)
{
case ProcessStatus.Busy:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(waferID, WaferProcessStatus.InProcess);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Completed:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(waferID, WaferProcessStatus.Completed);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Failed:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(waferID, WaferProcessStatus.Failed);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Idle:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(waferID, WaferProcessStatus.Idle);
2023-04-13 11:51:03 +08:00
break;
case ProcessStatus.Wait:
2023-08-10 14:20:55 +08:00
UpdateWaferProcessStatus(waferID, WaferProcessStatus.InProcess);
2023-04-13 11:51:03 +08:00
break;
}
}
public void UpdateWaferTransportState(string waferid, SubstrateTransportStatus ststate)
{
if (string.IsNullOrEmpty(waferid))
{
return;
}
var wafer = GetWafer(waferid);
lock (_lockerWaferList)
{
var array = wafer;
foreach (var waferInfo in array)
{
waferInfo.SubstTransStatus = ststate;
var dvid = new SerializableDictionary<string, object>
{
{ "SubstID", waferInfo.WaferID },
{ "LotID", waferInfo.LotId },
{
"SubstMtrlStatus",
(int)waferInfo.ProcessState
},
{
"SubstDestination",
((ModuleName)waferInfo.DestinationStation).ToString()
},
{ "SubstHistory", waferInfo.SubstHists },
{
"SubstLocID",
((ModuleName)waferInfo.Station).ToString()
},
{
"SubstProcState",
(int)waferInfo.SubstE90Status
},
{
"SubstSource",
2023-08-10 14:20:55 +08:00
((ModuleName)waferInfo.WaferOriginStation).ToString()
2023-04-13 11:51:03 +08:00
},
{
"SubstState",
(int)waferInfo.SubstTransStatus
}
};
if (ststate == SubstrateTransportStatus.AtWork)
{
EV.Notify("STS_ATWORK", dvid);
}
if (ststate == SubstrateTransportStatus.AtDestination)
{
EV.Notify("STS_ATDESTINATION", dvid);
}
if (ststate == SubstrateTransportStatus.AtSource)
{
EV.Notify("STS_ATSOURCE", dvid);
}
if (ststate == SubstrateTransportStatus.None)
{
EV.Notify("STS_DELETED", dvid);
}
}
}
_needSerialize = true;
_needSerialize = true;
}
public void UpdateWaferE90State(string waferid, EnumE90Status E90state)
{
if (string.IsNullOrEmpty(waferid))
{
return;
}
var wafer = GetWafer(waferid);
lock (_lockerWaferList)
{
var array = wafer;
foreach (var waferInfo in array)
{
if (waferInfo.SubstE90Status != E90state)
{
waferInfo.SubstE90Status = E90state;
var text = "";
if (ModuleHelper.IsLoadPort((ModuleName)waferInfo.Station))
{
text = Singleton<CarrierManager>.Instance.GetCarrier(((ModuleName)waferInfo.Station).ToString()).CarrierId;
}
var sECsDataItem = new SECsDataItem(SECsFormat.List);
sECsDataItem.Add("SourceCarrier", waferInfo.OriginCarrierID ?? "");
2023-08-10 14:20:55 +08:00
sECsDataItem.Add("SourceSlot", (waferInfo.WaferOriginSlot + 1).ToString());
2023-04-13 11:51:03 +08:00
sECsDataItem.Add("CurrentCarrier", text ?? "");
sECsDataItem.Add("CurrentSlot", (waferInfo.Slot + 1).ToString());
sECsDataItem.Add("LaserMark1", waferInfo.LaserMarker ?? "");
sECsDataItem.Add("LaserMark1Score", waferInfo.LaserMarkerScore ?? "");
sECsDataItem.Add("LaserMark2", waferInfo.T7Code ?? "");
sECsDataItem.Add("LaserMark2Score", waferInfo.T7CodeScore ?? "");
var dvid = new SerializableDictionary<string, object>
{
{ "SubstID", waferInfo.WaferID },
{ "LotID", waferInfo.LotId },
{
"SubstMtrlStatus",
(int)waferInfo.ProcessState
},
{
"SubstDestination",
((ModuleName)waferInfo.DestinationStation).ToString()
},
{ "SubstHistory", waferInfo.SubstHists },
{
"SubstLocID",
((ModuleName)waferInfo.Station).ToString()
},
{
"SubstProcState",
(int)waferInfo.SubstE90Status
},
{
"SubstState",
(int)waferInfo.SubstTransStatus
},
{
"SubstSource",
2023-08-10 14:20:55 +08:00
((ModuleName)waferInfo.WaferOriginStation).ToString()
2023-04-13 11:51:03 +08:00
},
{ "SourceCarrier", waferInfo.OriginCarrierID },
{
"SourceSlot",
2023-08-10 14:20:55 +08:00
waferInfo.WaferOriginSlot + 1
2023-04-13 11:51:03 +08:00
},
{
"Slot",
waferInfo.Slot + 1
},
{
"LASERMARK",
waferInfo.LaserMarker ?? ""
},
{
"OCRScore",
waferInfo.LaserMarkerScore ?? ""
},
{
"CarrierID",
text ?? ""
},
{
"LASERMARK1",
waferInfo.LaserMarker ?? ""
},
{
"LASERMARK2",
waferInfo.T7Code ?? ""
},
{
"LASERMARK1SCORE",
waferInfo.LaserMarkerScore ?? ""
},
{
"LASERMARK2SCORE",
waferInfo.T7CodeScore ?? ""
},
{ "PortID", waferInfo.Station },
{ "PORT_ID", waferInfo.Station },
{ "SubstInfoList", sECsDataItem }
};
if (E90state == EnumE90Status.InProcess)
{
EV.Notify("STS_INPROCESSING", dvid);
}
if (E90state == EnumE90Status.NeedProcessing)
{
EV.Notify("STS_NEEDPROCESSING", dvid);
}
if (E90state == EnumE90Status.Processed)
{
EV.Notify("STS_PROCESSED", dvid);
}
if (E90state == EnumE90Status.Aborted)
{
EV.Notify("STS_ABORTED", dvid);
}
if (E90state == EnumE90Status.Lost)
{
EV.Notify("STS_LOST", dvid);
}
if (E90state == EnumE90Status.Rejected)
{
EV.Notify("STS_REJECTED", dvid);
}
if (E90state == EnumE90Status.Skipped)
{
EV.Notify("STS_SKIPPED", dvid);
}
if (E90state == EnumE90Status.Stopped)
{
EV.Notify("STS_STOPPED", dvid);
}
}
}
}
_needSerialize = true;
}
public void UpdatTrayBelongTo(ModuleName module,int slot,string trayBelongTo)
{
AllLocationWafers[module][slot].TrayBelongTo = trayBelongTo;
UpdateWaferHistory(module, slot, SubstAccessType.Left);//属性信息设置后,不发生移动属性数据不保存,所以此处执行保存属性数据功能
}
2023-04-13 11:51:03 +08:00
public void UpdateWaferHistory(ModuleName module, int slot, SubstAccessType accesstype)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferHistory, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
var substHistory = new SubstHistory(module.ToString(), slot, DateTime.Now, accesstype);
if (AllLocationWafers[module][slot].SubstHists == null)
{
AllLocationWafers[module][slot].SubstHists = new SubstHistory[1] { substHistory };
}
else
{
AllLocationWafers[module][slot].SubstHists = AllLocationWafers[module][slot].SubstHists.Concat(new SubstHistory[1] { substHistory }).ToArray();
}
}
_needSerialize = true;
}
public void UpdateWaferLotId(ModuleName module, int slot, string lotId)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferLotId, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].LotId = lotId;
2023-08-10 14:20:55 +08:00
WaferDataRecorder.SetWaferLotId(AllLocationWafers[module][slot].WaferInnerID.ToString(), lotId);
2023-04-13 11:51:03 +08:00
Singleton<CarrierManager>.Instance.UpdateCarrierLot(module.ToString(), lotId);
}
_needSerialize = true;
}
2023-08-10 14:20:55 +08:00
public void UpdateWaferProcessStatus(string waferID, WaferProcessStatus status)
2023-04-13 11:51:03 +08:00
{
var wafer = GetWafer(waferID);
lock (_lockerWaferList)
{
var array = wafer;
foreach (var waferInfo in array)
{
waferInfo.ProcessState = status;
}
}
_needSerialize = true;
}
public void UpdateWaferProcess(string waferID, string processId)
{
var wafer = GetWafer(waferID);
lock (_lockerWaferList)
{
var array = wafer;
foreach (var waferInfo in array)
{
2023-08-10 14:20:55 +08:00
WaferDataRecorder.SetProcessInfo(waferInfo.WaferInnerID.ToString(), processId);
2023-04-13 11:51:03 +08:00
}
}
_needSerialize = true;
}
public WaferInfoRt CopyWaferInfo(ModuleName module, int slot, WaferInfoRt wafer)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed CopyWaferInfo, invalid parameter, {module}, {slot + 1}");
return null;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].Update(wafer);
AllLocationWafers[module][slot].Station = (int)module;
AllLocationWafers[module][slot].Slot = slot;
}
return AllLocationWafers[module][slot];
}
public bool UpdateWaferSize(ModuleName module, int slot, WaferSize size)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferSize, invalid parameter, {module}, {slot + 1}");
return false;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].Size = size;
}
_needSerialize = true;
Serialize();
return true;
}
private string GenerateWaferId(ModuleName module, int slot, string carrierID)
{
2023-08-11 14:26:37 +08:00
var text = ((!string.IsNullOrEmpty(carrierID)) ? carrierID : (module.ToString() + DateTime.Now.ToString("yyyyMMddHHmmssff")));
2023-04-13 11:51:03 +08:00
return string.Format(text + "." + (slot + 1).ToString("00"));
}
private string GenerateOrigin(ModuleName module, int slot)
{
return $"{ModuleHelper.GetAbbr(module)}.{slot + 1:D2}";
}
2023-08-10 14:20:55 +08:00
public void UpdateWaferTrayStatus(string waferid, TrayStatus state)
2023-04-13 11:51:03 +08:00
{
if (string.IsNullOrEmpty(waferid))
{
return;
}
var wafer = GetWafer(waferid);
lock (_lockerWaferList)
{
2023-08-11 14:26:37 +08:00
foreach (var waferInfo in wafer)
2023-04-13 11:51:03 +08:00
{
if (waferInfo.TrayState != state)
{
waferInfo.TrayState = state;
}
}
}
}
2023-08-10 14:20:55 +08:00
public void UpdateWaferTrayStatus(ModuleName module, int slot, TrayStatus status)
2023-04-13 11:51:03 +08:00
{
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].TrayState = status;
2023-08-10 14:20:55 +08:00
if (status == TrayStatus.Empty)
2023-04-13 11:51:03 +08:00
{
AllLocationWafers[module][slot].TrayProcessCount = 0;
}
}
}
2023-08-11 14:26:37 +08:00
#region 使
public bool CheckWaferSize(ModuleName module, int slot, WaferSize size)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferProcessStatus, invalid parameter, {module}, {slot + 1}");
return false;
}
WaferSize size2;
lock (_lockerWaferList)
{
size2 = AllLocationWafers[module][slot].Size;
if (size2 == WaferSize.WS0)
{
AllLocationWafers[module][slot].Size = size;
}
}
if (size2 == WaferSize.WS0)
{
_needSerialize = true;
return true;
}
return size2 == size;
}
public void UpdateWaferHostLM1(ModuleName module, int slot, string lasermark1)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferHostLM1, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].HostLaserMark1 = lasermark1;
}
_needSerialize = true;
}
public void UpdateWaferHostLM2(ModuleName module, int slot, string lasermark2)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferHostLM2, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].HostLaserMark2 = lasermark2;
}
_needSerialize = true;
}
public void UpdateWaferE90State(ModuleName module, int slot, EnumE90Status E90state)
{
var wafer = GetWafer(module, slot);
if (wafer.IsWaferEmpty)
{
return;
}
lock (_lockerWaferList)
{
wafer.SubstE90Status = E90state;
var value = "";
if (ModuleHelper.IsLoadPort((ModuleName)wafer.Station))
{
value = Singleton<CarrierManager>.Instance.GetCarrier(((ModuleName)wafer.Station).ToString()).CarrierId;
}
var dvid = new SerializableDictionary<string, object>
{
{ "SubstID", wafer.WaferID },
{ "LotID", wafer.LotId },
{
"SubstMtrlStatus",
(int)wafer.ProcessState
},
{
"SubstDestination",
((ModuleName)wafer.DestinationStation).ToString()
},
{ "SubstHistory", wafer.SubstHists },
{
"SubstLocID",
((ModuleName)wafer.Station).ToString()
},
{
"SubstProcState",
(int)wafer.SubstE90Status
},
{
"SubstState",
(int)wafer.SubstTransStatus
},
{
"SubstSource",
((ModuleName)wafer.WaferOriginStation).ToString()
},
{ "SourceCarrier", wafer.OriginCarrierID },
{
"SourceSlot",
wafer.WaferOriginSlot + 1
},
{
"Slot",
wafer.Slot + 1
},
{ "LASERMARK", wafer.LaserMarker },
{ "OCRScore", wafer.LaserMarkerScore },
{ "CarrierID", value }
};
if (E90state == EnumE90Status.InProcess)
{
EV.Notify("STS_INPROCESSING", dvid);
}
if (E90state == EnumE90Status.NeedProcessing)
{
EV.Notify("STS_NEEDPROCESSING", dvid);
}
if (E90state == EnumE90Status.Processed)
{
EV.Notify("STS_PROCESSED", dvid);
}
if (E90state == EnumE90Status.Aborted)
{
EV.Notify("STS_ABORTED", dvid);
}
if (E90state == EnumE90Status.Lost)
{
EV.Notify("STS_LOST", dvid);
}
if (E90state == EnumE90Status.Rejected)
{
EV.Notify("STS_REJECTED", dvid);
}
if (E90state == EnumE90Status.Skipped)
{
EV.Notify("STS_SKIPPED", dvid);
}
if (E90state == EnumE90Status.Stopped)
{
EV.Notify("STS_STOPPED", dvid);
}
}
_needSerialize = true;
}
public void SlotMapVerifyOK(ModuleName module)
{
var wafers = GetWafers(module);
var array = wafers;
foreach (var waferInfo in array)
{
lock (_lockerWaferList)
{
if (!waferInfo.IsWaferEmpty)
{
}
}
}
_needSerialize = true;
}
public void UpdateWaferLaser(ModuleName module, int slot, string laserMarker)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferLaser, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].LaserMarker = laserMarker;
WaferDataRecorder.SetWaferMarker(AllLocationWafers[module][slot].WaferInnerID.ToString(), laserMarker);
}
_needSerialize = true;
}
public void UpdateWaferDestination(ModuleName module, int slot, string destCarrierID, int destslot)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferLaser, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].DestinationCarrierID = destCarrierID;
AllLocationWafers[module][slot].DestinationSlot = destslot;
}
_needSerialize = true;
}
public void UpdateWaferDestination(ModuleName module, int slot, ModuleName destmodule, int destslot)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferLaser, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].DestinationStation = (int)destmodule;
AllLocationWafers[module][slot].DestinationSlot = destslot;
}
_needSerialize = true;
}
public void UpdateWaferLaserWithScoreAndFileName(ModuleName module, int slot, string laserMarker, string laserMarkerScore, string fileName, string filePath)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferLaser, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].LaserMarker = laserMarker;
AllLocationWafers[module][slot].LaserMarkerScore = laserMarkerScore;
AllLocationWafers[module][slot].ImageFileName = fileName;
AllLocationWafers[module][slot].ImageFilePath = filePath;
WaferDataRecorder.SetWaferMarkerWithScoreAndFileName(AllLocationWafers[module][slot].WaferInnerID.ToString(), laserMarker, laserMarkerScore, fileName, filePath);
}
_needSerialize = true;
}
public void UpdateWaferT7Code(ModuleName module, int slot, string T7Code)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferT7Code, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].T7Code = T7Code;
WaferDataRecorder.SetWaferT7Code(AllLocationWafers[module][slot].WaferInnerID.ToString(), T7Code);
}
_needSerialize = true;
}
public void UpdataWaferPPID(ModuleName module, int slot, string PPID)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferPPID, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].PPID = PPID;
WaferDataRecorder.SetWaferSequence(AllLocationWafers[module][slot].WaferInnerID.ToString(), PPID);
}
_needSerialize = true;
}
public void UpdateWaferT7CodeWithScoreAndFileName(ModuleName module, int slot, string t7Code, string t7CodeScore, string fileName, string filePath)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferT7Code, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].T7Code = t7Code;
AllLocationWafers[module][slot].T7CodeScore = t7CodeScore;
AllLocationWafers[module][slot].ImageFileName = fileName;
AllLocationWafers[module][slot].ImageFilePath = filePath;
WaferDataRecorder.SetWaferT7CodeWithScoreAndFileName(AllLocationWafers[module][slot].WaferInnerID.ToString(), t7Code, t7CodeScore, fileName, filePath);
}
_needSerialize = true;
}
public void UpdateWaferTransFlag(ModuleName module, int slot, string flag)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferTransFlag, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].TransFlag = flag;
}
_needSerialize = true;
}
public void UpdateWaferNotch(ModuleName module, int slot, int angle)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferNotch, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].Notch = angle;
}
_needSerialize = true;
}
public void ManualDeleteWafer(ModuleName module, int slotFrom, int count = 1)
{
for (var i = 0; i < count; i++)
{
var num = slotFrom + i;
if (!IsWaferSlotLocationValid(module, num))
{
LOG.Write($"Invalid wafer delete, invalid parameter, {module}, {num + 1}");
continue;
}
UpdateWaferE90State(AllLocationWafers[module][num].WaferID, EnumE90Status.Lost);
UpdateWaferTransportState(AllLocationWafers[module][num].WaferID, SubstrateTransportStatus.None);
UpdateWaferTrayStatus(AllLocationWafers[module][num].WaferID, TrayStatus.Empty);
UpdateWaferHistory(module, slotFrom, SubstAccessType.Delete);
lock (_lockerWaferList)
{
WaferDataRecorder.DeleteWafer(AllLocationWafers[module][num].WaferInnerID.ToString());
AllLocationWafers[module][num].SetWaferTrayEmpty();
_dictWaferInfo.Remove(AllLocationWafers[module][num].WaferID);
}
}
_needSerialize = true;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
public bool CheckWaferExistFlag(string moduleNo, string[] flagStrings, out string reason)
{
var num = 0;
reason = string.Empty;
if (!Enum.TryParse<ModuleName>("LP" + moduleNo, out var result))
{
reason = "Port Number Error";
return false;
}
foreach (var text in flagStrings)
{
if (text == "1")
{
if (IsWaferSlotLocationValid(result, num) && AllLocationWafers[result][num].IsWaferEmpty)
{
reason = "Flag Mis-Match";
return false;
}
}
else if (IsWaferSlotLocationValid(result, num) && !AllLocationWafers[result][num].IsWaferEmpty)
{
reason = "Flag Mis-Match";
return false;
}
num++;
}
return true;
}
public void DelectGuid(ModuleName module, int slotFrom)
{
AllLocationWafers[module][0].WaferInnerID = Guid.Empty;
}
public void UpdateWaferJodID(ModuleName module, int slot, string pjID, string cjID)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferId, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].ProcessJobID = pjID;
AllLocationWafers[module][slot].ControlJobID = cjID;
}
_needSerialize = true;
}
public void UpdateWaferId(ModuleName module, int slot, string waferId)
{
if (!IsWaferSlotLocationValid(module, slot))
{
LOG.Write($"Failed UpdateWaferId, invalid parameter, {module}, {slot + 1}");
return;
}
lock (_lockerWaferList)
{
AllLocationWafers[module][slot].WaferID = waferId;
}
UpdateWaferHistory(module, slot, SubstAccessType.UpdateWaferID);
_needSerialize = true;
}
#endregion
2023-04-13 11:51:03 +08:00
#endregion
}
}