using Aitex.Common.Util; using Aitex.Core.Common; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.Util; using DocumentFormat.OpenXml.Wordprocessing; using MECF.Framework.Common.CommonData.Rinse; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.ToolLayout; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; namespace MECF.Framework.Common.WaferHolder { public class WaferHolderManager : Singleton { #region 常量 private const string EventWaferHolderLeft = "WAFER_HOLDER_LEFT_POSITION"; private const string EventWaferHolderArrive = "WAFER_HOLDER_ARRIVE_POSITION"; private const string EventWaferHolderCreated = "WAFER_HOLDER_CREATED"; private const string EventWaferHolderRemoved = "WAFER_HOLDER_REMOVED"; private const string EventWaferHolderDeleted = "WAFER_HOLDER_DELETED"; private const string WaferShuttleUsageFileName = "WaferShuttleUsage.log"; private const char CVS_SPLIT_CHAR = ' '; #endregion #region 内部变量 /// /// 服务 /// private WaferHolderDataService _service; /// /// Start Flag /// private bool _isStarted = false; #endregion /// /// 模块载具字典(key-Location,value-WaferHolder对象) /// ConcurrentDictionary _locationWaferHolders = new ConcurrentDictionary(); /// (key-WaferHolder Id,value-WaferHolder对象) /// 载具字典 /// ConcurrentDictionary _waferHolderDic = new ConcurrentDictionary(); /// /// 初始化 /// public void Initialize() { EV.Subscribe(new EventItem("Event", EventWaferHolderLeft, "Wafer Holder Left Event")); EV.Subscribe(new EventItem("Event", EventWaferHolderArrive, "Wafer Holder Arrived Event")); EV.Subscribe(new EventItem("Event", EventWaferHolderCreated, "Wafer Holder Creates Event")); EV.Subscribe(new EventItem("Event", EventWaferHolderRemoved, "Wafer Holder Removed Event")); EV.Subscribe(new EventItem("Event", EventWaferHolderDeleted, "Wafer Holder Deleted Event")); OP.Subscribe("WaferHolder.TransferWaferHolder", (cmd, args) => { string fromModuleName = args[0] as string; string toModuleName = args[1] as string; TransferWaferHolder(fromModuleName, fromModuleName, toModuleName); return true; }); LoadDatas(); } /// /// 重置LayoutWafers /// /// /// public bool ResetLayoutWafers() { List waferHolderInfos = _locationWaferHolders.Values.ToList(); foreach(WaferHolderInfo item in waferHolderInfos) { bool isChanged = false; if(!Enum.TryParse(item.CurrentLocation,out ModuleName moduleName)) { continue; } if (!string.IsNullOrEmpty(item.WaferAId)) { if (item.WaferAType == (int)WaferType.Production) { WaferManager.Instance.DeleteWaferById(item.WaferAId); item.WaferAId = $"{item.Id}.01"; item.WaferAType= (int)WaferType.Assit; CreateModuleWafer(item, moduleName, 0,item.WaferAId); isChanged = true; } else { if(item.WaferAId!= $"{item.Id}.01") { item.WaferAId = $"{item.Id}.01"; isChanged = true; } CreateModuleWafer(item, moduleName, 0,item.WaferAId); } } else { item.WaferAId = $"{item.Id}.01"; item.WaferAType = (int)WaferType.Assit; CreateModuleWafer(item, moduleName, 0,item.WaferAId); isChanged = true; } if (!string.IsNullOrEmpty(item.WaferBId)) { if (item.WaferBType == (int)WaferType.Production) { WaferManager.Instance.DeleteWaferById(item.WaferBId); item.WaferBId = $"{item.Id}.02"; item.WaferBType = (int)WaferType.Assit; CreateModuleWafer(item, moduleName, 1, item.WaferBId); isChanged = true; } else { if (item.WaferBId != $"{item.Id}.02") { item.WaferBId = $"{item.Id}.02"; isChanged = true; } CreateModuleWafer(item, moduleName, 1,item.WaferBId); } } else { item.WaferBId = $"{item.Id}.02"; item.WaferBType = (int)WaferType.Assit; isChanged = true; CreateModuleWafer(item, moduleName,1,item.WaferBId); } if (isChanged) { WaferHolderDataRecorder.UpdateWaferHolderData(item.Id, item); } MaterialTrackerManager.Instance.UpdateModuleMaterial(item.CurrentLocation); } return true; } /// /// 创建Module Wafer /// /// /// /// private void CreateModuleWafer(WaferHolderInfo item,ModuleName moduleName,int slot,string waferId) { if (!WaferManager.Instance.CheckHasWafer(moduleName, slot)) { WaferManager.Instance.CreateWafer(moduleName, slot, WaferStatus.Normal, (WaferSize)item.WaferSize, WaferType.Assit); WaferInfo waferInfo = WaferManager.Instance.GetWafer(moduleName, slot); waferInfo.WaferOrigin = waferId; waferInfo.WaferID = waferId; waferInfo.OrginalWaferHolder = item.Id; } } /// /// 加载数据 /// private void LoadDatas() { _service = new WaferHolderDataService(); List waferHolderInfos= _service.GetAllWaferHolderDatas(); if(waferHolderInfos!=null&&waferHolderInfos.Count!=0) { foreach(WaferHolderInfo info in waferHolderInfos) { _locationWaferHolders[info.CurrentLocation] = info; _waferHolderDic[info.Id] = info; CellItemManager.Instance.UpdateCellWaferHolder(info.CurrentLocation, true); } } List installedModules = ToolLayoutConfigManager.Instance.InstalledModules; foreach (string item in installedModules) { if (Enum.TryParse(item, out ModuleName moduleName)) { DeleteHasNoWaferHolderWafers(moduleName); } } DeleteHasNoWaferHolderWafers(ModuleName.Transporter1); DeleteHasNoWaferHolderWafers(ModuleName.Transporter2); DeleteHasNoWaferHolderWafers(ModuleName.Loader1); } /// /// 删除不存在WaferHolder但存在Wafer /// /// private void DeleteHasNoWaferHolderWafers(ModuleName moduleName) { string str = moduleName == ModuleName.Loader1 ? "Loader" : moduleName.ToString(); if (!_locationWaferHolders.ContainsKey(str)) { if (WaferManager.Instance.CheckHasWafer(moduleName, 0)) { WaferManager.Instance.DeleteWafer(moduleName.ToString(), 0); } if (WaferManager.Instance.CheckHasWafer(moduleName, 1)) { WaferManager.Instance.DeleteWafer(moduleName.ToString(), 1); } } } /// /// 是否为WaferHolder单元 /// /// /// private bool IsWaferHolderCell(ModuleName moduleName) { return ModuleHelper.IsMetal(moduleName) || ModuleHelper.IsDry(moduleName) || ModuleHelper.IsRinse(moduleName) || ModuleHelper.IsPrewet(moduleName) || moduleName == ModuleName.Loader1 || moduleName == ModuleName.Transporter1 || moduleName == ModuleName.Transporter2; } /// /// 根据Id获取载具对象 /// /// /// public WaferHolderInfo GetWaferHolderInfoById(string id) { return _waferHolderDic.ContainsKey(id) ? _waferHolderDic[id] : null; } /// /// 创建WaferHolder /// /// public void CreateWaferHolder(WaferHolderInfo info) { _waferHolderDic[info.Id] = info; } /// /// 由各个模块自己定义注册可以放置几个载盒 /// /// 模块名称 /// 有几个位置可以放 public void SubscribeLocation(string module,WaferHolderInfo waferHolder) { _locationWaferHolders[module] = waferHolder; _waferHolderDic[waferHolder.Id] = waferHolder; EV.Notify(EventWaferHolderArrive, new SerializableDictionary() { {"WaferHolderID",waferHolder.Id }, {"LocationID",waferHolder.CurrentLocation } }); WaferHolderHistoryRecord.InsertWaferHolderArriveHistory(waferHolder.Id, waferHolder.CurrentLocation); CellItemManager.Instance.UpdateCellWaferHolder(waferHolder.CurrentLocation, true); MaterialTrackerManager.Instance.UpdateModuleMaterial(module); } /// /// 转移WaferHolder /// /// /// /// public bool TransferWaferHolder(string moduleName,string fromModule,string toModule) { if (!HasWaferHolder(fromModule)) { LOG.WriteLog(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System", $"Invalid wafer move, no wafer at source, {fromModule}=>{toModule}"); return false; } ModuleName fromModuleName = ModuleName.Unknown; if (fromModule == "Loader") { fromModuleName = ModuleName.Loader1; } else { fromModuleName = (ModuleName)Enum.Parse(typeof(ModuleName), fromModule); } ModuleName toModuleName = ModuleName.Unknown; if (toModule == "Loader") { toModuleName = ModuleName.Loader1; } else { toModuleName= (ModuleName)Enum.Parse(typeof(ModuleName), toModule); } if (HasWaferHolder(toModule)) { LOG.WriteLog(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System",$"Invalid wafer move, destination has wafer, {fromModule}=>{toModule}"); return false; } if (_locationWaferHolders.TryRemove(fromModule, out var info)) { EV.Notify(EventWaferHolderLeft, new SerializableDictionary() { {"WaferHolderID",info.Id }, {"LocationID",fromModule } }); CellItemManager.Instance.UpdateCellWaferHolder(fromModule, false); MaterialTrackerManager.Instance.UpdateModuleMaterial(fromModuleName.ToString()); WaferHolderHistoryRecord.InsertWaferHolderLeftHistory(info.Id, fromModule); info.CurrentLocation = toModule; SubscribeLocation(toModule, info); if (WaferManager.Instance.CheckHasWafer(fromModuleName, 0)) { WaferManager.Instance.WaferMoved(fromModuleName, 0, toModuleName, 0); } if (WaferManager.Instance.CheckHasWafer(fromModuleName, 1)) { WaferManager.Instance.WaferMoved(fromModuleName, 1, toModuleName, 1); } LOG.WriteLog(eEvent.INFO_TRANSPORTER, "System", $"Wafer Shuttle {info.Id} transfer from {fromModule} to {toModule}"); WaferHolderDataRecorder.UpdateWaferHolderData(info.Id, info); return true; } else { return false; } } /// /// 是否存在WaferHolder /// /// /// public bool HasWaferHolder(string moduleName) { return _locationWaferHolders.ContainsKey(moduleName); } /// /// 获取WaferHolder /// /// /// public WaferHolderInfo GetWaferHolder(string moduleName) { if (moduleName == ModuleName.Loader1.ToString()) { moduleName = "Loader"; } return _locationWaferHolders.ContainsKey(moduleName) ? _locationWaferHolders[moduleName]: null; } /// /// 禁用WaferHolder /// /// public void DisableWaferHolder(WaferHolderInfo info) { info.Enabled = false; WaferHolderDataRecorder.UpdateWaferHolderEnable(info.Id,false); } /// /// 移除 /// /// public void Remove(string moduleName) { if(_locationWaferHolders.ContainsKey(moduleName)) { _locationWaferHolders.TryRemove(moduleName, out var info); if (!string.IsNullOrEmpty(info.WaferAId)) { WaferManager.Instance.DeleteWaferById(info.WaferAId); } if (!string.IsNullOrEmpty(info.WaferBId)) { WaferManager.Instance.DeleteWaferById(info.WaferBId); } MaterialTrackerManager.Instance.UpdateModuleMaterial(moduleName); CellItemManager.Instance.UpdateCellWaferHolder(moduleName, false); EV.Notify(EventWaferHolderRemoved, new SerializableDictionary() { {"WaferHolderID",info.Id }, {"LocationID",moduleName } }); } } /// /// 删除 /// /// public void RemoveByWaferHolderId(string waferId) { _waferHolderDic.TryRemove(waferId, out var info); if (info!=null) { _locationWaferHolders.TryRemove(info.CurrentLocation, out var info1); WaferHolderHistoryRecord.InsertWaferHolderDeleteHistory(info.Id); EV.Notify(EventWaferHolderDeleted, new SerializableDictionary() { {"WaferHolderID",info.Id } }); } } /// /// 更换WaferHolder Id /// /// /// /// public void SwitchWaferHolderId(WaferHolderInfo waferHolderInfo,string transporterName,string newId) { if (waferHolderInfo.Id == newId) { return; } if(!Enum.TryParse(transporterName,out ModuleName moduleName)) { return; } _locationWaferHolders.TryRemove(waferHolderInfo.CurrentLocation, out var info); _waferHolderDic.TryRemove(waferHolderInfo.Id, out var tmp); string preId = waferHolderInfo.Id; waferHolderInfo.Id = newId; if (!string.IsNullOrEmpty(waferHolderInfo.WaferAId)&&waferHolderInfo.WaferAType==(int)WaferType.Assit) { WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferAId); int waferAOriginalStation = (int)ModuleName.Unknown; if (waferAInfo!=null) { waferAOriginalStation = waferAInfo.OriginStation; } WaferManager.Instance.DeleteWaferById(waferHolderInfo.WaferAId); waferHolderInfo.WaferAId = $"{newId}.01"; WaferManager.Instance.CreateWafer(moduleName, 0, WaferStatus.Normal, (WaferSize)waferHolderInfo.WaferSize, (WaferType)waferHolderInfo.WaferAType); WaferInfo waferInfo = WaferManager.Instance.GetWafer(moduleName, 0); waferInfo.WaferOrigin = waferHolderInfo.WaferAId; waferInfo.WaferID = waferHolderInfo.WaferAId; waferInfo.OriginStation = waferAOriginalStation; } if (!string.IsNullOrEmpty(waferHolderInfo.WaferBId) && waferHolderInfo.WaferBType == (int)WaferType.Assit) { WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferBId); int waferBOriginalStation = (int)ModuleName.Unknown; if (waferBInfo != null) { waferBOriginalStation = waferBInfo.OriginStation; } WaferManager.Instance.DeleteWaferById(waferHolderInfo.WaferBId); waferHolderInfo.WaferBId = $"{newId}.02"; WaferManager.Instance.CreateWafer(moduleName, 1, WaferStatus.Normal, (WaferSize)waferHolderInfo.WaferSize, (WaferType)waferHolderInfo.WaferBType); WaferInfo waferInfo = WaferManager.Instance.GetWafer(moduleName, 1); waferInfo.WaferOrigin = waferHolderInfo.WaferBId; waferInfo.WaferID = waferHolderInfo.WaferBId; waferInfo.OriginStation = waferBOriginalStation; } _locationWaferHolders[waferHolderInfo.CurrentLocation] = waferHolderInfo; _waferHolderDic[waferHolderInfo.Id] = waferHolderInfo; WaferHolderDataRecorder.UpdateWaferHolderData(preId, waferHolderInfo); MaterialTrackerManager.Instance.UpdateModuleMaterial(transporterName); } /// /// 启动时检验Wafer缓存 /// /// public bool CheckStartUpWaferHolderBuffer(ref string reason) { bool result = true; List waferHolderInfos = _waferHolderDic.Values.ToList(); foreach (WaferHolderInfo waferHolderInfo in waferHolderInfos) { if (!string.IsNullOrEmpty(waferHolderInfo.WaferAId)) { WaferInfo wafer = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferAId); if (wafer == null || wafer.IsEmpty) { reason = $"{waferHolderInfo.Id} side A has no Wafer"; LOG.Write(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System", reason); return false; } if (wafer!=null&&wafer.WaferType==WaferType.Production) { reason = $"{waferHolderInfo.Id} side A Wafer cache error"; LOG.Write(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System", reason); result = false; } } else { reason = $"{waferHolderInfo.Id} side A has no Wafer"; LOG.Write(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System", reason); return false; } if (!string.IsNullOrEmpty(waferHolderInfo.WaferBId)) { WaferInfo wafer = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferBId); if (wafer == null||wafer.IsEmpty) { reason = $"{waferHolderInfo.Id} side B has no Wafer"; LOG.Write(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System",reason); return false; } if (wafer != null && wafer.WaferType == WaferType.Production) { reason = $"{waferHolderInfo.Id} side B Wafer cache error"; LOG.Write(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System", reason); result = false; } } else { reason = $"{waferHolderInfo.Id} side B has no Wafer"; LOG.Write(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "System",reason); return false; } } return result; } /// /// 获取所有WaferHolder数据 /// /// public List GetAllWaferHolders() { return _waferHolderDic.Values.ToList(); } /// /// 更新WaferHolder信息 /// /// public void UpdateWaferHolderInfo(WaferHolderInfo waferHolderInfo) { WaferHolderInfo sourceInfo = GetWaferHolderInfoById(waferHolderInfo.Id); sourceInfo.CloneBaseInfo(waferHolderInfo); _service.UpdateWaferHolderData(waferHolderInfo.Id, sourceInfo,false); } /// /// 更新WaferHolder信息 /// /// /// /// public void UpdateWaferHolderInfo(string wsID, WaferInfo waferInfo, int slot) { WaferHolderInfo wsInfo = GetWaferHolderInfoById(wsID); if (wsInfo == null || waferInfo == null) return; if (slot == 0) { wsInfo.WaferAId = waferInfo.WaferID; wsInfo.WaferAType = (int)waferInfo.WaferType; } else { wsInfo.WaferBId = waferInfo.WaferID; wsInfo.WaferBType = (int)waferInfo.WaferType; } _service.UpdateWaferHolderData(wsInfo.Id, wsInfo, false); } /// /// 获取模块sequence /// /// /// public string GetModuleSequence(string moduleName) { if (_locationWaferHolders.ContainsKey(moduleName)) { WaferHolderInfo waferHolderInfo= _locationWaferHolders[moduleName]; if(waferHolderInfo == null) { return ""; } if (waferHolderInfo.SequenceRecipe == null) { return ""; } return waferHolderInfo.SequenceRecipe.Ppid; } return ""; } /// /// WaferShuttleUsage监控 /// public void WaferShuttleUsageMonitor() { bool isOnTime = DateTime.Now.Hour.Equals(0) && DateTime.Now.Minute.Equals(0) && DateTime.Now.Second.Equals(0); if ((!_isStarted || isOnTime) && !JudgeFileChanged()) { ExportWaferShuttleUsage(); _isStarted = true; } } /// /// WaferShuttle用量记录 /// private async void ExportWaferShuttleUsage() { await Task.Run(() => { try { List datas = GetAllWaferHolders(); if (datas == null) return; string filePath = PathManager.GetLotTrackFilePath() + WaferShuttleUsageFileName; FileInfo file = new FileInfo(filePath); if (!file.Directory.Exists) { file.Directory.Create(); } FileStream fileStream = new FileStream(file.FullName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); StreamWriter streamWriter = new StreamWriter(fileStream, System.Text.Encoding.UTF8); string str = string.Format("{0,22}", "") + CVS_SPLIT_CHAR + string.Format("{0, 4}", "#")+ CVS_SPLIT_CHAR + string.Format("{0, 12}", "WSID") + CVS_SPLIT_CHAR + CVS_SPLIT_CHAR + string.Format("{0, 12}", "IsEnabled")+ CVS_SPLIT_CHAR + string.Format("{0, 12}", "LSType") + CVS_SPLIT_CHAR + string.Format("{0, 12}", "TotalUses") + CVS_SPLIT_CHAR + string.Format("{0, 12}", "LSAID") + CVS_SPLIT_CHAR + string.Format("{0, 16}", "LSATotalUses") + CVS_SPLIT_CHAR + string.Format("{0, 12}", "LSBID") + CVS_SPLIT_CHAR + string.Format("{0, 16}", "LSBTotalUses") + CVS_SPLIT_CHAR + string.Format("{0, 12}", "Chemistry"); streamWriter.WriteLine(str); for (int i = 0; i < 16; i++) { WaferHolderInfo data = datas.Find(O => O.BufferId == i + 1); if (data != null) { string tmp = $"{string.Format("{0,22}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))}{CVS_SPLIT_CHAR}{string.Format("{0, 4}", data.BufferId)}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", data.Id)}" + $"{CVS_SPLIT_CHAR}{string.Format("{0, 13}", data.Enabled.ToString())}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", data.CrsType)}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", data.TotalUses)}" + $"{CVS_SPLIT_CHAR}{string.Format("{0, 12}", data.CrsAId)}{CVS_SPLIT_CHAR}{string.Format("{0, 16}", data.CrsATotalUses)}" + $"{CVS_SPLIT_CHAR}{string.Format("{0, 12}", data.CrsBId)}{CVS_SPLIT_CHAR}{string.Format("{0, 16}", data.CrsBTotalUses)}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", data.Chemistry)}"; streamWriter.WriteLine(tmp); } else { string tmp = $"{string.Format("{0,22}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))}{CVS_SPLIT_CHAR}{string.Format("{0, 4}", (i+1).ToString())}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", "")}" + $"{CVS_SPLIT_CHAR}{string.Format("{0, 13}", "")}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", "")}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", "")}" + $"{CVS_SPLIT_CHAR}{string.Format("{0, 12}", "")}{CVS_SPLIT_CHAR}{string.Format("{0, 16}", "")}" + $"{CVS_SPLIT_CHAR}{string.Format("{0, 12}", "")}{CVS_SPLIT_CHAR}{string.Format("{0, 16}", "")}{CVS_SPLIT_CHAR}{string.Format("{0, 12}", "")}"; streamWriter.WriteLine(tmp); } } streamWriter.WriteLine(""); streamWriter.Close(); fileStream.Close(); } catch (Exception ex) { LOG.WriteLog(eEvent.ERR_WAFER_HOLDER_MANAGER_FAILED, "WaferShuttle", $"Wafer Shuttle Usage file writing is failed!"); } }); } /// /// 文件更改判断 /// /// private bool JudgeFileChanged() { string filePath = PathManager.GetLotTrackFilePath() + WaferShuttleUsageFileName; if (!File.Exists(filePath)) { //未创建文件 return false; } FileInfo file = new FileInfo(filePath); if (file.LastWriteTime.Year.Equals(DateTime.Now.Year) && file.LastWriteTime.Month.Equals(DateTime.Now.Month) && file.LastWriteTime.Day.Equals(DateTime.Now.Day)) { //当日已修改 return true; } else { //当日未修改 return false; } } } }