using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.Util; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Utilities; namespace MECF.Framework.Common.SubstrateTrackings { public class WaferManager : Singleton { Dictionary _dict = new Dictionary(); object _lockerWaferList = new object(); Dictionary> _locationWafers = new Dictionary>(); private const string EventWaferLeft = "WaferLeftPosition"; private const string EventWaferArrive = "WaferArrivePosition"; public WaferManager() { } public void Serialize() { try { if (_locationWafers != null) { BinarySerializer>>.ToStream(_locationWafers, "WaferManager"); } } catch (Exception ex) { LOG.Write(ex); } } public void Deserialize() { try { var ccc = BinarySerializer>>.FromStream("WaferManager"); if (ccc != null) { foreach (var moduleWafers in ccc) { if (ModuleHelper.IsLoadPort(moduleWafers.Key)) { foreach (var waferInfo in moduleWafers.Value) { waferInfo.Value.SetEmpty(); } } } _locationWafers = ccc; } } catch (Exception ex) { LOG.Write(ex); } } public void Initialize() { EV.Subscribe(new EventItem("Event", EventWaferLeft, "Wafer Left")); EV.Subscribe(new EventItem("Event", EventWaferArrive, "Wafer Arrived")); Deserialize(); } public void SubscribeLocation(string module, int slotNumber) { ModuleName mod; if (Enum.TryParse(module, out mod)) { SubscribeLocation(mod, slotNumber); } else { LOG.Write(string.Format("Failed SubscribeLocation, module name invalid, {0} ", module)); } } public void SubscribeLocation(ModuleName module, int slotNumber) { if (!_locationWafers.ContainsKey(module)) { _locationWafers[module] = new Dictionary(); for (int i = 0; i < slotNumber; i++) { _locationWafers[module][i] = new WaferInfo(); } } DATA.Subscribe(module.ToString(), "ModuleWaferList", () => _locationWafers[module].Values.ToArray()); } public void WaferMoved(ModuleName moduleFrom, int slotFrom, ModuleName moduleTo, int slotTo) { if (_locationWafers[moduleFrom][slotFrom].IsEmpty) { LOG.Write(string.Format("Invalid wafer move, no wafer at source, {0}{1}=>{2}{3}", moduleFrom, slotFrom+1, moduleTo, slotTo+1)); return; } if (!_locationWafers[moduleTo][slotTo].IsEmpty) { LOG.Write(string.Format("Invalid wafer move, destination has wafer, {0}{1}=>{2}{3}", moduleFrom, slotFrom + 1, moduleTo, slotTo + 1)); return; } string waferOrigin = _locationWafers[moduleFrom][slotFrom].WaferOrigin; WaferInfo wafer = CopyWaferInfo(moduleTo, slotTo, _locationWafers[moduleFrom][slotFrom]); DeleteWafer(moduleFrom, slotFrom); EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferMoved, waferOrigin, moduleFrom.ToString(), slotFrom + 1, moduleTo.ToString(), slotTo + 1); WaferMoveHistoryRecorder.WaferMoved(wafer.InnerId.ToString(), moduleTo.ToString(), slotTo, wafer.Status.ToString()); if (ModuleHelper.IsLoadPort(moduleFrom)) { EV.Notify(EventWaferLeft, new SerializableDictionary() { {"SLOT_NO", (slotFrom+1).ToString("D2")}, {"WAFER_ID", wafer.WaferID}, {"LOT_ID", wafer.LotId}, { "CAR_ID", CarrierManager.Instance.GetCarrier(moduleFrom.ToString()).CarrierId ?? ""}, { "LEFT_POS_NAME", $"{moduleFrom}.{(slotFrom+1).ToString("D2")}" }, {"PortID", (wafer.OriginStation-(int)ModuleName.LP1+1).ToString()}, {"SlotID", (wafer.OriginSlot+1).ToString()}, {"StationName", moduleFrom.ToString()}, }); } else { EV.Notify(EventWaferLeft, new SerializableDictionary() { {"PortID", (wafer.OriginStation-(int)ModuleName.LP1+1).ToString()}, {"SlotID", (wafer.OriginSlot+1).ToString()}, {"StationName", moduleFrom.ToString()}, }); } if (ModuleHelper.IsLoadPort(moduleTo)) { EV.Notify(EventWaferArrive, new SerializableDictionary() { {"SLOT_NO", (slotTo+1).ToString("D2")}, {"WAFER_ID", wafer.WaferID}, {"LOT_ID", wafer.LotId}, { "CAR_ID", CarrierManager.Instance.GetCarrier(moduleTo.ToString()).CarrierId ?? ""}, { "ARRIVE_POS_NAME", $"{moduleTo}.{(slotTo+1).ToString("D2")}" }, {"PortID", (wafer.OriginStation-(int)ModuleName.LP1+1).ToString()}, {"SlotID", (wafer.OriginSlot+1).ToString()}, {"StationName", moduleTo.ToString()}, }); } else { EV.Notify(EventWaferArrive, new SerializableDictionary() { {"PortID", (wafer.OriginStation-(int)ModuleName.LP1+1).ToString()}, {"SlotID", (wafer.OriginSlot+1).ToString()}, {"StationName", moduleTo.ToString()}, }); } Serialize(); } public bool IsWaferSlotLocationValid(ModuleName module, int slot) { return _locationWafers.ContainsKey(module) && _locationWafers[module].ContainsKey(slot); } public WaferInfo[] GetWafers(ModuleName module) { return _locationWafers[module].Values.ToArray() ; } public WaferInfo[] GetWaferByProcessJob(string jobName) { List wafers = new List(); foreach (var moduleWafer in _locationWafers) { foreach (var waferInfo in moduleWafer.Value) { if (waferInfo.Value!=null && !waferInfo.Value.IsEmpty && (waferInfo.Value.ProcessJob!=null) && waferInfo.Value.ProcessJob.Name == jobName) wafers.Add(waferInfo.Value); } } return wafers.ToArray(); } public WaferInfo[] GetWafer(string waferID) { List result = new List(); foreach (var locationWafer in _locationWafers) { foreach (var wafer in locationWafer.Value) { if (wafer.Value.WaferID == waferID) result.Add(wafer.Value); } } return result.ToArray(); } public WaferInfo GetWafer(ModuleName module, int slot) { return _locationWafers[module][slot]; } public string GetWaferID(ModuleName module, int slot) { return IsWaferSlotLocationValid(module, slot) ? _locationWafers[module][slot].WaferID: ""; } public bool CheckNoWafer(ModuleName module, int slot) { return IsWaferSlotLocationValid(module, slot) && _locationWafers[module][slot].IsEmpty; } public bool CheckNoWafer(string module, int slot) { return CheckNoWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot); } public bool CheckHasWafer(ModuleName module, int slot) { return IsWaferSlotLocationValid(module, slot) && !_locationWafers[module][slot].IsEmpty; } public bool CheckWaferIsDummy(ModuleName module, int slot) { return IsWaferSlotLocationValid(module, slot) && !_locationWafers[module][slot].IsEmpty && _locationWafers[module][slot].Status == WaferStatus.Dummy; } /// /// Verify the slot map in string[] format, if there's any mis-match it will return false. /// /// LP No /// Flag input /// public bool CheckWaferExistFlag(string moduleNo, string[] flagStrings, out string reason) { var i = 0; reason = string.Empty; if (!Enum.TryParse($"LP{moduleNo}", out ModuleName module)) { reason = "Port Number Error"; return false; } foreach (var slot in flagStrings) { if (slot == "1") { if (IsWaferSlotLocationValid(module, i) && _locationWafers[module][i].IsEmpty) { reason = "Flag Mis-Match"; return false; } } else { if (IsWaferSlotLocationValid(module, i) && !_locationWafers[module][i].IsEmpty) { reason = "Flag Mis-Match"; return false; } } i++; } return true; } public bool CheckHasWafer(string module, int slot) { return CheckHasWafer((ModuleName)Enum.Parse(typeof(ModuleName), module), slot); } public bool CheckWaferFull(ModuleName module) { var wafers = _locationWafers[module]; foreach (var waferInfo in wafers) { if (waferInfo.Value.IsEmpty) return false; } return true; } public bool CheckWaferEmpty(ModuleName module) { var wafers = _locationWafers[module]; foreach (var waferInfo in wafers) { if (!waferInfo.Value.IsEmpty) return false; } return true; } public bool CheckWafer(ModuleName module, int slot, WaferStatus state) { if (module==ModuleName.Robot && slot == 2) { return IsWaferSlotLocationValid(module, 0) && (_locationWafers[module][0].Status==state) && IsWaferSlotLocationValid(module, 1) && (_locationWafers[module][1].Status==state); } return IsWaferSlotLocationValid(module, slot) && (_locationWafers[module][slot].Status==state); } public WaferInfo CreateWafer(ModuleName module, int slot, WaferStatus state) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Invalid wafer create, invalid parameter, {0},{1}", module, slot+1)); return null; } string carrierInnerId = ""; string carrierID = string.Empty; if (ModuleHelper.IsLoadPort(module)) { CarrierInfo carrier = CarrierManager.Instance.GetCarrier(module.ToString()); if (carrier == null) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, string.Format("No carrier at {0}, can not create wafer", module)); return null; } carrierInnerId = carrier.InnerId.ToString(); carrierID = carrier.CarrierId; } lock (_lockerWaferList) { _locationWafers[module][slot].Status = state; _locationWafers[module][slot].ProcessState = EnumWaferProcessStatus.Idle; _locationWafers[module][slot].WaferID = GenerateWaferId(module, slot,""); _locationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot); _locationWafers[module][slot].Station = (int)module; _locationWafers[module][slot].Slot = slot; _locationWafers[module][slot].InnerId = Guid.NewGuid(); _locationWafers[module][slot].OriginStation = (int)module; _locationWafers[module][slot].OriginSlot = slot; _locationWafers[module][slot].OriginCarrierID = carrierID; _dict[_locationWafers[module][slot].WaferID] = _locationWafers[module][slot]; } WaferDataRecorder.CreateWafer(_locationWafers[module][slot].InnerId.ToString(), carrierInnerId, module.ToString(), slot, _locationWafers[module][slot].WaferID); Serialize(); return _locationWafers[module][slot]; } public WaferInfo CreateWafer(ModuleName module, int slot, WaferStatus state,WaferSize wz) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Invalid wafer create, invalid parameter, {0},{1}", module, slot + 1)); return null; } string carrierInnerId = ""; string carrierID = string.Empty; if (ModuleHelper.IsLoadPort(module) ) { CarrierInfo carrier = CarrierManager.Instance.GetCarrier(module.ToString()); if (carrier == null) { EV.PostWarningLog(ModuleName.System.ToString(),string.Format("No carrier at {0}, can not create wafer.", module)); return null; } carrierInnerId = carrier.InnerId.ToString(); carrierID = carrier.CarrierId; } lock (_lockerWaferList) { _locationWafers[module][slot].Status = state; _locationWafers[module][slot].ProcessState = EnumWaferProcessStatus.Idle; _locationWafers[module][slot].WaferID = GenerateWaferId(module, slot, carrierID); _locationWafers[module][slot].WaferOrigin = GenerateOrigin(module, slot); _locationWafers[module][slot].Station = (int)module; _locationWafers[module][slot].Slot = slot; _locationWafers[module][slot].InnerId = Guid.NewGuid(); _locationWafers[module][slot].OriginStation = (int)module; _locationWafers[module][slot].OriginSlot = slot; _locationWafers[module][slot].OriginCarrierID = carrierID; _locationWafers[module][slot].LotId = ""; _locationWafers[module][slot].LaserMarker = ""; _locationWafers[module][slot].T7Code = ""; _locationWafers[module][slot].Size = wz; _dict[_locationWafers[module][slot].WaferID] = _locationWafers[module][slot]; } EV.PostInfoLog("System", $"Create wafer successfully on {module} slot:{slot+1} wafersize:{wz}."); WaferDataRecorder.CreateWafer(_locationWafers[module][slot].InnerId.ToString(), carrierInnerId, module.ToString(), slot, _locationWafers[module][slot].WaferID ); Serialize(); return _locationWafers[module][slot]; } public void DeleteWafer(ModuleName module, int slotFrom, int count = 1) { lock (_lockerWaferList) { for (int i = 0; i < count; i++) { int slot = slotFrom+i; if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Invalid wafer delete, invalid parameter, {0},{1}", module, slot + 1)); continue; } WaferDataRecorder.DeleteWafer(_locationWafers[module][slot].InnerId.ToString()); _locationWafers[module][slot].SetEmpty(); _dict.Remove(_locationWafers[module][slot].WaferID); } } Serialize(); } public void UpdateWaferLaser(ModuleName module, int slot, string laserMarker) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferLaser, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].LaserMarker = laserMarker; WaferDataRecorder.SetWaferMarker(_locationWafers[module][slot].InnerId.ToString(), laserMarker); } Serialize(); } public void UpdateWaferT7Code(ModuleName module, int slot, string T7Code) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferT7Code, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].T7Code = T7Code; WaferDataRecorder.SetWaferT7Code(_locationWafers[module][slot].InnerId.ToString(), T7Code); } Serialize(); } public void UpdateWaferTransFlag(ModuleName module, int slot, string flag) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferTransFlag, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].TransFlag = flag; } Serialize(); } public void UpdateWaferNotch(ModuleName module, int slot, int angle) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferNotch, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].Notch = angle; } Serialize(); } public void UpdateWaferProcessStatus(ModuleName module, int slot, EnumWaferProcessStatus status) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferProcessStatus, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].ProcessState = status; } Serialize(); } #pragma warning disable CS0618 public void UpdateWaferProcessStatus(ModuleName module, int slot, ProcessStatus status) { switch (status) { case ProcessStatus.Busy: UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.InProcess); break; case ProcessStatus.Completed: UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.Completed); break; case ProcessStatus.Failed: UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.Failed); break; case ProcessStatus.Idle: UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.Idle); break; case ProcessStatus.Wait: UpdateWaferProcessStatus(module, slot, EnumWaferProcessStatus.InProcess); break; } } public void UpdateWaferProcessStatus(string waferID, ProcessStatus status) { switch (status) { case ProcessStatus.Busy: UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.InProcess); break; case ProcessStatus.Completed: UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.Completed); break; case ProcessStatus.Failed: UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.Failed); break; case ProcessStatus.Idle: UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.Idle); break; case ProcessStatus.Wait: UpdateWaferProcessStatus(waferID, EnumWaferProcessStatus.InProcess); break; } } #pragma warning restore CS0618 public void UpdateWaferId(ModuleName module, int slot, string waferId) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferId, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].WaferID = waferId; } Serialize(); } public void UpdateWaferLotId(ModuleName module, int slot, string lotId) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferLotId, invalid parameter, {0},{1}", module, slot + 1)); return; } lock (_lockerWaferList) { _locationWafers[module][slot].LotId = lotId; } Serialize(); } public void UpdateWaferProcessStatus(string waferID, EnumWaferProcessStatus status) { WaferInfo[] wafers = GetWafer(waferID); lock (_lockerWaferList) { foreach (var waferInfo in wafers) { waferInfo.ProcessState = status; } } Serialize(); } public void UpdateWaferProcess(string waferID, string processId) { WaferInfo[] wafers = GetWafer(waferID); lock (_lockerWaferList) { foreach (var waferInfo in wafers) { WaferDataRecorder.SetProcessInfo(waferInfo.InnerId.ToString(), processId); } } Serialize(); } public WaferInfo CopyWaferInfo(ModuleName module, int slot, WaferInfo wafer) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed CopyWaferInfo, invalid parameter, {0},{1}", module, slot + 1)); return null; } lock (_lockerWaferList) { _locationWafers[module][slot].Update(wafer); _locationWafers[module][slot].Station = (int)module; _locationWafers[module][slot].Slot = slot; } return _locationWafers[module][slot]; } public bool UpdateWaferSize(ModuleName module, int slot, WaferSize size) { if (!IsWaferSlotLocationValid(module, slot)) { LOG.Write(string.Format("Failed UpdateWaferSize, invalid parameter, {0},{1}", module, slot + 1)); return false; } lock (_lockerWaferList) { _locationWafers[module][slot].Size = size; } Serialize(); return true; } private string GenerateWaferId(ModuleName module, int slot,string carrierID) { string carrierinfor = ""; //5 + 2(unit) + 2(slot) + time(18) + index{5} if (string.IsNullOrEmpty(carrierID)) carrierinfor = module.ToString() + DateTime.Now.ToString("yyyyMMddHHmmssffff"); else carrierinfor = carrierID; return string.Format($"{carrierinfor}.{(slot+1).ToString("00")}"); } private string GenerateOrigin(ModuleName module, int slot) { return string.Format("{0}.{1:D2}", ModuleHelper.GetAbbr(module), slot + 1); } } }