using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Device.Bases; using MECF.Framework.Common.Equipment; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs; using System; using IoMfc = Venus_RT.Devices.IODevices.IoMfc; using IoPressureMeter = Venus_RT.Devices.IODevices.IoPressureMeter; using Venus_Core; using Venus_RT.Modules; namespace Venus_RT.Devices { public class HongHuTM : TM { /// /// 针对VenusSE设计 /// #region io 信号抽象 //控制阀信号 private readonly IoValve _TMFastPumpValve; private readonly IoValve _TMSoftPumpValve; private readonly IoValve _VCESoftPumpValve; private readonly IoValve _VCEFastPumpValve; private readonly IoValve _TMFastVentValve; private readonly IoValve _TMSoftVentValve; private readonly IoValve _VCESoftVentValve; private readonly IoValve _VCEFastVentValve; //判断信号 private readonly IoSensor _VCESlitDoorOpen; private readonly IoSensor _PMASlitDoorOpen; private readonly IoSensor _PMBSlitDoorOpen; private readonly IoSensor _PMCSlitDoorOpen; private readonly IoSensor _VCESlitDoorOpenEnable; private readonly IoSensor _PMASlitDoorOpenEnable; private readonly IoSensor _PMBSlitDoorOpenEnable; private readonly IoSensor _PMCSlitDoorOpenEnable; private readonly IoSensor _TMExtendVCEEnable; private readonly IoSensor _TMExtendPMAEnable; private readonly IoSensor _TMExtendPMBEnable; private readonly IoSensor _TMExtendPMCEnable; private readonly IoSensor _TMVACSensor; private readonly IoSensor _VCEVACSensor; //控制门信号 private readonly IoCylinder _VCESlitDoor; private readonly IoCylinder _PMASlitDoor; private readonly IoCylinder _PMBSlitDoor; private readonly IoCylinder _PMCSlitDoor; private readonly IoMfc _TMMfc; private readonly IoPressureMeter _TMPressure; private readonly IoPressureMeter _TMPiplinePressure; private readonly IoPressureMeter _VCEPressure; private readonly IoPressureMeter _VCEPiplinePressure; private readonly PumpBase _TMPump; //控压 //安装的module private string _allInstalledModules { get { return SC.GetStringValue("System.InstalledModules").ToString(); } } #endregion #region 暴露变量 //ATM VAC信号 public bool IsTMATM => _TMPressure.Value >= SC.GetValue($"{Module}.ATMTargetPressure"); public bool IsVCEATM => _VCEPressure.Value >= SC.GetValue("VCE1.ATMTargetPressure"); public bool IsTMVAC => _TMVACSensor.Value; public bool IsVCEVAC => _VCEVACSensor.Value; public bool? IsTMPumpRunning => _TMPump?.IsRunning; //valve开关状态 public bool IsTMFastPumpOpen => _TMFastPumpValve.Status; public bool IsTMSoftPumpOpen => _TMSoftPumpValve.Status; public bool IsTMFastVentOpen => _TMFastVentValve.Status; public bool IsTMSoftVentOpen => _TMSoftVentValve.Status; public bool IsVCEFastPumpOpen => _VCEFastPumpValve.Status; public bool IsVCESoftPumpOpen => _VCESoftPumpValve.Status; public bool IsVCEFastVentOpen => _VCEFastVentValve.Status; public bool IsVCESoftVentOpen => _VCESoftVentValve.Status; public bool IsTMVentValveOpen => IsTMFastVentOpen && IsTMSoftVentOpen; public bool IsVCEVentValveOpen => IsVCEFastVentOpen && IsVCESoftVentOpen; //SlitDoor public bool VCESlitDoorClosed => _VCESlitDoor.State == CylinderState.Close; public bool PMASlitDoorClosed { get { if (_allInstalledModules.Contains("PMA")) return _PMASlitDoor.State == CylinderState.Close; else return true; } } public bool PMBSlitDoorClosed { get { if (_allInstalledModules.Contains("PMB")) return _PMBSlitDoor.State == CylinderState.Close; else return true; } } public bool PMCSlitDoorClosed { get { if (_allInstalledModules.Contains("PMC")) return _PMCSlitDoor.State == CylinderState.Close; else return true; } } public bool AllPMSlitDoorClosed { get { if (PMASlitDoorClosed && PMBSlitDoorClosed && PMCSlitDoorClosed) return true; else return false; } } public bool VCESlitDoorOpenEnable => _VCESlitDoorOpenEnable.Value; public bool PMASlitDoorOpenEnable => _PMASlitDoorOpenEnable.Value; public bool PMBSlitDoorOpenEnable => _PMBSlitDoorOpenEnable.Value; public bool PMCSlitDoorOpenEnable => _PMCSlitDoorOpenEnable.Value; //Robot动作 public bool TMExtendVCEEnable => _TMExtendVCEEnable.Value; public bool TMExtendPMAEnable => _TMExtendPMAEnable.Value; public bool TMExtendPMBEnable => _TMExtendPMBEnable.Value; public bool TMExtendPMCEnable => _TMExtendPMCEnable.Value; public double TMPressure => _TMPressure.Value; public double VCEPressure => _VCEPressure.Value; enum PumpState { Idle, TMUsing, VCEUsing, } PumpState _PumpingState = PumpState.Idle; #endregion public HongHuTM() : base(ModuleName.SETM.ToString()) { Module = ModuleName.SETM.ToString(); _TMFastPumpValve = DEVICE.GetDevice($"{Module}.{VenusDevice.TMFastPumpValve}"); _TMSoftPumpValve = DEVICE.GetDevice($"{Module}.{VenusDevice.TMSoftPumpValve}"); _VCESoftPumpValve = DEVICE.GetDevice($"{Module}.{VenusDevice.VCESoftPumpValve}"); _VCEFastPumpValve = DEVICE.GetDevice($"{Module}.{VenusDevice.VCEFastPumpValve}"); _TMFastVentValve = DEVICE.GetDevice($"{Module}.{VenusDevice.TMFastVentValve}"); _TMSoftVentValve = DEVICE.GetDevice($"{Module}.{VenusDevice.TMSoftVentValve}"); _VCESoftVentValve = DEVICE.GetDevice($"{Module}.{VenusDevice.VCESoftVentValve}"); _VCEFastVentValve = DEVICE.GetDevice($"{Module}.{VenusDevice.VCEFastVentValve}"); _VCESlitDoorOpenEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.VCESlitDoorOpenEnable}"); _PMASlitDoorOpenEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.PMASlitDoorOpenEnable}"); _PMBSlitDoorOpenEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.PMBSlitDoorOpenEnable}"); _PMCSlitDoorOpenEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.PMCSlitDoorOpenEnable}"); _TMExtendVCEEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.TMExtendVCEEnable}"); _TMExtendPMAEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.TMExtendPMAEnable}"); _TMExtendPMBEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.TMExtendPMBEnable}"); _TMExtendPMCEnable = DEVICE.GetDevice($"{Module}.{VenusDevice.TMExtendPMCEnable}"); _TMVACSensor = DEVICE.GetDevice($"{Module}.{VenusDevice.TMVACSensor}"); _VCEVACSensor = DEVICE.GetDevice($"{Module}.{VenusDevice.VCEVACSensor}"); _VCESlitDoor = DEVICE.GetDevice($"{Module}.{VenusDevice.VCESlitDoor}"); _PMASlitDoor = DEVICE.GetDevice($"{Module}.{VenusDevice.PMASlitDoor}"); _PMBSlitDoor = DEVICE.GetDevice($"{Module}.{VenusDevice.PMBSlitDoor}"); _PMCSlitDoor = DEVICE.GetDevice($"{Module}.{VenusDevice.PMCSlitDoor}"); _TMMfc = DEVICE.GetDevice($"{Module}.TM_MFC1"); _TMPressure = DEVICE.GetDevice($"{Module}.TMPressure"); _TMPiplinePressure = DEVICE.GetDevice($"{Module}.TMPipelinePressure"); _VCEPressure = DEVICE.GetDevice($"{Module}.VCEPressure"); _VCEPiplinePressure = DEVICE.GetDevice($"{Module}.VCEPipelinePressure"); if (SC.GetValue($"{Module}.DryPump.CommunicationType") == (int)CommunicationType.RS232) { if (SC.GetValue($"{Module}.DryPump.MFG") == (int)DryPumpMFG.SKY) { _TMPump = DEVICE.GetDevice($"{Module}.{VenusDevice.MainPump}"); } else if (SC.GetValue($"{Module}.DryPump.MFG") == (int)DryPumpMFG.Edwards) { _TMPump = DEVICE.GetDevice($"{Module}.{VenusDevice.MainPump}"); } } DATA.Subscribe($"{Module}.VCESlitDoorClosed", () => VCESlitDoorClosed); DATA.Subscribe($"{Module}.PMASlitDoorClosed", () => PMASlitDoorClosed); DATA.Subscribe($"{Module}.PMBSlitDoorClosed", () => PMBSlitDoorClosed); DATA.Subscribe($"{Module}.PMCSlitDoorClosed", () => PMCSlitDoorClosed); DATA.Subscribe($"{Module}.PumpIsRunning", () => IsTMPumpRunning, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.TMIsATM", ()=> IsTMATM); DATA.Subscribe($"{Module}.VCEIsATM", ()=> IsVCEATM); OP.Subscribe($"{Module}.ControlPump", (cmd, args) => { _TMPump.SetPumpOnOff((bool)args[0]); return true; }); OP.Subscribe($"{Module}.SetSlitDoor", (cmd, args) => { var module = (ModuleName)Enum.Parse(typeof(ModuleName), args[0].ToString()); return TurnSlitDoor(module, (bool)args[1]); }); } #region IO控制方法 //slitdoor //2023/11/1 增加两边压差比较 public bool TurnSlitDoor(ModuleName mod, bool bOn) { double MaxPressureDifference = SC.GetValue("System.PMTMMaxPressureDifference"); switch (mod) { case ModuleName.VCE1: if (bOn && Math.Abs(_TMPressure.Value - _VCEPressure.Value)> MaxPressureDifference) { LOG.Write(eEvent.ERR_TM, ModuleName.SETM, $"cannot open door cause pressure, TM Pressure:{_TMPressure.Value} and VCE Pressure:{_VCEPressure.Value}"); return false; } return _VCESlitDoor.SetCylinder(bOn, out _); case ModuleName.PMA: if (bOn && !CanOpenSlitDoor(mod, MaxPressureDifference)) return false; return _PMASlitDoor.SetCylinder(bOn, out _); case ModuleName.PMB: if (bOn && !CanOpenSlitDoor(mod, MaxPressureDifference)) return false; return _PMBSlitDoor.SetCylinder(bOn, out _); case ModuleName.PMC: if (bOn && !CanOpenSlitDoor(mod, MaxPressureDifference)) return false; return _PMCSlitDoor.SetCylinder(bOn, out _); } return false; } //valve public void TurnFastPumpValve(ModuleName mod, bool bOn) { switch (mod) { case ModuleName.SETM: _TMFastPumpValve.TurnValve(bOn, out string _); break; case ModuleName.VCE1: _VCEFastPumpValve.TurnValve(bOn, out string _); break; } } public void TurnSoftPumpValve(ModuleName mod, bool bOn) { switch (mod) { case ModuleName.SETM: _TMSoftPumpValve.TurnValve(bOn, out string _); break; case ModuleName.VCE1: _VCESoftPumpValve.TurnValve(bOn, out string _); break; } } public void TurnFastVentValve(ModuleName mod, bool bOn) { switch (mod) { case ModuleName.SETM: _TMFastVentValve.TurnValve(bOn, out string _); break; case ModuleName.VCE1: _VCEFastVentValve.TurnValve(bOn, out string _); break; } } public void TurnSoftVentValve(ModuleName mod, bool bOn) { switch (mod) { case ModuleName.SETM: _TMSoftVentValve.TurnValve(bOn, out string _); break; case ModuleName.VCE1: _VCESoftVentValve.TurnValve(bOn, out string _); break; } } public bool CloseAllSlitDoor() { _VCESlitDoor.SetCylinder(false, out _); if (_allInstalledModules.Contains("PMA")) _PMASlitDoor.SetCylinder(false, out _); if (_allInstalledModules.Contains("PMB")) _PMBSlitDoor.SetCylinder(false, out _); if (_allInstalledModules.Contains("PMC")) _PMCSlitDoor.SetCylinder(false, out _); return true; } public void HomeVceSlitDoor() { //由SlitDoor的状态对其下发同样的指令 if (VCESlitDoorClosed == true) _VCESlitDoor.SetCylinder(false, out _); else _VCESlitDoor.SetCylinder(true, out _); } public void CloseVentValve() { _TMSoftVentValve.TurnValve(false, out _); _TMFastVentValve.TurnValve(false, out _); _VCESoftVentValve.TurnValve(false, out _); _VCEFastVentValve.TurnValve(false, out _); } public bool CheckPumpValveClosed(ModuleName mod) { switch (mod) { case ModuleName.SETM: return !IsTMFastPumpOpen && !IsTMSoftPumpOpen; case ModuleName.VCE1: return !IsVCEFastPumpOpen && !IsVCESoftPumpOpen; } return true; } public bool CheckVentValveClosed(ModuleName mod) { switch (mod) { case ModuleName.SETM: if (IsTMVentValveOpen) { LOG.Write(eEvent.ERR_TM, ModuleName.SETM, "TM Vent Valve not closed"); return false; } break; case ModuleName.VCE1: if (IsVCEVentValveOpen) { LOG.Write(eEvent.ERR_TM, ModuleName.VCE1, "VCE1 Vent Valve not closed"); return false; } break; } return true; } public void SetTMFlow(int flowValue) { _TMMfc.SetPoint = (flowValue); } public double GetModulePressure(ModuleName mod) { switch (mod) { case ModuleName.SETM: return TMPressure; case ModuleName.VCE1: return VCEPressure; } return 0.0; } public bool TryGetPump(ModuleName mod) { //Self if ((mod == ModuleName.VCE1 && _PumpingState == PumpState.VCEUsing) || (mod == ModuleName.SETM && _PumpingState == PumpState.TMUsing)) return true; //Idle if (mod == ModuleName.SETM && !IsTMFastPumpOpen && !IsTMSoftPumpOpen && _PumpingState == PumpState.Idle) { _PumpingState = PumpState.TMUsing; return true; } if (mod == ModuleName.VCE1 && !IsVCEFastPumpOpen && !IsVCESoftPumpOpen && _PumpingState == PumpState.Idle) { _PumpingState = PumpState.VCEUsing; return true; } LOG.Write(eEvent.WARN_DEFAULT_WARN, mod, "无法打开,另一个泵正在用!"); //locked return false; } public void ReleasePump(ModuleName Module) { //release pump (must do it by user) if ((Module == ModuleName.SETM && _PumpingState == PumpState.TMUsing) || (Module == ModuleName.VCE1 && _PumpingState == PumpState.VCEUsing)) _PumpingState = PumpState.Idle; } #endregion #region 工具方法 private bool CanOpenSlitDoor(ModuleName mod,double MaxPressureDifference) { if (Singleton.Instance.GetPM(mod) == null || RouteManager.IsATMMode) return true; else { double PMPressure = Singleton.Instance.GetPM(mod).ChamberPressure; if (Math.Abs(_TMPressure.Value - PMPressure) > MaxPressureDifference) { LOG.Write(eEvent.ERR_TM, $"cannot open door cause pressure, TM Pressure:{_TMPressure.Value} and {mod} pressure:{PMPressure}"); return false; } else return true; } } #endregion } }