using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Media; using Aitex.Core.Common; using Aitex.Core.Common.DeviceData; using Aitex.Core.Util; using Aitex.Core.Utilities; using Caliburn.Micro; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.OperationCenter; using MECF.Framework.Common.RecipeCenter; using OpenSEMI.ClientBase; using VirgoCommon; using VirgoUI.Client.Models.Recipe; using VirgoUI.Client.Models.Sys; using Ax = Aitex.Core.Common; namespace VirgoUI.Client.Models.PMs { public class PmOverviewViewModel : ModuleUiViewModelBase, ISupportMultipleSystem { private object[] _oldmfc = new object[5] { 0.0, 0.0, 0.0, 0.0, 0.0 }; //public Ax.WaferInfo PMWafer { get; set; } //private Ax.WaferSize _PMWaferType = Ax.WaferSize.WS6; //public Ax.WaferSize PMWaferType //{ // get // { // return _PMWaferType; // } // set // { // _PMWaferType = value; // NotifyOfPropertyChange("PMWaferType"); // } //} private int _BottomPinStatus = 0; public int BottomPinStatus { get { return _BottomPinStatus; } set { _BottomPinStatus = value; NotifyOfPropertyChange("BottomPinStatus"); } } private int _MidPinStatus = 0; public int MidPinStatus { get { return _MidPinStatus; } set { _MidPinStatus = value; NotifyOfPropertyChange("MidPinStatus"); } } private int _TopPinStatus = 0; public int TopPinStatus { get { return _TopPinStatus; } set { _TopPinStatus = value; NotifyOfPropertyChange("TopPinStatus"); } } private int _CoverStatus = 0; public int CoverStatus { get { return _CoverStatus; } set { _CoverStatus = value; NotifyOfPropertyChange("CoverStatus"); } } //private int _ChamberStatus; //public int ChamberStatus //{ // get { return _ChamberStatus; } // set // { // _ChamberStatus = value; // NotifyOfPropertyChange("ChamberStatus"); // } //} private List _PMParameters; public List PMParameters { get { return _PMParameters; } set { _PMParameters = value; NotifyOfPropertyChange("PMParameters"); } } private List _Temperatures; public List Temperatures { get { return _Temperatures; } set { _Temperatures = value; NotifyOfPropertyChange("Temperatures"); } } private List _Gaslines; public List Gaslines { get { return _Gaslines; } set { _Gaslines = value; NotifyOfPropertyChange("Gaslines"); } } [Subscription("EPD.IsConnected")] public bool IsEPDConnected { get; set; } [Subscription("EPD.ChannelStatus")] public string EPDStatus { get; set; } public Visibility EPDVisibility { get; set; } [Subscription("EnableBiasRF")] public bool EnableBiasRF { get; set; } [Subscription("IoThrottleValve.ThrottleValve.ProcessPressureOffset")] public double ProcessPressureOffset { get; set; } [Subscription("IoMfc.MfcGas1.IsEnable")] public bool MfcGas1Enable { get; set; } [Subscription("IoMfc.MfcGas2.IsEnable")] public bool MfcGas2Enable { get; set; } [Subscription("IoMfc.MfcGas3.IsEnable")] public bool MfcGas3Enable { get; set; } [Subscription("IoMfc.MfcGas4.IsEnable")] public bool MfcGas4Enable { get; set; } [Subscription("IoMfc.MfcGas5.IsEnable")] public bool MfcGas5Enable { get; set; } [Subscription("ModuleWaferList")] public Ax.WaferInfo[] ChamberWafer { get; set; } [Subscription("SlitDoor.DeviceData")] public AITCylinderData SlitDoorData { get; set; } [Subscription("LiftPin.DeviceData")] public AITCylinderData LiftPinData { get; set; } [Subscription("SmallPin.DeviceData")] public AITCylinderData UpperPinData { get; set; } [Subscription("MediumPin.DeviceData")] public AITCylinderData LowerPinData { get; set; } [Subscription("Lid.DeviceData")] public AITCylinderData LidData { get; set; } [Subscription("LidLocker.DeviceData")] public AITCylinderData LidLockerData { get; set; } [Subscription("IsOnline")] public bool IsOnline { get; set; } [Subscription("LeakRate")] public double LeakRate { get; set; } [Subscription("IsCDAOK")] public bool IsCDAOK { get; set; } [Subscription("IsArmNotExtend")] public bool IsArmNotExtend { get; set; } [Subscription(VirgoDevice.ValveMfc1)] public AITValveData GP1Valve { get; set; } [Subscription(VirgoDevice.ValveMfc2)] public AITValveData GP2Valve { get; set; } [Subscription(VirgoDevice.ValveMfc3)] public AITValveData GP3Valve { get; set; } [Subscription(VirgoDevice.ValveMfc4)] public AITValveData GP4Valve { get; set; } [Subscription(VirgoDevice.ValveMfc5)] public AITValveData GP5Valve { get; set; } [Subscription(VirgoDevice.ValveChamberPurge)] public AITValveData ChamberPurgeValve { get; set; } [Subscription(VirgoDevice.ValveChamberPurge)] public AITValveData SoftVentVlv { get; set; } [Subscription(VirgoDevice.ValveFastVent)] public AITValveData FastVentVlv { get; set; } [Subscription(VirgoDevice.ValveSoftPumping)] public AITValveData SoftPumpVlv { get; set; } [Subscription(VirgoDevice.ValveFastPumping)] public AITValveData FastPumpVlv { get; set; } [Subscription(VirgoDevice.ValveN2Supply)] public AITValveData N2SupplyVlv { get; set; } [Subscription(VirgoDevice.ValveProcess)] public AITValveData ProcessVlv { get; set; } [Subscription("SensorATMSwitch")] public AITSensorData SensorATMSwitch { get; set; } [Subscription("N2PressureOk")] public AITSensorData N2PressureOk { get; set; } [Subscription("SensorVacSwitch")] public AITSensorData SensorVacSwitch { get; set; } [Subscription("SensorWaterFlowOk")] public AITSensorData SensorWaterFlowOk { get; set; } [Subscription("SensorCDAPressureOk")] public AITSensorData SensorCDAPressureOk { get; set; } [Subscription("SourceFan1")] public AITSensorData SourceFan1 { get; set; } [Subscription("SourceFan2")] public AITSensorData SourceFan2 { get; set; } [Subscription("SensorWaterLeakOk")] public AITSensorData SensorWaterLeakOk { get; set; } [Subscription("SensorArmNotExtend")] public AITSensorData SensorArmNotExtend { get; set; } private AITMfcData _mfc1; [Subscription(VirgoDevice.MfcGas1)] public AITMfcData GP1Mfc { get { return _mfc1; } set { _mfc1 = value; if (IsAutoMode && MfcGas1Enable) { PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas1.FeedBack").Setpoint = _mfc1.SetPoint.ToString("F1"); } } } private AITMfcData _mfc2; [Subscription(VirgoDevice.MfcGas2)] public AITMfcData GP2Mfc { get { return _mfc2; } set { _mfc2 = value; if (IsAutoMode && MfcGas2Enable) { PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas2.FeedBack").Setpoint = _mfc2.SetPoint.ToString("F1"); } } } private AITMfcData _mfc3; [Subscription(VirgoDevice.MfcGas3)] public AITMfcData GP3Mfc { get { return _mfc3; } set { _mfc3 = value; if (IsAutoMode && MfcGas3Enable/* && _Gaslines.Count > 2*/) { PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas3.FeedBack").Setpoint = _mfc3.SetPoint.ToString("F1"); } } } private AITMfcData _mfc4; [Subscription(VirgoDevice.MfcGas4)] public AITMfcData GP4Mfc { get { return _mfc4; } set { _mfc4 = value; if (IsAutoMode && MfcGas4Enable/* && _Gaslines.Count > 3*/) { PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas4.FeedBack").Setpoint = _mfc4.SetPoint.ToString("F1"); } } } private AITMfcData _mfc5; [Subscription(VirgoDevice.MfcGas5)] public AITMfcData GP5Mfc { get { return _mfc5; } set { _mfc5 = value; if (IsAutoMode && MfcGas5Enable/* && _Gaslines.Count > 4*/) { PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas5.FeedBack").Setpoint = _mfc5.SetPoint.ToString("F1"); } } } [Subscription("Chiller.DeviceData")] public AITChillerData ChillerData { get; set; } [Subscription("HeaterChamber.DeviceData")] public AITHeaterData HeaterChamber { get; set; } [Subscription("ForelineHeater.DeviceData")] public AITHeaterData ForelineHeater { get; set; } [Subscription("WallHeater.DeviceData")] public AITHeaterData WallHeater { get; set; } [Subscription("GridHeater.DeviceData")] public AITHeaterData GridHeater { get; set; } [Subscription(VirgoDevice.ProcessGauge)] public AITPressureMeterData ProcessGauge { get; set; } [Subscription(VirgoDevice.PressureGauge)] public AITPressureMeterData PressureGauge { get; set; } [Subscription(VirgoDevice.ForelineGauge)] public AITPressureMeterData ForelineGauge { get; set; } private AITRfData _rf; [Subscription("Rf.DeviceData")] public AITRfData Rf { get { return _rf; } set { _rf = value; if (IsAutoMode) { PMParameters.Find(x => x.Name == $"{SystemName}.Rf.PowerOnTime").Setpoint = ""; PMParameters.Find(x => x.Name == $"{SystemName}.Rf.ForwardPower").Setpoint = _rf.PowerSetPoint.ToString("F0"); RfDutySetPoint = _rf.DutySetPoint.ToString("F0"); NotifyOfPropertyChange("RfDutySetPoint"); RfFrequencySetPoint = _rf.FrequencySetPoint.ToString("F0"); NotifyOfPropertyChange("RfFrequencySetPoint"); RfModeSetPoint = _rf.WorkMode == (int)RfMode.ContinuousWaveMode ? "Continuous" : "Pulsing"; NotifyOfPropertyChange("RfModeSetPoint"); } } } private AITRfData _rfBias; [Subscription("BiasRf.DeviceData")] public AITRfData RfBias { get { return _rfBias; } set { _rfBias = value; if (IsAutoMode) { PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.MatchProcessMode").Setpoint = _rfBias.MatchPresetMode == (int)BiasRfMatchMode.Preset ? "Preset" : "Hold"; PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.C1").Setpoint = _rfBias.MatchPositionC1SetPoint.ToString("F1"); PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.C2").Setpoint = _rfBias.MatchPositionC2SetPoint.ToString("F1"); PMParameters.Find(x => x.Name == $"{SystemName}.BiasRf.ForwardPower").Setpoint = _rfBias.PowerSetPoint.ToString("F0"); RfMatchProcessModeSetPoint = _rf.TritonMatchProcessModeDisplay; InvokePropertyChanged("RfMatchProcessModeSetPoint"); } } } private AITRfMatchData _match; [Subscription("Match.DeviceData")] public AITRfMatchData Match { get { return _match; } set { _match = value; RfMatchPositionC1SetPoint = _match.TunePosition1.ToString("F0"); NotifyOfPropertyChange("RfMatchPositionC1SetPoint"); RfMatchPositionC2SetPoint = _match.TunePosition2.ToString("F0"); NotifyOfPropertyChange("RfMatchPositionC2SetPoint"); } } [Subscription("MainPump.DeviceData")] public AITPumpData MainPumpData { get; set; } private AITThrottleValveData _tv; [Subscription(VirgoDevice.ThrottleValve)] public AITThrottleValveData Tv { get { return _tv; } set { _tv = value; if (IsAutoMode) { PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVMode").Setpoint = _tv.Mode == (int)PressureCtrlMode.TVPressureCtrl ? "Pressure" : _tv.Mode == (int)PressureCtrlMode.TVPositionCtrl ? "Position" : "Undefined"; PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVMode").Feedback = _tv.Mode == (int)PressureCtrlMode.TVPressureCtrl ? "Pressure" : _tv.Mode == (int)PressureCtrlMode.TVPositionCtrl ? "Position" : "Undefined"; PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVPosition").Setpoint = _tv.PositionSetPoint.ToString("F0"); PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVPressure").Setpoint = _tv.PressureSetPoint.ToString("F0"); ThrottleValveModeSetPoint = _tv.TextMode; NotifyOfPropertyChange("ThrottleValveModeSetPoint"); ThrottleValvePositionSetPoint = _tv.PositionSetPoint.ToString("F0"); NotifyOfPropertyChange("ThrottleValvePositionSetPoint"); ThrottleValvePressureSetPoint = _tv.PressureSetPoint.ToString("F0"); NotifyOfPropertyChange("ThrottleValvePressureSetPoint"); } } } public double TvHeight { get; set; } public Visibility TvVisible { get; set; } private AITSensorData _chamberDoorLid = new AITSensorData(); [Subscription(VirgoDevice.ChamberLid)] public AITSensorData ChamberDoorLid { get { return _chamberDoorLid; } set { _chamberDoorLid = value; } } private bool _isAutoMode; private R_TRIG _trigChangeToAuto = new R_TRIG(); [Subscription(StateData.IsAutoMode)] public bool IsAutoMode { get { return _isAutoMode; } set { _isAutoMode = value; _trigChangeToAuto.CLK = _isAutoMode; if (_trigChangeToAuto.Q) { RfTimeSetPoint = ""; NotifyOfPropertyChange("RfTimeSetPoint"); RfModeSetPoint = ""; NotifyOfPropertyChange("RfModeSetPoint"); PMParameters.Find(x => x.Name == $"{SystemName}.Rf.ForwardPower").Setpoint = ""; RfFrequencySetPoint = ""; NotifyOfPropertyChange("RfFrequencySetPoint"); RfDutySetPoint = ""; NotifyOfPropertyChange("RfDutySetPoint"); RfMatchProcessModeSetPoint = ""; InvokePropertyChanged("RfMatchProcessModeSetPoint"); RfMatchPositionC1SetPoint = ""; NotifyOfPropertyChange("RfMatchPositionC1SetPoint"); RfMatchPositionC2SetPoint = ""; NotifyOfPropertyChange("RfMatchPositionC2SetPoint"); for (int i = 1; i <= 5; i++) //GasLine 跳号Enable { if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{i}.Enable")) { PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas{i}.FeedBack").Setpoint = ""; } } //PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas1.FeedBack").Setpoint = ""; //PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas2.FeedBack").Setpoint = ""; //PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas3.FeedBack").Setpoint = ""; //if (_Gaslines.Count > 3) // PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas4.FeedBack").Setpoint = ""; //if (_Gaslines.Count > 4) // PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas5.FeedBack").Setpoint = ""; ElectrodeTemperatureSetPoint = ""; NotifyOfPropertyChange("ElectrodeTemperatureSetPoint"); StepModeSetPoint = ""; NotifyOfPropertyChange("StepModeSetPoint"); } } } public bool IsManualMode { get { return !IsAutoMode; } } public bool IsRFEnabled { get { return IsManualMode && IsGasFlowing || IsRfPowering; } } //public bool IsMatchPositionInputEnabled //{ // get // { // if (Rf != null && Match.TuneMode1 == EnumRfMatchTuneMode.Auto) // return false; // return IsManualMode; // } //} [Subscription(StateData.RecipeStepNo)] public int RecipeStepNo { get; set; } private int _recipeStepMode; [Subscription(StateData.RecipeStepMode)] public int RecipeStepMode { get { return _recipeStepMode; } set { _recipeStepMode = value; if (IsAutoMode) { switch (_recipeStepMode) { //case (int)EndByCondition.EndByHeatUp: // StepModeSetPoint = "Heat Up"; // break; //case (int)EndByCondition.EndByRfTime: // StepModeSetPoint = "RF Time"; // break; default: StepModeSetPoint = "Step Time"; break; } NotifyOfPropertyChange("StepModeSetPoint"); } } } [Subscription(StateData.RecipeProcessTime)] public string RecipeProcessTime { get; set; } [Subscription(StateData.PumpTime)] public string PumpTime { get; set; } [Subscription(StateData.PMState)] public int PMStatus { get; set; } [Subscription(StateData.IsPumpingOkForProcess)] public bool IsPumpingOkForProcess { get; set; } [Subscription(StateData.IsCoolingOkForProcess)] public bool IsCoolingOkForProcess { get; set; } [Subscription(StateData.IsGasFlowingOkForProcess)] public bool IsGasFlowingOkForProcess { get; set; } [Subscription(StateData.DataLogName)] public string DataLogName { get; set; } [Subscription(StateData.TotalCycle)] public int TotalCycle { get; set; } [Subscription(StateData.SmallWafer)] public int SmallWafer { get; set; } [Subscription(StateData.MidWafer)] public int MidWafer { get; set; } [Subscription(StateData.BigWafer)] public int BigWafer { get; set; } public string TvText { get { //if (Tv == null || !SCLocal.PressureControlConfig.EnableThrottleValve) return ""; //return string.Format("{0}%", Tv.PositionFeedback.ToString("F0")); } } public string TvTextBackground { get { if (Tv == null) return "Transparent"; if (Tv.State != 1) return "Red"; return "Green"; } } public string PmOperationMode { get { return IsAutoMode ? "Auto" : "Manual"; } } public string PmOnlineMode { get { return IsOnline ? "Online" : "Offline"; } } public bool IsOnlineButtonEnabled { get { return !IsOnline; } } public bool IsOfflineButtonEnabled { get { return IsOnline; } } [IgnorePropertyChange] public bool BasePressureSetPointSaved { get; set; } [IgnorePropertyChange] public bool PumpLimitSetPointSaved { get; set; } public double ElectrodeTemperatureFeedback { get { return 0; //return SCLocal.CoolingConfig.EnableElectrodeTcLeftAsControlTc ? (ElectrodeLeftThermalCouple!= null ? ElectrodeLeftThermalCouple.FeedBack :0) : // (ElectrodeRightThermalCouple!=null ? ElectrodeRightThermalCouple.FeedBack : 0); } } public int WaferLength { get { Ax.WaferInfo wafer = ChamberWafer==null ? new Ax.WaferInfo() : ChamberWafer[0]; if (wafer.IsEmpty) return 0; switch (wafer.Size) { case Ax.WaferSize.WS3: return 85; case Ax.WaferSize.WS4: return 125; default: return 145; } } } public bool IsHeaterButtonEnable { get { if (SystemName == "PMB") { if ((bool)QueryDataClient.Instance.Service.GetConfig($"PMA.Chiller.EnableChiller") && (bool)QueryDataClient.Instance.Service.GetConfig($"PMB.Chiller.ChillerSameWithPMA")) { return false; } else return IsManualMode; } else return IsManualMode; } } public string HeaterButtonContent { get { if ((bool)QueryDataClient.Instance.Service.GetConfig($"PMA.Chiller.EnableChiller")) { if (SystemName == "PMB") { if ((bool)QueryDataClient.Instance.Service.GetConfig($"PMB.Chiller.ChillerSameWithPMA")) { return "温度设定"; } else { if ((bool)QueryDataClient.Instance.Service.GetConfig($"PMB.Chiller.EnableChiller")) { return "温度设定"; } else { return "底座加热"; } } } else { return "温度设定"; } } else return "底座加热"; } } //public string WaferSize //{ // get // { // Ax.WaferInfo wafer = ChamberWafer == null ? new Ax.WaferInfo() : ChamberWafer[0]; // if (wafer.IsEmpty) // return ""; // switch (wafer.Size) // { // case Ax.WaferSize.WS3: return SmallWafer.ToString(); // case Ax.WaferSize.WS4: return MidWafer.ToString(); // default: return BigWafer.ToString(); // } // } //} public bool IsSmallPinVisible { get { return _smallGuidePinEnable && QueryDataClient.Instance.Service.GetConfig($"{SystemName}.SupportedGuidePinSize").ToString().Split(',').Contains(SmallPinWaferSize.ToString().Replace("WS", "")); } } public bool IsMidPinVisible { get { return _mediumGuidePinEnable && QueryDataClient.Instance.Service.GetConfig($"{SystemName}.SupportedGuidePinSize").ToString().Split(',').Contains(MediumPinWaferSize.ToString().Replace("WS", "")); } } public bool IsLiftPinVisible { get { return true; } } public bool IsLiftPinUp { get { return LiftPinData != null && LiftPinData.OpenFeedback; } } public bool EnableLiftPinUp { get { return !IsAutoMode && LiftPinData != null && !LiftPinData.OpenFeedback; } } public bool EnableLock { get { return LidLockerData != null && !LidLockerData.OpenSetPoint; } } public bool IsLiftPinDown { get { return LiftPinData != null && LiftPinData.CloseFeedback; } } public bool EnableLiftPinDown { get { return !IsAutoMode && LiftPinData != null && !LiftPinData.CloseFeedback; } } public bool EnableUnlock { get { return LidLockerData != null && !LidLockerData.CloseSetPoint; } } public bool IsUpperPinUp { get { return UpperPinData != null && UpperPinData.OpenFeedback; } } public bool EnableUpperPinUp { get { return !IsAutoMode && UpperPinData != null && !UpperPinData.OpenFeedback; } } public bool IsUpperPinDown { get { return UpperPinData != null && UpperPinData.CloseFeedback; } } public bool EnableUpperPinDown { get { return !IsAutoMode && UpperPinData != null && !UpperPinData.CloseFeedback; } } public bool IsLowerPinUp { get { return LowerPinData != null && LowerPinData.OpenFeedback; } } public bool EnableLowerPinUp { get { return !IsAutoMode && LowerPinData != null && !LowerPinData.OpenFeedback; } } public bool IsLowerPinDown { get { return LowerPinData != null && LowerPinData.CloseFeedback; } } public bool EnableLowerPinDown { get { return !IsAutoMode && LowerPinData != null && !LowerPinData.CloseFeedback; } } public bool IsLidOpen { get { return LidData != null && !LidData.CloseFeedback; } } public bool EnableCloseLid { get { return LidData != null && !LidData.CloseFeedback; } } public bool EnableOpenLid { get { return LidData != null && LidData.CloseFeedback; } } public bool IsSlitValveOpen { get { return SlitDoorData != null && SlitDoorData.OpenFeedback; } } public bool IsSlitValveClose { get { return !IsSlitValveOpen; } } public bool EnableCloseSlitValve { get { return !IsAutoMode && SlitDoorData != null && !SlitDoorData.CloseFeedback; } } public bool EnableOpenSlitValve { get { return !IsAutoMode && SlitDoorData != null && SlitDoorData.CloseFeedback; } } public bool EnableRfTimeSetPoint { get { return IsManualMode; } } //public bool IsEnableCloseLid //{ // get // { // return !ChamberDoorLid.IsClose && !IsAutoMode; // } //} public bool IsLeftTcAsControlTc { get { return true;//SCLocal.CoolingConfig.EnableElectrodeTcLeftAsControlTc; } } public bool IsRightTcAsControlTc { get { return !IsLeftTcAsControlTc; } } public bool IsEnableRecipeScan { get { return IsAutoMode && !IsProcessing; } } public bool IsEnableLotScan { get { return IsAutoMode && !IsProcessing; } } public bool IsEnableSelectRecipe { get { return IsAutoMode && !IsProcessing; } } public bool IsEnableStartRecipe { get { return IsAutoMode && !string.IsNullOrEmpty(SelectedRecipeName) && !IsProcessing; } } public bool IsEnableNextStep { get { return IsAutoMode && IsProcessing; } } public bool IsEnableStopRecipe { get { return IsAutoMode && IsProcessing; } } public bool IsBarcodeEnabled { get; set; } public bool IsRfPowerOn { get { return Rf != null && Rf.IsRfOn; } } public bool IsBiasRfPowerOn { get { return RfBias != null && RfBias.IsRfOn; } } public bool IsBiasMatchPowerOn { get { return RfBias != null && RfBias.IsRfOn && RfBias.IsMatchOn; } } public bool IsBiasRfVisible { get { return (bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.BiasRf.EnableBiasRF"); } } public bool IsBiasMatchVisible { get { return (bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.BiasMatch.EnableBiasMatch"); } } public bool IsChillerVisibility { get { return (bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Chiller.EnableChiller"); } } public bool IsHeaterVisibility { get { return !IsChillerVisibility; } } public bool IsMatchPositionInputEnabled { get { if (Rf != null && RfMatchProcessModeSetPoint != "Preset") return false; return IsManualMode; } } public bool IsChillerEnable { get { if (SystemName == "PMB") { if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Chiller.ChillerSameWithPMA")) { return false; } else { return (bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Chiller.EnableChiller"); } } else { return (bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Chiller.EnableChiller"); } } } public bool IsHeaterEnable { get { return IsHeaterVisibility; } } public bool SensorValue { get { return false; } } public bool IsManualButtonEnabled { get { return IsAutoMode; } } public bool IsAutoButtonEnabled { get { return !IsAutoMode; } } public bool IsPumping { get { return (PMState)PMStatus == PMState.Pumping; } } public bool IsStartPumping { get { return (PMState)PMStatus == PMState.LaunchingPump; } } public bool enableServiceControl { get { return Permission == 3; } } public string RecipeStepNoDisplay { get { return (PMState)PMStatus == PMState.Processing ? RecipeStepNo.ToString() : "--"; } } public string RecipeStepModeDisplay { get { if ((PMState)PMStatus != PMState.Processing) return "--"; switch (RecipeStepMode) { //case (int)EndByCondition.EndByHeatUp: // return "Heat Up Mode"; //case (int)EndByCondition.EndByRfTime: // return "RF Time Mode"; default: return "Step Time Mode"; } } } private string _pumpButtonBackground = "#376092"; public string PumpButtonBackground { get { if (IsPumping) { _pumpButtonBackground = _pumpButtonBackground == "#95B3D7" ? "Blue" : "#95B3D7"; return _pumpButtonBackground; } if (IsPumpingOkForProcess) return "#00C900"; return "#376092"; } } public bool IsGasFlowing { get { return (PMState)PMStatus == PMState.GasFlowing; } } private string _gasFlowButtonBackground = "CadetBlue"; public string GasFlowButtonBackground { get { if (IsGasFlowing) { _gasFlowButtonBackground = _gasFlowButtonBackground == "#95B3D7" ? "Blue" : "#95B3D7"; return _gasFlowButtonBackground; } if (IsGasFlowingOkForProcess) return "#00C900"; return "CadetBlue"; } } public bool IsCooling { get { return true;//ElectrodeCoolingWaterValve!=null && ElectrodeCoolingWaterValve.IsOpen; } } private string _coolingButtonBackground = "CadetBlue"; public string CoolingButtonBackground { get { if (IsCooling) { _coolingButtonBackground = _coolingButtonBackground == "#95B3D7" ? "Blue" : "#95B3D7"; return _coolingButtonBackground; } if (IsCoolingOkForProcess) return "#00C900"; return "CadetBlue"; } } public bool IsRfPowering { get { return (PMState)PMStatus == PMState.RfPowering; } } public bool IsLeakCheck { get { return (PMState)PMStatus == PMState.LeakCheck; } } private string _rfPowerButtonBackground = "CadetBlue"; public string RfPowerButtonBackground { get { if (IsRfPowering) { _rfPowerButtonBackground = _rfPowerButtonBackground == "#95B3D7" ? "Blue" : "#95B3D7"; return _rfPowerButtonBackground; } return "CadetBlue"; } } public bool IsCyclePurging => (PMState)PMStatus == PMState.Purge; private string _cyclePurgeButtonBackground = "CadetBlue"; public string CyclePurgeButtonBackground { get { if (IsCyclePurging) { _cyclePurgeButtonBackground = _cyclePurgeButtonBackground == "#95B3D7" ? "Blue" : "#95B3D7"; return _cyclePurgeButtonBackground; } return "CadetBlue"; } } public bool IsVenting { get { return (PMState)PMStatus == PMState.Venting; } } private string _ventButtonBackground = "CadetBlue"; public string VentButtonBackground { get { if (IsVenting) { _ventButtonBackground = _ventButtonBackground == "#95B3D7" ? "Blue" : "#95B3D7"; return _ventButtonBackground; } return "CadetBlue"; } } public bool IsProcessing { get { return (PMState)PMStatus == PMState.PreProcess || (PMState)PMStatus == PMState.Processing || (PMState)PMStatus == PMState.PostProcess; } } public Visibility RfPowerOnChamberVisibility { get { return IsRfPowerOn ? Visibility.Visible : Visibility.Hidden; } } public Visibility BiasRfPowerOnChamberVisibility { get { if (!IsBiasRfVisible) return RfPowerOnChamberVisibility; return IsBiasRfPowerOn ? Visibility.Visible : Visibility.Hidden; } } public Visibility BoostPumpVisibility { get; set; } public bool IsRfPowerOnEnabled { get { return !IsRfPowerOn; } } public bool IsRfPowerOffEnabled { get { return IsRfPowerOn; } } public string ChamberStatus { get { return $"{(PMState)PMStatus}"; } } public Brush ChamberStatusBkColor { get { switch ((PMState)PMStatus) { case PMState.Error: return Brushes.Red; case PMState.Idle: return Brushes.LightGray; default: return Brushes.LightGreen; } //return Brushes.Transparent; } } public Brush ChamberStatusForeColor { get { if (true) return Brushes.Black; //else if (false) // return Brushes.LightGreen; //return Brushes.Red; } } public Brush PMOnlineColor { get { if (IsOnline) return Brushes.LimeGreen; return Brushes.Transparent; } } public double RfReflectPower { get; set; } public double RfForwardPower { get; set; } public object[] RfPowerOnCommandParameter { get { return new object[] { VirgoDevice.Rf.ToString(), AITRfOperation.SetPowerOnOff.ToString(), "true" }; } } public object[] RfPowerOffCommandParameter { get { return new object[] { VirgoDevice.Rf.ToString(), AITRfOperation.SetPowerOnOff.ToString(), "false" }; } } public double LotBarcodeHeight { get { return IsBarcodeEnabled ? 35 : 0; } } public double DataLogHeight { get { return IsBarcodeEnabled ? 0 : 35; } } public double RecipeBarcodeHeight { get { return IsBarcodeEnabled ? 35 : 0; } } public string RecipeBarcodeInputText { get; set; } public int RecipeBarcodeLength { get; set; } public int LotBarcodeLength { get; set; } public int LotBarcodeMaxCount { get; set; } [IgnorePropertyChange] public string BasePressureSetPoint { get; set; } [IgnorePropertyChange] public string PumpLimitSetPoint { get; set; } [IgnorePropertyChange] public string ManualProcessElectrodeCriticalTemperatureSetPoint { get; set; } private string _stepModeSetPoint = ""; [IgnorePropertyChange] public string StepModeSetPoint { get { return _stepModeSetPoint; } set { _stepModeSetPoint = value; } } [IgnorePropertyChange] public string ElectrodeTemperatureSetPoint { get; set; } [IgnorePropertyChange] public string ThrottleValveModeSetPoint { get; set; } [IgnorePropertyChange] public string ThrottleValvePositionSetPoint { get; set; } [IgnorePropertyChange] public string ThrottleValvePressureSetPoint { get; set; } [IgnorePropertyChange] public string BoostPumpPressureSetPoint { get; set; } [IgnorePropertyChange] public string RfTimeSetPoint { get; set; } private string _rfModeSetPoint; [IgnorePropertyChange] public string RfModeSetPoint { get { return _rfModeSetPoint; } set { _rfModeSetPoint = value; } } [IgnorePropertyChange] public string RfFrequencySetPoint { get; set; } [IgnorePropertyChange] public string RfDutySetPoint { get; set; } [IgnorePropertyChange] public string RfMatchProcessModeSetPoint { get; set; } [IgnorePropertyChange] public string RfMatchPositionC1SetPoint { get; set; } [IgnorePropertyChange] public string RfMatchPositionC2SetPoint { get; set; } private string _selectedRecipeName; [Subscription("RecipeName")] public string SelectedRecipeName { get { return _selectedRecipeName; } set { if (string.IsNullOrEmpty(value)) return; _selectedRecipeName = value; if (IsAutoMode) { InvokePropertyChanged("SelectedRecipeName"); } } } [Subscription("ProcessStatus")] public string ProcessStatus { get; set; } [Subscription("RecipeStepTimeElapsed")] public string RecipeStepTimeElapsed { get; set; } [Subscription("RecipeStepTimeSetPoint")] public string RecipeStepTimeSetPoint { get; set; } [Subscription("RecipeSteps")] public string RecipeSteps { get; set; } private string _recipeStepRfTimeSetPoint; [Subscription("RecipeStepRfTimeSetPoint")] public string RecipeStepRfTimeSetPoint { get { return _recipeStepRfTimeSetPoint; } set { _recipeStepRfTimeSetPoint = value; if (IsAutoMode) { RfTimeSetPoint = _recipeStepRfTimeSetPoint; InvokePropertyChanged("RfTimeSetPoint"); } } } //public string RecipeStatusBackground //{ // get // { // return IsProcessing ? "Green" : "Blue"; // } //} public ObservableCollection RFModeItems { get; set; } public bool IsRFModeSelectable { get; set; } public bool IsFullControlPermission { get; set; } public bool EnableDeviceControl { get { return IsFullControlPermission; } } public Visibility WallHeaterVisibility { get; set; } public Visibility GridHeaterVisibility { get; set; } public Ax.WaferSize SmallPinWaferSize { get; set; } public Ax.WaferSize MediumPinWaferSize { get; set; } public Ax.WaferSize BigPinWaferSize { get; set; } public string SmallPinUpText { get; set; } public string SmallPinDownText { get; set; } public string MediumPinUpText { get; set; } public string MediumPinDownText { get; set; } public int SmallPinHeight { get; set; } public int MediumPinHeight { get; set; } private int MenuPermission; private bool _smallGuidePinEnable; private bool _mediumGuidePinEnable; public PmOverviewViewModel() { BasePressureSetPointSaved = true; PumpLimitSetPointSaved = true; } protected override void OnActivate() { base.OnActivate(); BasePressureSetPoint = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Pump.PumpBasePressure").ToString(); PumpLimitSetPoint = ((float)(double)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.Pump.PumpTimeLimit")).ToString(); SmallPinWaferSize = MapWaferSize((int)QueryDataClient.Instance.Service.GetConfig($"System.SmallWafer")); MediumPinWaferSize = MapWaferSize((int)QueryDataClient.Instance.Service.GetConfig($"System.MidWafer")); BigPinWaferSize = MapWaferSize((int)QueryDataClient.Instance.Service.GetConfig($"System.BigWafer")); SmallPinUpText = $"{SmallPinWaferSize} Pin Up"; SmallPinDownText = $"{SmallPinWaferSize} Pin Down"; MediumPinUpText = $"{MediumPinWaferSize} Pin Up"; MediumPinDownText = $"{MediumPinWaferSize} Pin Down"; SmallPinHeight = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.SupportedGuidePinSize").ToString().Split(',').Contains(SmallPinWaferSize.ToString().Replace("WS","")) ? 32 : 0; MediumPinHeight = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.SupportedGuidePinSize").ToString().Split(',').Contains(MediumPinWaferSize.ToString().Replace("WS", "")) ? 32 : 0; WallHeaterVisibility = ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.EnableWallHeater")) ? Visibility.Visible: Visibility.Hidden; GridHeaterVisibility = ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.EnableGridHeater")) ? Visibility.Visible : Visibility.Hidden; EPDVisibility = (bool) QueryDataClient.Instance.Service.GetConfig($"System.SetUp.EPDInstalled") && (bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.EPD.IsEnabled") ? Visibility.Visible : Visibility.Hidden; } private Ax.WaferSize MapWaferSize(int value) { switch (value) { case 3: return Ax.WaferSize.WS3; case 4: return Ax.WaferSize.WS4; case 6: return Ax.WaferSize.WS6; case 8: return Ax.WaferSize.WS8; case 12: return Ax.WaferSize.WS12; case 150: return Ax.WaferSize.WS150; case 159: return Ax.WaferSize.WS159; } return Ax.WaferSize.WS0; } protected override void OnDeactivate(bool close) { base.OnDeactivate(close); } protected override void OnInitialize() { base.OnInitialize(); InitGasLine(); InitParameterList(SystemName); foreach (var pmParameter in PMParameters) { Subscribe(pmParameter.Name); } _smallGuidePinEnable = (bool)QueryDataClient.Instance.Service.GetConfig($"System.SmallGuidePinEnable"); _mediumGuidePinEnable = (bool)QueryDataClient.Instance.Service.GetConfig($"System.MediumGuidePinEnable"); } private void InitGasLine() { Gaslines = new List(); for (int i = 1; i <= 5; i++) //GasLine 跳号Enable { if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{i}.Enable")) { var gasName = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{i}.GasName"); var gasscale = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{i}.MfcN2Scale"); Gaslines.Add(new GaslineItem { Index = (byte)i, Display = $"MfcGas{i} " + gasName.ToString() + " " +gasscale.ToString() + " sccm", ValveName = $"{SystemName}.ValveMfc{i}", MfcName = $"{SystemName}.MfcGas{i}" }); } } //int count = 0; //for (int i = 1; i <= 5; i++) //{ // if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{i}.Enable")) count++; //} //for (byte index = 1; index <= count; index++) //{ // var gasName = QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{index}.GasName"); // Gaslines.Add(new GaslineItem // { // Index = index, // Display = gasName.ToString(), // ValveName = $"{SystemName}.ValveMfc{index}", // MfcName = $"{SystemName}.MfcGas{index}" // }); //} } public List InitParameterList(string pmID) { PMParameters = new List(); // 工艺时间 PMParameters.Add(new PMParameter { Name = $"{pmID}.RecipeProcessTime", Display = "工艺总时间 (s)", Type = ParameterType.Share, Feedback = "00:00:00" }); // 工艺步数 PMParameters.Add(new PMParameter { Name = $"{pmID}.StepNo", Display = "工艺步数", Type = ParameterType.Share, Feedback = "0", Setpoint = "" }); // 工艺每一步运行时间 PMParameters.Add(new PMParameter { Name = $"{pmID}.RecipeStepTimeElapsed", Display = "当前步时间 (s)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = false }); // process gauge PMParameters.Add(new PMParameter { Name = $"{pmID}.ProcessGauge.Value", Display = "工艺压力(mTorr)", Type = ParameterType.Share, Feedback = "0", SetpointEnabled = false }); // pressure gauge //PMParameters.Add(new PMParameter //{ // Name = $"{pmID}.PressureGauge.Value", Display = "腔体压力(mTorr)", // Type = ParameterType.Share, Feedback = "0", SetpointEnabled = false //}); // foreline gauge // 蝶阀运作模式 PMParameters.Add(new PMParameter { Name = $"{pmID}.IoThrottleValve.ThrottleValve.TVMode", Display = "蝶阀运行模式", Type = ParameterType.DropDownList, SetpointEnabled = true, Selections = new List { "Position", "Pressure" }, Setpoint = "Pressure", Feedback = "Pressure" }); // 蝶阀位置 PMParameters.Add(new PMParameter { Name = $"{pmID}.IoThrottleValve.ThrottleValve.TVPosition", Display = "蝶阀位置 (%)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = true }); // 蝶阀压力 PMParameters.Add(new PMParameter { Name = $"{pmID}.IoThrottleValve.ThrottleValve.TVPressure", Display = "蝶阀压力 (mTorr)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = true }); // 底座温度 PMParameters.Add(new PMParameter { Name = $"{pmID}.IoTemperatureCtrl.TemperatureControl.SubstrateTemperature", Display = HeaterButtonContent=="底座加热"?"底座温度 (℃)": "水冷温度(℃)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = true }); // 射频时间 PMParameters.Add(new PMParameter { Name = $"{pmID}.Rf.PowerOnTime", Display = "射频时间 (s)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = true }); //para = new PMParameter() { Display = "RF Mode", Type = ParameterType.DropDownList, Feedback = "Manual", SetpointEnabled = true }; //para.Selections = new List() { "Manual", "Auto" }; //paras.Add(para); // 设定功率 PMParameters.Add(new PMParameter { Name = $"{pmID}.Rf.ForwardPower", Display = "源射频功率 (w)", Type = ParameterType.Default, Feedback = "", Setpoint = "", SetpointEnabled = true }); // ReflectPower PMParameters.Add(new PMParameter { Name = $"{pmID}.Rf.ReflectPower", Display = "源反射功率 (w)", Type = ParameterType.Share, Setpoint = "" }); //// Match C1 //PMParameters.Add(new PMParameter //{ // Name =$"{pmID}.Match.TunePosition1", Display = "Match C1 (%)", Type = ParameterType.Default, Feedback = "", Setpoint = "", // SetpointEnabled = true //}); //// Match C2 //PMParameters.Add(new PMParameter //{ // Name = $"{pmID}.Match.TunePosition2", Display = "Match C2 (%)", Type = ParameterType.Default, Feedback = "", Setpoint = "", // SetpointEnabled = true //}); // Match C1 PMParameters.Add(new PMParameter() { Name = $"{pmID}.match.TunePosition1", Display = "源射频匹配 C1 (%)", Type = ParameterType.Share, Setpoint = "" }); // Match C2 PMParameters.Add(new PMParameter() { Name = $"{pmID}.match.TunePosition2", Display = "源射频匹配 C2 (%)", Type = ParameterType.Share, Setpoint = "" }); // Vpp PMParameters.Add(new PMParameter() { Name = $"{pmID}.Match.VPP", Display = "源射频Vpp", Type = ParameterType.Share, Setpoint = "" }); if ((bool)QueryDataClient.Instance.Service.GetConfig($"{pmID}.BiasRf.EnableBiasRF")) { // 设定功率 PMParameters.Add(new PMParameter { Name = $"{pmID}.BiasRf.ForwardPower", Display = "偏压射频功率 (w)", Type = ParameterType.Default, Feedback = "", Setpoint = "", SetpointEnabled = true }); // ReflectPower PMParameters.Add(new PMParameter { Name = $"{pmID}.BiasRf.ReflectPower", Display = "偏压反射功率 (w)", Type = ParameterType.Share, Setpoint = "" }); // Match Mode PMParameters.Add(new PMParameter { Name = $"{pmID}.BiasMatch.MatchProcessMode", Display = "偏压射频匹配器模式", Type = ParameterType.DropDownList, SetpointEnabled = true, Selections = new List { "Preset", "Hold" }, Setpoint = "Preset", Feedback = "Preset" }); // Match C1 PMParameters.Add(new PMParameter { Name = $"{pmID}.BiasMatch.C1", Display = "偏压射频匹配 C1 (%)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = true }); // Match C2 PMParameters.Add(new PMParameter { Name = $"{pmID}.BiasMatch.C2", Display = "偏压射频匹配 C2 (%)", Type = ParameterType.Default, Feedback = "0", Setpoint = "", SetpointEnabled = true }); // Vpp PMParameters.Add(new PMParameter() { Name = $"{pmID}.BiasMatch.VPP", Display = "偏压射频Vpp", Type = ParameterType.Share, Setpoint = "" }); } // 气体 foreach (var gas in Gaslines) { PMParameters.Add(new PMParameter { Name = $"{pmID}.IoMfc.MfcGas{gas.Index}.FeedBack", Display = $"{gas.Display} (sccm)", Type = ParameterType.Default, Feedback = "0", Setpoint = "0", SetpointEnabled = true }); } return PMParameters; } public void SelectRecipe() { if (MenuPermission != 3) return; if (!Enum.TryParse(SystemName, out ModuleName mod)) return; RecipeSequenceSelectDialogViewModel dialog = new RecipeSequenceSelectDialogViewModel(); dialog.DisplayName = "Select Recipe"; dialog.Files = new ObservableCollection(RecipeSequenceTreeBuilder.GetFiles(RecipeClient.Instance.Service.GetRecipes(mod, false).ToList())); WindowManager wm = new WindowManager(); bool? bret = wm.ShowDialog(dialog); if ((bool)bret) { SelectedRecipeName = dialog.DialogResult; } } public void UnLoad() { } public void Start() { if (MenuPermission != 3) return; if (string.IsNullOrWhiteSpace(this.SelectedRecipeName)) { DialogBox.ShowError("请选择工艺程序文件"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.RunRecipe}", $"{SystemName}\\{this.SelectedRecipeName}"); } public void NextStep() { if (MenuPermission != 3) return; if (MessageBox.Show("跳至下一步工艺?", "JetPlasma", MessageBoxButton.YesNo) == MessageBoxResult.Yes) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.SkipCurrentStep}"); } } public void Stop() { if (MenuPermission != 3) return; if (MessageBox.Show("停止当前工艺?", "JetPlasma", MessageBoxButton.YesNo) == MessageBoxResult.Yes) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.AbortRecipe}"); } } public void SetManual() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.PmManual"); } public void SetAuto() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.PmAuto"); } public void SetOnline() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.PmOnline"); } public void SetInit() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.Home"); } public void AbortPM() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.Abort"); } public void SetOffline() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.PmOffline"); } public void UnlockLid() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.UnlockLid"); } public void LockLid() { if (MenuPermission != 3) return; InvokeClient.Instance.Service.DoOperation($"{SystemName}.LockLid"); } public void OpenSlitValve() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } if (!IsArmNotExtend) { DialogBox.ShowWarning("Arm Is Not Extend Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.SlitDoor.Open"); } public void CloseSlitValve() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } if (!IsArmNotExtend) { DialogBox.ShowWarning("Arm Is Not Extend Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.SlitDoor.Close"); } protected override void InvokeAfterUpdateProperty(Dictionary data) { MenuPermission = ClientApp.Instance.GetPermission($"Overview{SystemName}"); foreach (var pmParameter in PMParameters) { string paraName = pmParameter.Name; if (!data.ContainsKey(paraName)) continue; pmParameter.Feedback = $"{data[paraName]:N0}"; if (paraName == $"{SystemName}.BiasMatch.MatchProcessMode") { pmParameter.Feedback = (int)data[paraName] == 1 ? "Preset" : "Hold"; } if (paraName == $"{SystemName}.BiasMatch.C1") { pmParameter.Feedback = $"{data[paraName]:N1}"; } if (paraName == $"{SystemName}.BiasMatch.C2") { pmParameter.Feedback = $"{data[paraName]:N1}"; } if (paraName == $"{SystemName}.ProcessGauge.Value") { pmParameter.Feedback = $"{data[paraName]:N1}"; } if (paraName == $"{SystemName}.IoThrottleValve.ThrottleValve.TVMode") { pmParameter.Feedback = pmParameter.Setpoint; } if (paraName == $"{SystemName}.IoThrottleValve.ThrottleValve.TVPressure") { if (Convert.ToDouble(data[paraName]) <= 0.0) { pmParameter.Feedback = "0.0"; } else { pmParameter.Feedback = $"{(Convert.ToDouble(data[paraName]) + ProcessPressureOffset):N1}"; } } if (paraName == $"{SystemName}.Rf.PowerOnTime") { pmParameter.Feedback = $"{data[$"{SystemName}.Rf.PowerOnTime"]}"; } if (paraName == $"{SystemName}.Match.TunePosition1"|| paraName == $"{SystemName}.Match.TunePosition2") { pmParameter.Feedback = $"{data[paraName]:N2}"; } if (paraName == $"{SystemName}.StepTime") { pmParameter.Feedback = $"{data[$"{SystemName}.RecipeStepTimeElapsed"]:N0}"; pmParameter.Setpoint = $"{data[$"{SystemName}.RecipeStepTimeSetPoint"]:N0}"; } if (paraName == $"{SystemName}.StepNo") { pmParameter.Setpoint = $"{data[$"{SystemName}.RecipeSteps"]:N0}"; } if (paraName == $"{SystemName}.RecipeStepTimeElapsed") { pmParameter.Setpoint = $"{data[$"{SystemName}.RecipeStepTimeSetPoint"]:N0}"; } if (paraName == ($"{SystemName}.IoTemperatureCtrl.TemperatureControl.SubstrateTemperature")) { if(IsAutoMode) { pmParameter.Setpoint = string.Format("{0:N1}", ((AITHeaterData)data[$"{SystemName}.HeaterChamber.DeviceData"]).SetPoint); } pmParameter.Feedback = string.Format("{0:N1}", ((AITHeaterData)data[$"{SystemName}.HeaterChamber.DeviceData"]).FeedBack); } } foreach (var gasLine in Gaslines) { if (data.ContainsKey(gasLine.ValveName)) { gasLine.ValveData = (AITValveData)data[gasLine.ValveName]; gasLine.NotifyOfPropertyChange("ValveData"); } if (data.ContainsKey(gasLine.MfcName)) { gasLine.MfcData = (AITMfcData)data[gasLine.MfcName]; gasLine.Display = gasLine.MfcData.DeviceName + " " + $"({gasLine.MfcData.DisplayName})" + " " + gasLine.MfcData.Scale + " " + gasLine.MfcData.Unit; PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas{gasLine.Index}.FeedBack").Display = gasLine.Display; PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas{gasLine.Index}.FeedBack").NotifyOfPropertyChange("Display"); gasLine.NotifyOfPropertyChange("MfcData"); } } //if (PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.MatchProcessMode").Setpoint == "Hold") //{ // PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.C1").Setpoint = ""; // PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.C2").Setpoint = ""; //} } public void DoStartPump() { if (MenuPermission != 3) return; if (IsStartPumping) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.Abort}"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.StartPump"); } // Pumpdown public void DoPump() { if (MenuPermission != 3) return; if (IsPumping) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.Abort}"); return; } if (IsPumpingOkForProcess) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.StopPump"); return; } // 设置底压 double basePressure = string.IsNullOrEmpty(BasePressureSetPoint) ? 0 : Convert.ToDouble(BasePressureSetPoint); if (basePressure <= 0.01 || basePressure >= 1000) { MessageBox.Show($"基准压力设定值 {basePressure} 无效,应该在0到1000毫托之间"); return; } double pumpLimit = string.IsNullOrEmpty(PumpLimitSetPoint) ? 0 : Convert.ToDouble(PumpLimitSetPoint); if (pumpLimit <= 0.01 || pumpLimit >= 1200) { MessageBox.Show($"抽气时间应该在0到1200之间,当前设定值{pumpLimit}"); return; } InvokeClient.Instance.Service.DoOperation("System.SetConfig", $"{SystemName}.Pump.PumpBasePressure", basePressure.ToString()); InvokeClient.Instance.Service.DoOperation("System.SetConfig", $"{SystemName}.Pump.PumpTimeLimit", pumpLimit.ToString()); InvokeClient.Instance.Service.DoOperation($"{SystemName}.Pump"); // pump down 过程中tv 全开 var tvMode = PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVMode"); tvMode.Feedback = "Position"; PumpLimitSetPointSaved = true; BasePressureSetPointSaved = true; NotifyOfPropertyChange(nameof(PumpLimitSetPointSaved)); NotifyOfPropertyChange(nameof(BasePressureSetPointSaved)); } private void MoveGuidePin(MovementPosition pos) { switch (pos) { case MovementPosition.Down: BottomPinStatus = 1; TopPinStatus = 0; MidPinStatus = 0; break; case MovementPosition.Up: BottomPinStatus = 0; TopPinStatus = 1; MidPinStatus = 0; break; case MovementPosition.Middle: BottomPinStatus = 0; TopPinStatus = 0; MidPinStatus = 1; break; default: break; } } public void Purge() { if (MenuPermission != 3) return; if (IsCyclePurging) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.StopPurge"); } else { InvokeClient.Instance.Service.DoOperation($"{SystemName}.Purge"); } } public void LeakCheck() { if (!IsLeakCheck) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.LeakCheck"); } } public void Vent() { if (MenuPermission != 3) return; //OverviewPMProvider.Instance.Vent("PM1"); if (!IsVenting) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.Vent"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.Abort}"); } /// /// 流气 /// public void Gas() { if (MenuPermission != 3) return; if (!this.HandleThrottleValve()) return; //GasLine 跳号Enable object[] mfc = new object[5]; string[] mfcSetPoint = new string[5]; for (int i = 0; i < 5; i++) { if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.MfcGas{i + 1}.Enable")) { mfcSetPoint[i] = PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas{i + 1}.FeedBack").Setpoint; if (string.IsNullOrWhiteSpace(mfcSetPoint[i])) { DialogBox.ShowError("请输入气体流量值"); return; } } mfc[i] = Convert.ToDouble(string.IsNullOrEmpty(mfcSetPoint[i]) ? "0.0" : mfcSetPoint[i]); } //object[] mfc = new object[Gaslines.Count]; //string[] mfcSetPoint = new string[Gaslines.Count]; //for (int index = 0; index < Gaslines.Count; index++) //{ // mfcSetPoint[index] = PMParameters.Find(x => x.Name == $"{SystemName}.IoMfc.MfcGas{index + 1}.FeedBack").Setpoint; // if (string.IsNullOrWhiteSpace(mfcSetPoint[index])) // { // DialogBox.ShowError("请输入气体流量值"); // return; // } // mfc[index] = Convert.ToDouble(string.IsNullOrEmpty(mfcSetPoint[index]) ? "0.0" : mfcSetPoint[index]); //} if ((IsGasFlowing && (Math.Abs((double)mfc[0] - (double)_oldmfc[0]) < 0.01) && (Math.Abs((double)mfc[1] - (double)_oldmfc[1]) < 0.01) && (Math.Abs((double)mfc[2] - (double)_oldmfc[2])) < 0.01) || (IsGasFlowing && (Math.Abs((double)mfc[0]) <= 0.01 && Math.Abs((double)mfc[1]) <= 0.01 && Math.Abs((double)mfc[2]) <= 0.01))) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.Abort}"); return; } _oldmfc = mfc; InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.GasFlow}", mfc); } /// /// 处理蝶阀 /// /// private bool HandleThrottleValve() { var tvMode = PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVMode"); string tvModeSp = "TV" + tvMode.Setpoint + "Ctrl"; if (!Enum.TryParse(tvModeSp, out PressureCtrlMode ctrlMode)) { MessageBox.Show("Select the mode of Throttle valve"); return false; } switch (ctrlMode) { case PressureCtrlMode.TVPressureCtrl: string tvPressureSP = PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVPressure").Setpoint; if (string.IsNullOrWhiteSpace(tvPressureSP)) { DialogBox.ShowError("请输入蝶阀 pressure value"); return false; } double pressure = Convert.ToDouble(tvPressureSP); if (pressure < 0 || pressure > 756000) { DialogBox.ShowError($"压力设定值 {pressure} 无效,应该介于0到756000之间"); return false; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{VirgoDevice.ThrottleValve}.{AITThrottleValveOperation.SetPressure}", pressure); break; case PressureCtrlMode.TVPositionCtrl: string tvPositionSP = PMParameters.Find(x => x.Name == $"{SystemName}.IoThrottleValve.ThrottleValve.TVPosition").Setpoint; if (string.IsNullOrWhiteSpace(tvPositionSP)) { DialogBox.ShowError("请输入蝶阀 Position value"); return false; } double position = Convert.ToDouble(tvPositionSP); if (position < 0 || position > 100) { DialogBox.ShowError($"蝶阀位置 {position} 无效,应该在0到100之间"); return false; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{VirgoDevice.ThrottleValve}.{AITThrottleValveOperation.SetPosition}", position); break; default: break; } tvMode.Feedback = tvMode.Setpoint; return true; } public void Heat() { var para_temp = PMParameters.Find(x => x.Name == $"{SystemName}.IoTemperatureCtrl.TemperatureControl.SubstrateTemperature"); var temp = para_temp.Setpoint; if (double.TryParse(temp, out double dt)) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.Heat}", dt); } else { DialogBox.ShowError("设定温度无效"); } } // RF Power public void RF() { if (MenuPermission != 3) return; double rf_sp = 0; double rf_sp_bias = 0; double match1_sp = 0.0f; double match2_sp = 0.0f; double rf_time = 0; string rfPowerSetPointBias = ""; BiasRfMatchMode matchMode = BiasRfMatchMode.Preset; if (IsRfPowering) { InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.Abort}"); return; } // 源射频功率 string rfPowerSetPoint = PMParameters.Find(x => x.Name == $"{SystemName}.Rf.ForwardPower").Setpoint; if (string.IsNullOrWhiteSpace(rfPowerSetPoint)) { DialogBox.ShowWarning("Input RF power set value first"); return; } // 源射频时间 string sRFTime = PMParameters.Find(x => x.Name == $"{SystemName}.Rf.PowerOnTime").Setpoint; if (string.IsNullOrWhiteSpace(sRFTime)) { DialogBox.ShowError("Input RF power time"); return; } // 偏压射频功率 if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.BiasRf.EnableBiasRF")) { rfPowerSetPointBias = PMParameters.Find(x => x.Name == $"{SystemName}.BiasRf.ForwardPower").Setpoint; if (string.IsNullOrWhiteSpace(rfPowerSetPointBias)) { DialogBox.ShowWarning("Input Bias RF power set value first"); return; } rf_sp_bias = Convert.ToDouble(rfPowerSetPointBias); if ((bool)QueryDataClient.Instance.Service.GetConfig($"{SystemName}.BiasMatch.EnableBiasMatch")) { var MatchMode = PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.MatchProcessMode"); if (!Enum.TryParse(MatchMode.Setpoint, out matchMode)) { MessageBox.Show("Select the mode of Throttle valve"); return; } if (matchMode == BiasRfMatchMode.Preset) { PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.MatchProcessMode").Feedback = "Preset"; // Match C1 string rfMatchC1SetPoint = PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.C1").Setpoint; if (string.IsNullOrWhiteSpace(rfMatchC1SetPoint)) { DialogBox.ShowWarning("Input Match C1 set value first"); return; } // Match C2 string rfMatchC2SetPoint = PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.C2").Setpoint; if (string.IsNullOrWhiteSpace(rfMatchC2SetPoint)) { DialogBox.ShowWarning("Input Match C2 set value first"); return; } match1_sp = Convert.ToDouble(rfMatchC1SetPoint); match2_sp = Convert.ToDouble(rfMatchC2SetPoint); } else if (matchMode == BiasRfMatchMode.Hold) { //PMParameters.Find(x => x.Name == $"{SystemName}.BiasMatch.MatchProcessMode").Feedback = "Hold"; } } } rf_sp = Convert.ToDouble(rfPowerSetPoint); rf_time = Convert.ToDouble(sRFTime); InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.RfPower}", rf_sp, rf_sp_bias, rf_time, (int)matchMode, match1_sp, match2_sp); } // Lift pin method public void MoveLiftPinUp() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.LiftPin.Open"); } public void MoveLiftPinDown() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.LiftPin.Close"); } // Guide pin method public void MovePin3Up() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.MoveGuidePin}", WaferSize.WS3, 2); } public void MovePin3Down() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.MoveGuidePin}", WaferSize.WS3, 1); } public void MovePin4Up() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.MoveGuidePin}", WaferSize.WS4, 2); } public void MovePin4Down() { if (MenuPermission != 3) return; if (!IsCDAOK) { DialogBox.ShowWarning("CDA Pressure Error"); return; } InvokeClient.Instance.Service.DoOperation($"{SystemName}.{RtOperation.MoveGuidePin}", WaferSize.WS4, 1); } } }