using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.ParameterCenter; using Aitex.Core.Util; using FurnaceRT.Devices; using FurnaceRT.Equipments.Boats; using FurnaceRT.Equipments.PMs.RecipeExecutions; using FurnaceRT.Equipments.Systems; using MECF.Framework.Common.Equipment; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Xml; namespace FurnaceRT.Equipments.PMs { public partial class PMModule { public bool IsMainRecipeComplete { get; set; } public bool IsHeaterProfile { get; set; } public bool IsHeaterProfileSuccess { get; set; } public bool IsBoatMoveToLoadPosition{ get; private set; } public bool IsWaitBoatMoveComplete { get; private set; } private string _boatTargetPosition; private R_TRIG _profileTrig = new R_TRIG(); public RecipeRunningInfo RecipeRunningInfo { get { return _recipeRunningInfo; } } public bool IsPaused { get; set; }//按了hold按键 public bool IsHolded { get; set; }//按了hold按键之后,当前step执行完了 public bool IsWait { get; set; }//等待wait条件的结束 public void ResetToleranceChecker() { } public void OnProcessStart(string v1, string recipeName, bool v2) { } public void PauseRecipe(out string reason) { reason = string.Empty; } public bool CheckEndPoint() { return true; } public bool CheckAllDevicesStable(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9) { return true; } public bool CheckEnableRunProcess(out string reason) { reason = string.Empty; return true; } public void AbortRunProcess(out string reason) { //GasSticks.ForEach(x => x.SetFlow(out _, 0, 0)); reason = string.Empty; } private bool SetBoatManualMotion(object[] param) { if (param == null || param.Length < 1) { return false; } var paramArray = param[0].ToString().Split(';'); var loaderCommand = paramArray[0].ToString(); switch (loaderCommand.ToLower().Replace(" ", "")) { case "boatload": if (paramArray.Length > 3) { var boat = Singleton.Instance.Modules[ModuleName.Boat] as BoatModule; if (!boat.CheckPrepareMove(out string reason)) { boat.BoatZAxisMoveFailedForInterlock.Set(reason); return false; } float.TryParse(paramArray[1], out float speed1); float.TryParse(paramArray[2], out float speed2); float.TryParse(paramArray[3], out float speed3); ZAxisDevice.SetServoMoveTo("Position1", out _, speed1); } break; case "boatunload": if (paramArray.Length > 3) { var boat = Singleton.Instance.Modules[ModuleName.Boat] as BoatModule; if (!boat.CheckPrepareMove(out string reason)) { boat.BoatZAxisMoveFailedForInterlock.Set(reason); return false; } float.TryParse(paramArray[1], out float speed1); float.TryParse(paramArray[2], out float speed2); float.TryParse(paramArray[3], out float speed3); ZAxisDevice.SetServoMoveTo("Position3", out _, speed1); } break; case "boatloaderhome": { var boat = Singleton.Instance.Modules[ModuleName.Boat] as BoatModule; if (!boat.CheckPrepareMove(out string reason)) { boat.BoatZAxisMoveFailedForInterlock.Set(reason); return false; } } ZAxisDevice.SetServoMoveTo("HomePosition", out _); break; case "boatcap2": if (paramArray.Length > 1) { var boat = Singleton.Instance.Modules[ModuleName.Boat] as BoatModule; if (!boat.CheckPrepareMove(out string reason)) { boat.BoatZAxisMoveFailedForInterlock.Set(reason); return false; } float.TryParse(paramArray[1], out float speed); ZAxisDevice.SetServoMoveTo("CapPosition", out _, speed); } break; case "boatrotate": if (paramArray.Length > 1) { float.TryParse(paramArray[1], out float speed); RAxisDevice.SetServoMoveTo("CCW", out _, speed); } break; case "boatrotatestop"://r home RAxisDevice.ServoStop(); RAxisDevice.SetServoHome(); break; case "stop(includer-axis)": RAxisDevice.ServoStop(); break; } return true; } private bool SetValves(object[] param) { var stopwatch = new Stopwatch(); stopwatch.Start(); if (param == null || param.Length < 1) { return false; } var paramArray = param[0].ToString().Split(';'); for(int i=0; i< paramArray.Length;i++) { var item = paramArray[i]; if (string.IsNullOrEmpty(item)) continue; var valveDatas = item.Split(','); if(valveDatas != null && valveDatas.Length > 1) { var valveName = valveDatas[0]; var valveSet = valveDatas[1]; if (valveSet == "Continue") continue; bool.TryParse(valveSet, out bool set); switch(valveName.ToUpper()) { case "F2CLN": IsF2ClnOn = set; break; case "HFCLN": IsHFClnOn = set; break; case "HTR1": //_HTR1Group.ForEach(x => x.SetEnable(set)); SetHTR1Enable(new object[1] { set }); break; case "HTR2": //_HTR2Group.ForEach(x => x.SetEnable(set)); SetHTR2Enable(new object[1] { set }); break; case "HTR3": SetHTR3Enable(new object[1] { set }); break; case "DEPO": SetDEPOEnable(new object[1] { set }); break; case "DPR": valveName = "ValveAV91"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; case "AGV": valveName = "AGVPump"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; case "AGV2": valveName = "AGV2Pump"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; case "MBP": case "MBP1": case "MBP2": case "DP": valveName = "BothPump"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; case "DP1": valveName = "BothPump1"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; case "DP2": valveName = "BothPump2"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; case "BWR": valveName = "ValveBlowerPowerOn"; if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; default: if (_valves.Any(x => x.Name == valveName)) { var valve = _valves.Find(x => x.Name == valveName); if (valve != null) valve.TurnValve(set, out _); } break; } } } LOG.Write($"SetValves exec time {stopwatch.ElapsedMilliseconds}"); return true; } private bool SetBoatMotion(object[] param) { var boatModule = Singleton.Instance.Modules[ModuleName.Boat] as BoatModule; if (param == null || param.Length < 1 || boatModule == null) { return false; } var paramArray = param[0].ToString().Split(';'); var loaderCommand = paramArray[0].ToString(); IsWaitBoatMoveComplete = false; IsBoatMoveToLoadPosition = false; switch (loaderCommand.ToLower().Replace(" ", "")) { case "boatload": if (paramArray.Length > 3) { float.TryParse(paramArray[1], out float speed1); float.TryParse(paramArray[2], out float speed2); float.TryParse(paramArray[3], out float speed3); IsWaitBoatMoveComplete = true; IsBoatMoveToLoadPosition = true; _boatTargetPosition = "Position1"; //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed1); boatModule.BoatMove("boatload", _boatTargetPosition, speed1); } break; case "boatunload": if (paramArray.Length > 3) { float.TryParse(paramArray[1], out float speed1); float.TryParse(paramArray[2], out float speed2); float.TryParse(paramArray[3], out float speed3); IsWaitBoatMoveComplete = true; _boatTargetPosition = "Position3"; //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed1); boatModule.BoatMove("boatunload", _boatTargetPosition, speed1); } break; case "boatloaderhome": IsWaitBoatMoveComplete = true; _boatTargetPosition = "HomePosition"; //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _); boatModule.BoatMove("boatloaderhome", _boatTargetPosition, 0); break; case "boatcap2": if (paramArray.Length > 1) { float.TryParse(paramArray[1], out float speed); IsWaitBoatMoveComplete = true; _boatTargetPosition = "CapPosition"; //ZAxisDevice.SetServoMoveTo(_boatTargetPosition, out _, speed); boatModule.BoatMove("boatcap2", _boatTargetPosition, speed); } break; case "boatrotate": if (paramArray.Length > 4) { float.TryParse(paramArray[4], out float speed); //RAxisDevice.SetServoMoveTo("CCW", out _, speed); //boatModule.BoatMove("boatrotate", "CCW", speed); boatModule.RAxisDevice.SetServoMoveTo("CCW", out string reason, speed);//旋转直接发 } break; case "boatrotatestop"://r home IsWaitBoatMoveComplete = true; _boatTargetPosition = "RotateHome"; //RAxisDevice.ServoStop(); //RAxisDevice.SetServoHome(); boatModule.BoatMove("boatrotatestop", _boatTargetPosition, 0); break; case "stop(includer-axis)": //RAxisDevice.ServoStop(); boatModule.BoatMove("stop(includer-axis)", "", 0); break; } return true; } public bool CheckBoatWaitCondition(out string reason) { reason = ""; if (!IsWaitBoatMoveComplete) return true; if (_boatTargetPosition == "RotateHome") { if (!RAxisDevice.IsHomeDone) { reason = "rotate not home done"; return false; } return (Singleton.Instance.Modules[ModuleName.Boat] as BoatModule).IsReady; } else { if (!ZAxisDevice.CheckServoAtPosition(_boatTargetPosition)) { reason = $"elevator not at {_boatTargetPosition}"; return false; } return (Singleton.Instance.Modules[ModuleName.Boat] as BoatModule).IsReady; } } public bool CheckAPCWaitCondition(out string reason) { return APCDevice.CheckWaitCondition(out reason); } public bool CheckMFCWaitCondition(out string reason) { reason = ""; var ret = true; foreach (var mfc in _processMFCs) { if (!mfc.CheckWaitCondition(out string info)) { reason += $"{info} \n"; ret = false; } } return ret; } public bool CheckHeaterWaitCondition(out string reason) { reason = ""; var ret = true; foreach (var heater in _heaters) { if(!heater.CheckWaitCondition(out string info)) { reason += $"{info} \n"; ret = false; } } return ret; } public void AbortRecipe() { _processMFCs.ForEach(x=>x.Terminate()); _heaters.ForEach(x=>x.Terminate()); _valves.ForEach(x=>x.Terminate()); ZAxisDevice.ServoStop(); RAxisDevice.ServoStop(); APC.Terminate(); AbortLeakCheck(); IsWait = false; } public void HeaterEnable(bool isEnable) { _heaters.ForEach(x => x.SetEnable(isEnable)); } public bool CheckHeaterProfileFinish(out string reason) { reason = ""; if (_heaters.Any(x => x.IsProfileMode)) { IsHeaterProfile = true; var ret = true; foreach(var heater in _heaters) { if (!heater.CheckProfileFinish(out string info)) { reason += $"{info} \n"; ret = false; } } if (!ret) { foreach (var heater in _heaters) { heater.IsProfileSuccess = false;//有任何一个没结束,所有都要接着判断 } _profileTrig.CLK = false; return false;//有任何一个没结束 } if (HeaterU.IsProfileSuccess && HeaterCU.IsProfileSuccess && HeaterC.IsProfileSuccess && HeaterCL.IsProfileSuccess && HeaterL.IsProfileSuccess) { IsHeaterProfileSuccess = true; _profileTrig.CLK = true; _heaters.ForEach(x=>x.DeviceData.ProfileStatus = "Normal End"); _heaters.ForEach(x=>x.ProfileFinish()); if (_profileTrig.Q) SaveHeaterProflieToCorrectTable(_heaters[0].CurrentCorrectFileName, _heaters[0].CurrentCorrectIndex);//更新profile table } return true; } else { _heaters.ForEach(x => x.ProfileFinish()); return true;//不处于profile模式 } } private void SaveHeaterProflieToCorrectTable(string correctFileName, int tableIndex) { var content = ParameterFileManager.Instance.LoadParameter("Parameter\\TempCorrection", correctFileName, false); if (string.IsNullOrEmpty(content)) { EV.PostWarningLog(Module, $"{correctFileName} heater temperature correct file is empty"); return; } var doc = new XmlDocument(); doc.LoadXml(content); XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step"); if (nodeSteps == null) nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step"); if (nodeSteps == null) { EV.PostWarningLog(Module, $"Invalid heater temperature correct file {correctFileName}"); return; } if (tableIndex < 1 || nodeSteps.Count < tableIndex) { EV.PostWarningLog(Module, $"{correctFileName} heater temperature correct file table id={tableIndex} is invalid"); return; } XmlElement targetStepNode = nodeSteps[tableIndex - 1] as XmlElement; if(targetStepNode != null) { var correctionDataString = targetStepNode.GetAttribute("CorrectionData"); if (string.IsNullOrEmpty(correctionDataString)) { EV.PostWarningLog(Module, $"Heater temperature correct file is empty"); return; } var correctionDatas = correctionDataString.Split('|'); if (correctionDatas.Length < 5) { EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid"); return; } List newCorrectionDatas = new List(); for (int i=0;i< correctionDatas.Length;i++) { var datas = correctionDatas[i]; var dataArry = datas.Split(';'); if (dataArry.Length < 6) { EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid"); return; } var correctParameter = new CorrectParameter(); foreach (var item in dataArry) { var itemArry = item.Split(':'); if (itemArry.Length < 2) { EV.PostWarningLog(Module, $"Heater temperature correct file data length is invalid"); return; } switch (itemArry[0].ToLower()) { case "index": int.TryParse(itemArry[1], out int no); correctParameter.No = no; break; case "name": correctParameter.Name = itemArry[1]; break; case "profiletemp": float.TryParse(itemArry[1], out float profiletemp); correctParameter.ProfileTemp = profiletemp; break; case "profilecorrect": float.TryParse(itemArry[1], out float profilecorrect); correctParameter.ProfileCorrect = profilecorrect; break; case "cascadetccorrect": float.TryParse(itemArry[1], out float cascadetccorrect); correctParameter.CascadeTCCorrect = cascadetccorrect; break; case "profiletccalib": float.TryParse(itemArry[1], out float profiletccalib); correctParameter.ProfileTCCalib = profiletccalib; break; } } FurnaceRT.Devices.IoHeater heater = null; if(_heaters.Count > i) { heater = _heaters[i]; } if(heater != null) { newCorrectionDatas.Add($"Index:{correctParameter.No};Name:{correctParameter.Name};ProfileTemp:{heater.DeviceData.HeaterPV};ProfileCorrect:{(heater.DeviceData.HeaterPV - heater.DeviceData.CascadePV).ToString("f1")};CascadeTCCorrect:{heater.DeviceData.CascadePV};ProfileTCCalib:{correctParameter.ProfileTCCalib}"); heater.DeviceData.ProfileResult = correctParameter.ProfileCorrect; } } if (newCorrectionDatas.Count == correctionDatas.Length) targetStepNode.SetAttribute("CorrectionData", string.Join("|", newCorrectionDatas.ToArray())); LOG.Write($"Profile result {correctFileName}:{tableIndex} CorrectionData={string.Join("|", newCorrectionDatas.ToArray())}"); //FileStream fileStream = new FileStream(ParameterFileManager.Instance.GenerateParameterFilePath("Parameter\\TempCorrection", correctFileName), FileMode.Create); //doc.Save(fileStream); using (FileStream fileStream = new FileStream(ParameterFileManager.Instance.GenerateParameterFilePath("Parameter\\TempCorrection", correctFileName), FileMode.Create)) { doc.Save(fileStream); } } } private bool SetAlarmConditionTable(object[] param) { if (param == null || param.Length < 1) { return false; } var array = param[0].ToString().Split(':'); int.TryParse(array[0], out int index); lock (_alarmConditionLocker) { SetAlarmConditionTableIndex(index); } return true; } } }