using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.RT.ModuleLibrary.EfemModules; using MECF.Framework.RT.ModuleLibrary.LPModules; using SecsGem.Core.Application; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using VirgoRT.Devices.EFEM; using VirgoRT.Modules; namespace VirgoRT.Instances { public class SecsGemEquipment : IEquipmentCommand { #region 常量 private const string EventTerminalMessage = "TerminalMessage"; #endregion #region 内部变量 private Dictionary _dicPortModule = new Dictionary() { {"1", ModuleName.LP1}, {"2", ModuleName.LP2}, {"3", ModuleName.LP3} }; #endregion /// /// 初始化 /// public void Initialize() { EV.Subscribe(new EventItem("Host", EventTerminalMessage, "{0}", EventLevel.Warning, EventType.EventUI_Notify)); } public bool AbortControlJob(string controlJob) { return true; } public bool CheckAuto() { return Singleton.Instance.IsAutoMode; } public bool CheckCreateControlJobCondition(List modules, out string reason) { reason = ""; return true; } public void CreateControlJob(string controlJobId, string carrierId, List processJobs) { return; } public bool CreateProcessJob(string processJobId, string sequenceName, string carrierId, out string reason) { reason = ""; return true; } /// /// 执行指令 /// /// /// /// /// public bool ExcuteCommand(string command, object[] paras, out string reason) { reason = ""; int portID; string jobID; string lotId; object[] sequence; switch (command.ToUpper()) { case "PP-SELECT": portID = int.Parse(paras[0].ToString()); jobID = paras[1].ToString(); lotId = paras[2].ToString(); sequence = (object[])paras[3]; return PPselect(portID, jobID, lotId, sequence,out reason); case "STARTJOB": jobID = paras[0].ToString(); OP.DoOperation("System.StartJob", new object[] { jobID }); return true; case "ABORTJOB": jobID = paras[0].ToString(); OP.DoOperation("System.AbortJob", new object[] { jobID }); return true; case "PAUSEJOB": jobID = paras[0].ToString(); OP.DoOperation("System.PauseJob", new object[] { jobID }); return true; case "RESUMEJOB": jobID = paras[0].ToString(); OP.DoOperation("System.ResumeJob", new object[] { jobID }); return true; case "STOPJOB": jobID = paras[0].ToString(); OP.DoOperation("System.StopJob", new object[] { jobID }); return true; case "LOAD": portID = int.Parse(paras[0].ToString()); return Load(portID, out reason); case "UNLOAD": portID = int.Parse(paras[0].ToString()); return Unload(portID, out reason); case "LOCK": portID = int.Parse(paras[0].ToString()); return Lock(portID, out reason); case "UNLOCK": portID = int.Parse(paras[0].ToString()); return Unlock(portID, out reason); case "READID": portID = int.Parse(paras[0].ToString()); return ReadId(portID, out reason); case "WRITEID": portID = int.Parse(paras[0].ToString()); string carrierID = paras[1].ToString(); return WriteId(portID, carrierID, out reason); case "READTAG": portID = int.Parse(paras[0].ToString()); return ReadTag(portID, out reason); case "WRITETAG": portID = int.Parse(paras[0].ToString()); string tagData = paras[1].ToString(); return WriteId(portID, tagData, out reason); } return true; } #region LoadPort /// /// 创建Job /// /// /// /// /// /// /// private bool PPselect(int portID,string jobID,string lotID, object[] sequence,out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } var len = SC.GetValue($"LoadPort.SlotNumber"); if (len != sequence.Length) { reason = $"length is not match,length={len}"; return false; } string[] slotsequence = new string[len]; for (int i = 0; i < len; i++) { slotsequence[i] = sequence[i].ToString() == "*null*" ? "" : sequence[i].ToString(); } if (!Singleton.Instance.IsAutoMode) { reason = $"System not in auto mode"; return false; } Dictionary param = new Dictionary() { {"JobId", jobID}, {"LotId", lotID}, {"Module", _dicPortModule[portID.ToString()].ToString()}, {"SlotSequence", slotsequence}, {"AutoStart", false}, }; OP.DoOperation("System.CreateJob", param); reason = string.Empty; return true; } /// /// Load指令 /// /// /// /// private bool Load(int portID,out string reason) { reason = ""; if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } Loadport LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Load"); return true; } /// /// Load指令 /// /// /// /// private bool Unload(int portID, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } Loadport LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } if (SC.GetValue("EFEM.AutoUnlockAfterUnload")) { OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Unload"); } else { OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Undock"); } reason = string.Empty; return true; } /// /// Lock指令 /// /// /// /// private bool Lock(int portID, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } Loadport LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Clamp"); reason = string.Empty; return true; } /// /// Unlock指令 /// /// /// /// private bool Unlock(int portID, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } Loadport LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.Unclamp"); reason = string.Empty; return true; } /// /// Read ID /// /// /// /// private bool ReadId(int portID, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } var LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.ReadCarrierId"); reason = string.Empty; return true; } /// /// Write ID /// /// /// /// private bool WriteId(int portID,string carrierID, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } var LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.WriteCarrierID", carrierID); reason = string.Empty; return true; } /// /// Read ID /// /// /// /// private bool ReadTag(int portID, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } var LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.ReadTagData"); reason = string.Empty; return true; } /// /// Write ID /// /// /// /// private bool WriteTag(int portID, string tagData, out string reason) { if (!_dicPortModule.ContainsKey(portID.ToString())) { reason = $"{portID} not valid"; return false; } var LPDevice = Singleton.Instance.EFEM.EfemDevice[_dicPortModule[portID.ToString()]] as Loadport; if (LPDevice == null) { reason = $"{portID} not valid"; return false; } if (!LPDevice.HasCassette) { reason = $"{portID} cassette not placed"; return false; } if (LPDevice.Status == DeviceState.Error) { reason = $"{portID} port in error, need reset"; return false; } OP.DoOperation($"{_dicPortModule[portID.ToString()]}.WriteTagData", tagData); reason = string.Empty; return true; } #endregion #region recipe /// /// 删除Sequence /// /// /// public bool deleteSequence(string ppid) { LOG.Warning("system not support update sequence"); return false; //return RecipeFileManager.Instance.DeleteSequence(ppid); } /// /// S7F25 /// /// /// public List GetFormatedSequence(string ppid) { List result = new List(); string reason = string.Empty; try { string content = string.Empty; if (RecipeFileManager.Instance.CheckSequenceFileExist(ppid)) content = RecipeFileManager.Instance.GetSequence(ppid, false); if (string.IsNullOrEmpty(content)) { bool enableFolder = SC.GetValue("System.RecipeFolderByType"); if (enableFolder) { if (ppid.StartsWith("PMA") && !ppid.StartsWith("PMA\\Process") && !ppid.StartsWith("PMA\\Clean")) ppid = ppid.Replace("PMA", "PMA\\Process"); if (ppid.StartsWith("PMB") && !ppid.StartsWith("PMB\\Process") && !ppid.StartsWith("PMB\\Clean")) ppid = ppid.Replace("PMB", "PMB\\Process"); } content = RecipeFileManager.Instance.LoadRecipe("", ppid, false); } result.Add(content); } catch (Exception ex) { LOG.Write(ex); reason = ex.Message; } return result; } /// /// S7F5 获取recipe body /// /// /// /// public string GetSequenceBody(string ppid) { return RecipeFileManager.Instance.GetSequence(ppid, false); } /// /// S7F3 更新Recipe /// /// /// /// public bool UpdateSequence(string ppid, string body) { LOG.Warning("system not support update sequence"); return false; //bool ret = false; //string reason = string.Empty; //ret = RecipeFileManager.Instance.SaveSequence(ppid, body, false); //if (!ret) //{ // reason = string.Format("save recipe content failed,recipeName:{0}", ppid); // LOG.Write(reason); //} //return ret; } /// /// 获取sequence集合 S7F19 /// /// public string[] GetSequenceList() { var recipeList = RecipeFileManager.Instance.GetSequenceNameList(); return recipeList.ToArray(); } #endregion public bool PauseControlJob(string controlJob) { throw new NotImplementedException(); } public bool ResumeControlJob(string controlJob) { throw new NotImplementedException(); } public void ShowTerminalMessage(string message) { EV.Notify("Host", EventTerminalMessage, message); } public bool StartControlJob(string controlJob) { throw new NotImplementedException(); } public bool StopControlJob(string controlJob) { throw new NotImplementedException(); } public void UpdateControlJobModule(string controlJobId, string moduleName) { throw new NotImplementedException(); } public void UpdateProcessJobCarrierSlot(string processJobId, string moduleName, List slots) { throw new NotImplementedException(); } #region eap log write in RT public void WriteErrorLog(string message) { LOG.Error(message); } public void WriteInfoLog(string message) { LOG.Info(message); } public void WriteWarningLog(string message) { LOG.Warning(message); } #endregion } }