using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Xml; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.Utilities; using FurnaceRT.Equipments.Boats; using FurnaceRT.Equipments.CarrierRobots; using FurnaceRT.Equipments.FIMSs; using FurnaceRT.Equipments.LPs; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.PMs.RecipeExecutions; using FurnaceRT.Equipments.Stockers; using FurnaceRT.Equipments.WaferRobots; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.Core.Applications; using MECF.Framework.RT.Core.IoProviders; namespace FurnaceRT.Equipments.Systems { public partial class EquipmentManager { private CarrierRobotModule _cassetteRobotModule; private WaferRobotModule _waferRobotModule; private LoadPortModule _lp1Module; private LoadPortModule _lp2Module; private LoadPortModule _lp3Module; private LoadPortModule _lp4Module; private FIMSModule _fims1Module; private FIMSModule _fims2Module; private BoatModule _boatModule; private RD_TRIG _pauseTrig = new RD_TRIG(); private IoSensor _sensorEMSTP; private IoSensor _sensorEnableTP; private IoSensor _sensorPort1LockUnlock; private IoSensor _sensorPort2LockUnlock; private IoSensor _sensorBuzzerOff; private IoSensor _sensorIn; private IoSensor _sensorOut; private IoSensor _sensorMECHIlkReset; private IoSensor _sensorTXPauseFront; private IoSensor _sensorELVPauseFront; private IoSensor _sensorTXPauseBack; private IoSensor _sensorELVPauseBack; private IoTrigger _trigPort1LockUnlockLight; private IoTrigger _trigPort2LockUnlockLight; private IoTrigger _trigBuzzerOffLight; private IoTrigger _trigCassetteInLight; private IoTrigger _trigCassetteOutLight; private IoTrigger _trigMECHIlkResetLight; private IoTrigger _trigTXPauseFrontLight; private IoTrigger _trigELVPauseFrontLight; private IoTrigger _trigTXPauseBackLight; private IoTrigger _trigELVPauseBackLight; private int _TXPauseTrigCount = 0; private int _ELVPauseTrigCount = 0; private PeriodicJob _monitorInCommandJob; private List _inCommandLst; private Dictionary _inCommandTirgs = new Dictionary(); protected virtual void InitModules() { for (int i = 1; i <= 30; i++) { if (SC.ContainsItem($"System.SetUp.IsStocker{i}Installed") && SC.GetValue($"System.SetUp.IsStocker{i}Installed")) { var module = ModuleHelper.Converter($"Stocker{i}"); var stocker = new StockerModule(module); Modules[module] = stocker; } } Modules[ModuleName.PM1] = new PMModule(ModuleName.PM1); if (SC.GetValue($"System.SetUp.IsLP1Installed")) { _lp1Module = new LoadPortModule(ModuleName.LP1); Modules[ModuleName.LP1] = _lp1Module; } if (SC.GetValue($"System.SetUp.IsLP2Installed")) { _lp2Module = new LoadPortModule(ModuleName.LP2); Modules[ModuleName.LP2] = _lp2Module; } if (SC.GetValue($"System.SetUp.IsLP3Installed")) { _lp3Module = new LoadPortModule(ModuleName.LP3); Modules[ModuleName.LP3] = _lp3Module; } if (SC.GetValue($"System.SetUp.IsLP4Installed")) { _lp4Module = new LoadPortModule(ModuleName.LP4); Modules[ModuleName.LP4] = _lp4Module; } _cassetteRobotModule = new CarrierRobotModule(ModuleName.CarrierRobot); Modules[ModuleName.CarrierRobot] = _cassetteRobotModule; _waferRobotModule = new WaferRobotModule(ModuleName.WaferRobot); Modules[ModuleName.WaferRobot] = _waferRobotModule; if (SC.GetValue($"System.SetUp.IsFIMS1Installed")) { _fims1Module = new FIMSModule(ModuleName.FIMS1); Modules[ModuleName.FIMS1] = _fims1Module; } if (SC.GetValue($"System.SetUp.IsFIMS2Installed")) { _fims2Module = new FIMSModule(ModuleName.FIMS2); Modules[ModuleName.FIMS2] = _fims2Module; } _boatModule = new BoatModule(ModuleName.Boat); Modules[ModuleName.Boat] = _boatModule; foreach (var modulesValue in Modules.Values) { modulesValue.Initialize(); } //_monitorInCommandJob = new PeriodicJob(50, ModulesOnTimer, "Modules monitor thread", true); } private bool ModulesOnTimer() { return true; foreach (var item in _inCommandLst) { if (item == null) continue; if (!_inCommandTirgs.ContainsKey(item.Name)) { _inCommandTirgs.Add(item.Name, new RD_TRIG()); } _inCommandTirgs[item.Name].CLK = item.Value; } if ((_inCommandTirgs.ContainsKey(_sensorTXPauseFront?.Name) && _inCommandTirgs[_sensorTXPauseFront?.Name].R) || (_inCommandTirgs.ContainsKey(_sensorTXPauseBack?.Name) && _inCommandTirgs[_sensorTXPauseBack?.Name].R)) { _TXPauseTrigCount++; if (_TXPauseTrigCount % 2 == 1) { _trigTXPauseFrontLight?.SetTrigger(true, out _); _trigTXPauseBackLight?.SetTrigger(true, out _); _cassetteRobotModule.CarrierRobotDevice.SetPauseResume(true); _waferRobotModule.WaferRobotDevice.SetPauseResume(true); _fims1Module.FIMSDevice.SetPauseResume(true); _fims2Module.FIMSDevice.SetPauseResume(true); } else { _trigTXPauseFrontLight?.SetTrigger(false, out _); _trigTXPauseBackLight?.SetTrigger(false, out _); _cassetteRobotModule.CarrierRobotDevice.SetPauseResume(false); _waferRobotModule.WaferRobotDevice.SetPauseResume(false); _fims1Module.FIMSDevice.SetPauseResume(false); _fims2Module.FIMSDevice.SetPauseResume(false); } } if ((_inCommandTirgs.ContainsKey(_sensorELVPauseFront?.Name) && _inCommandTirgs[_sensorELVPauseFront?.Name].R) || (_inCommandTirgs.ContainsKey(_sensorELVPauseBack?.Name) && _inCommandTirgs[_sensorELVPauseBack?.Name].R)) { _ELVPauseTrigCount++; if (_ELVPauseTrigCount % 2 == 1) { _trigELVPauseFrontLight?.SetTrigger(true, out _); _trigELVPauseBackLight?.SetTrigger(true, out _); _boatModule.ZAxisDevice.SetPauseResume(true); _boatModule.RAxisDevice.SetPauseResume(true); } else { _trigELVPauseFrontLight?.SetTrigger(false, out _); _trigELVPauseBackLight?.SetTrigger(false, out _); _boatModule.ZAxisDevice.SetPauseResume(false); _boatModule.RAxisDevice.SetPauseResume(false); } } foreach (var modulesValue in Modules.Values) { if (modulesValue != null) modulesValue.Monitor(); } return true; } protected virtual void InitDevices() { _sensorEMSTP = DEVICE.GetDevice($"System.SensorEMSTP"); _sensorEnableTP = DEVICE.GetDevice($"System.SensorEnableTP"); _sensorPort1LockUnlock = DEVICE.GetDevice($"System.SensorPort1LockUnlock"); _sensorPort2LockUnlock = DEVICE.GetDevice($"System.SensorPort2LockUnlock"); _sensorBuzzerOff = DEVICE.GetDevice($"System.SensorBuzzerOff"); _sensorIn = DEVICE.GetDevice($"System.SensorIn"); _sensorOut = DEVICE.GetDevice($"System.SensorOut"); _sensorMECHIlkReset = DEVICE.GetDevice($"System.SensorMECHIlkReset"); _sensorTXPauseFront = DEVICE.GetDevice($"System.SensorTXPauseFront"); _sensorELVPauseFront = DEVICE.GetDevice($"System.SensorELVPauseFront"); _sensorTXPauseBack = DEVICE.GetDevice($"System.SensorTXPauseBack"); _sensorELVPauseBack = DEVICE.GetDevice($"System.SensorELVPauseBack"); _trigPort1LockUnlockLight = DEVICE.GetDevice($"System.TrigPort1LockUnlockLight"); _trigPort2LockUnlockLight = DEVICE.GetDevice($"System.TrigPort2LockUnlockLight"); _trigBuzzerOffLight = DEVICE.GetDevice($"System.TrigBuzzerOffLight"); _trigCassetteInLight = DEVICE.GetDevice($"System.TrigCassetteInLight"); _trigCassetteOutLight = DEVICE.GetDevice($"System.TrigCassetteOutLight"); _trigMECHIlkResetLight = DEVICE.GetDevice($"System.TrigMECHIlkResetLight"); _trigTXPauseFrontLight = DEVICE.GetDevice($"System.TrigTXPauseFrontLight"); _trigELVPauseFrontLight = DEVICE.GetDevice($"System.TrigELVPauseFrontLight"); _trigTXPauseBackLight = DEVICE.GetDevice($"System.TrigTXPauseBackLight"); _trigELVPauseBackLight = DEVICE.GetDevice($"System.TrigELVPauseBackLight"); if (_trigTXPauseFrontLight != null && _trigTXPauseFrontLight.Value) _TXPauseTrigCount = 1; if (_trigELVPauseFrontLight != null && _trigELVPauseFrontLight.Value) _ELVPauseTrigCount = 1; _inCommandLst = new List() { _sensorEMSTP, _sensorEnableTP, _sensorPort1LockUnlock, _sensorPort2LockUnlock, _sensorBuzzerOff, _sensorIn, _sensorOut, _sensorMECHIlkReset, _sensorTXPauseFront, _sensorELVPauseFront, _sensorTXPauseBack, _sensorELVPauseBack, }; this.OnDeviceAlarmStateChanged += OnModuleDeviceAlarmStateChanged; } public bool GetJobRecipeInfor(string jobRecipeName, out string processRecipe, out string layoutRecipe, out int coolTimeSec, out string reason) { processRecipe = ""; layoutRecipe = ""; reason = ""; coolTimeSec = 0; string abortRecipeName = SC.ContainsItem("System.Recipe.Abort Recipe") ? SC.GetStringValue("System.Recipe.Abort Recipe") : string.Empty; if (string.IsNullOrEmpty(abortRecipeName)) { reason = $"Load abort recipe failed, recipe file is null"; return false; } if (!RecipeParser.Parse(abortRecipeName, ModuleName.PM1.ToString(), out var abortRecipeHead, out var abortRecipeSteps, out reason, "Abort")) { reason = $"Load abort recipe {abortRecipeName} failed, {reason}"; return false; } var module = "PM1"; var processType = SC.GetStringValue("System.Recipe.SupportedJobType"); var prefixPath = $"Furnace\\{processType}"; var recipeContent = RecipeFileManager.Instance.LoadRecipe(prefixPath, jobRecipeName, false); if (string.IsNullOrEmpty(recipeContent)) { reason = $"{prefixPath}\\{jobRecipeName} is empty, please confirm the file is valid."; return false; } var doc = new XmlDocument(); doc.LoadXml(recipeContent); var nodeModule = doc.SelectSingleNode($"Aitex/TableRecipeData/Module[@Name='{module}']/Step"); XmlElement stepNode = nodeModule as XmlElement; if (nodeModule == null) { reason = $"{prefixPath}\\{jobRecipeName} is empty, please confirm the file is valid."; return false; } var strCoolTime = ""; foreach (XmlAttribute att in stepNode.Attributes) { switch (att.Name) { case "ProcessRecipe": processRecipe = att.Value; break; case "LayoutRecipe": layoutRecipe = att.Value; break; case "CoolTime": strCoolTime = att.Value; break; } } if (!string.IsNullOrEmpty(strCoolTime)) { if (System.Text.RegularExpressions.Regex.Match(strCoolTime, @"[a-zA-Z]").Success) { if (SC.ContainsItem($"PM1.RecipeEditParameter.CoolTime.{strCoolTime}")) { var time = DateTime.Parse(SC.GetStringValue($"PM1.RecipeEditParameter.CoolTime.{strCoolTime}")); coolTimeSec = time.Second + time.Minute * 60 + time.Hour * 3600; } else { reason = $"Configuration does not contains cool time config {strCoolTime}"; return false; } } else { if (DateTime.TryParse(strCoolTime, out DateTime time)) { coolTimeSec = time.Second + time.Minute * 60 + time.Hour * 3600; } else if (Int32.TryParse(strCoolTime, out int timeInSec)) { coolTimeSec = timeInSec; } else { reason = $"Cool time {strCoolTime} is invalid"; return false; } } } return true; } } }