using System; using System.Xml; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; namespace Aitex.Core.RT.Device.Unit { public class IoHeater : BaseDevice, IDevice { public double SetPointLimit { get { if (_aoSetPointLimit != null) //return _aoSetPointLimit.Value; return _GetRealFloat(_aoSetPointLimit); return 100; } } [Subscription(AITHeaterPropertyName.CoolantInletTempFeedback)] public float CoolantInletTcFeedback { get { if (_aiCoolantInletTempFeedback == null) return -1; //return _aiMonitorTcFeedback.Value; return _GetRealFloat(_aiCoolantInletTempFeedback); } } [Subscription(AITHeaterPropertyName.CoolantOutletTempFeedback)] public float CoolantOutletTcFeedback { get { if (_aiCoolantOutletTempFeedback == null) return -1; //return _aiMonitorTcFeedback.Value; return _GetRealFloat(_aiCoolantOutletTempFeedback); } } [Subscription(AITHeaterPropertyName.MonitorTcFeedback)] public float MonitorTcFeedback { get { if (_aiMonitorTcFeedback == null) return -1; //return _aiMonitorTcFeedback.Value; return _GetRealFloat(_aiMonitorTcFeedback); } } [Subscription(AITHeaterPropertyName.ControlTcFeedback)] public float ControlTcFeedback { get { //if (Name == "ForelineHeater") //{ // if (_aiControlTcFeedback == null) return -1; // return _GetRealFloat(_aiControlTcFeedback); //} if (_aiControlTcFeedback == null) return -1; float real = _GetRealFloat(_aiControlTcFeedback); if (Name == "LEHeater1") { return real - GetHeater1OffsetSetting(real - _offset); } else if (Name == "LEHeater2") { return real - GetHeater2OffsetSetting(real - _offset); } return _GetRealFloat(_aiControlTcFeedback); //return ((real - GetHeaterOffsetSetting(real - _offset)) >= ControlTcSetPoint - _offset) ? (real - _offset) : (real - GetHeaterOffsetSetting(real - _offset)); } } [Subscription(AITHeaterPropertyName.ControlTcFeedbackNoOffSet)] public float ControlTcFeedbackNoOffSet { get { if (_aiControlTcFeedback == null) return -1; return _GetRealFloat(_aiControlTcFeedback); } } [Subscription(AITHeaterPropertyName.ControlTcSetPoint)] public float ControlTcSetPoint { get { if (_aoSetPoint != null) { float real = _GetRealFloat(_aoSetPoint); if (Name == "LEHeater1") { return real - GetHeater1OffsetSetting(real - _offset); } else if (Name == "LEHeater2") { return real - GetHeater2OffsetSetting(real - _offset); } return _GetRealFloat(_aoSetPoint); } return 0; } private set { if (_aoSetPoint != null) { //_aoSetPoint.Value = (short)setpoint; _SetRealFloat(_aoSetPoint, value); } } } [Subscription(AITHeaterPropertyName.IsMonitorTcBroken)] public bool IsMonitorTcBroken { get { if (_diMonitorTcBroken != null) return _diMonitorTcBroken.Value; return false; } } [Subscription(AITHeaterPropertyName.IsTcDeviation)] public bool IsTcDeviation { get { if (_diDeviation != null) return _diDeviation.Value; return false; } } [Subscription(AITHeaterPropertyName.IsControlTcBroken)] public bool IsControlTcBroken { get { if (_diControlTcBroken != null) return _diControlTcBroken.Value; return false; } } [Subscription(AITHeaterPropertyName.IsPowerOnFeedback)] public bool IsPowerOnFeedback { get { if (_diPowerOnFeedback != null) return _diPowerOnFeedback.Value; if (_doPowerOn != null) return _doPowerOn.Value; return false; } } [Subscription(AITHeaterPropertyName.ControlTcSetPointView)] public float ControlTcSetPointView { get { return _controlTcSetPointView; } } [Subscription(AITHeaterPropertyName.IsPowerOnSetPoint)] public bool IsPowerOnSetPoint { get { if (_doPowerOn != null) return _doPowerOn.Value; return false; } } public string Unit { get; set; } //private int _stage = 0; private float _controlTcSetPointView = 0f; //private int _stageSet = 0; private float _offset = 0f; //private float _offsetSet = 0f; private readonly DIAccessor _diPowerOnFeedback; private readonly DIAccessor _diControlTcBroken; private readonly DIAccessor _diMonitorTcBroken; private readonly DIAccessor _diDeviation; private readonly DOAccessor _doPowerOn; private readonly AIAccessor _aiControlTcFeedback; private readonly AIAccessor _aiMonitorTcFeedback; private readonly AIAccessor _aiCoolantInletTempFeedback; private readonly AIAccessor _aiCoolantOutletTempFeedback; private readonly AOAccessor _aoSetPoint; private AOAccessor _aoSetPointLimit; private readonly SCConfigItem _scSetPointLimit; private readonly R_TRIG _trigMonitorTcBroken = new R_TRIG(); private readonly R_TRIG _trigControlTcBroken = new R_TRIG(); private readonly R_TRIG _trigDeviation = new R_TRIG(); private SCConfigItem _scEnableToleranceCheck; private SCConfigItem _scDeviationAlarmRange; private SCConfigItem _scDeviationAlarmTime; private SCConfigItem _scDeviationWarningRange; private SCConfigItem _scDeviationWarningTime; private DeviceTimer _timerAlarm = new DeviceTimer(); private DeviceTimer _timerWarning = new DeviceTimer(); private readonly R_TRIG _trigWarning = new R_TRIG(); private readonly R_TRIG _trigAlarm = new R_TRIG(); private ToleranceChecker _checkerWarning = new ToleranceChecker(); private ToleranceChecker _checkerAlarm = new ToleranceChecker(); private string HeaterDeviationAlarm = "HeaterDeviationAlarm"; public IoHeater(string module, XmlElement node, string ioModule = "") { base.Module = module; base.Name = node.GetAttribute("id"); base.Display = node.GetAttribute("display"); base.DeviceID = node.GetAttribute("schematicId"); Unit = node.GetAttribute("unit"); _diPowerOnFeedback = ParseDiNode("diPowerOnFeedback", node, ioModule); _diControlTcBroken = ParseDiNode("diControlTcBroken", node, ioModule); _diMonitorTcBroken = ParseDiNode("diMonitorTcBroken", node, ioModule); _doPowerOn = ParseDoNode("doPowerOn", node, ioModule); _diDeviation = ParseDiNode("diDeviation", node, ioModule); _aiControlTcFeedback = ParseAiNode("aiFeedback", node, ioModule); _aiMonitorTcFeedback = ParseAiNode("aiMonitor", node, ioModule); _aiCoolantInletTempFeedback = ParseAiNode("aiCoolantInletTemp", node, ioModule); _aiCoolantOutletTempFeedback = ParseAiNode("aiCoolantOutletTemp", node, ioModule); _aoSetPoint = ParseAoNode("aoSetPoint", node, ioModule); _aoSetPointLimit = ParseAoNode("aoSetPointLimit", node, ioModule); _scSetPointLimit = ParseScNodeEx("scSetPointLimit", node, ioModule); } //public void UpdateConfig(double setPointLimit) //{ // if (_aoSetPointLimit != null) // _aoSetPointLimit.Value = (short)setPointLimit; //} public bool Initialize() { DATA.Subscribe($"{Module}.{Name}.DeviceData", () => { AITHeaterData data = new AITHeaterData() { Module = Module, DeviceName = Name, DeviceSchematicId = DeviceID, DisplayName = Display, FeedBack = ControlTcFeedback, MonitorTcFeedBack = MonitorTcFeedback, CoolantInletTcFeedback = CoolantInletTcFeedback, CoolantOutletTcFeedback = CoolantOutletTcFeedback, Scale = SetPointLimit, SetPoint = ControlTcSetPointView, IsPowerOn = IsPowerOnFeedback, IsPowerOnSetPoint = IsPowerOnSetPoint, IsControlTcBroken = IsControlTcBroken, IsMonitorTcBroken = IsMonitorTcBroken, Unit = Unit, IsTcDeviation = IsTcDeviation, }; return data; }, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.Temperature", () => ControlTcFeedback); OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.SetPowerOnOff}", (functionName, param) => { bool isEnable = Convert.ToBoolean((string)param[0]); return this.TurnOnOff(isEnable); }); OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.Ramp}", (functionName, param) => { float setpoint = (float)Convert.ToDouble((string)param[0]); if (!RampTemp(setpoint)) return false; return true; }); this.SetBySC(_aoSetPointLimit, _scSetPointLimit); if(Name== "LEHeater2"|| Name == "LEHeater1") { _scEnableToleranceCheck = SC.GetConfigItem($"{Module}.HeaterChamber.HeaterEnableTolerance"); _scDeviationAlarmRange = SC.GetConfigItem($"{Module}.HeaterChamber.HeaterAlarmRange"); _scDeviationAlarmTime = SC.GetConfigItem($"{Module}.HeaterChamber.HeaterAlarmTime"); _scDeviationWarningRange = SC.GetConfigItem($"{Module}.HeaterChamber.HeaterWarningRange"); _scDeviationWarningTime = SC.GetConfigItem($"{Module}.HeaterChamber.HeaterWarningTime"); } if (Name == "HeaterChamber") { _scEnableToleranceCheck = SC.GetConfigItem($"{Module}.HeaterChamberWall.HeaterEnableTolerance"); _scDeviationAlarmRange = SC.GetConfigItem($"{Module}.HeaterChamberWall.HeaterAlarmRange"); _scDeviationAlarmTime = SC.GetConfigItem($"{Module}.HeaterChamberWall.HeaterAlarmTime"); _scDeviationWarningRange = SC.GetConfigItem($"{Module}.HeaterChamberWall.HeaterWarningRange"); _scDeviationWarningTime = SC.GetConfigItem($"{Module}.HeaterChamberWall.HeaterWarningTime"); } EV.Subscribe(new EventItem("Event", HeaterDeviationAlarm, "Heater Deviation Out of Tolerance", EventLevel.Alarm, EventType.HostNotification)); return true; } public bool TurnOnOff(bool on) { if (!_doPowerOn.SetValue(on, out string reason)) { EV.PostWarningLog(Module, reason); return false; } EV.PostInfoLog(Module, $"Set Heater {Name} Power {(on ? "ON" : "OFF")}"); return true; } public bool RampTemp(float setpoint) { //_stageSet = (setpoint < 100) ? 3 : (setpoint < 200 && setpoint >= 100) ? 5 : (setpoint >= 200) ? 6 : 0; if (Name == "LEHeater1") { _offset = GetHeater1OffsetSetting(setpoint); } else if (Name == "LEHeater2") { _offset = GetHeater2OffsetSetting(setpoint); } else { _offset = 0; } // offset 处理后的设定值 _controlTcSetPointView = setpoint; if (Name == "ForelineHeater"||Name== "HeaterChamber") ControlTcSetPoint = setpoint; else ControlTcSetPoint = setpoint + _offset; // 是否越界 if (setpoint > SetPointLimit || setpoint < 0) { EV.PostAlarmLog(Module, $"{Name} 温度设定 {setpoint} 无效, 正确范围是 (0, {SetPointLimit})"); return false; } EV.PostInfoLog(Module, $"设定 {Display} 温度到 {setpoint}"); return true; } public void Stop() { if (_aoSetPoint != null) { _aoSetPoint.Value = 0; } } public void Terminate() { } public void Monitor() { _trigControlTcBroken.CLK = IsControlTcBroken; if (_trigControlTcBroken.Q) { EV.PostAlarmLog(Module, $"{Display}, Found control TC broken"); } _trigMonitorTcBroken.CLK = IsMonitorTcBroken; if (_trigMonitorTcBroken.Q) { EV.PostAlarmLog(Module, $"{Display}, Found monitor TC broken"); } _trigDeviation.CLK = IsTcDeviation; if (_trigDeviation.Q) { EV.PostAlarmLog(Module, $"{Display}, Found TC Deviation out of range"); } this.SetBySC(_aoSetPointLimit, _scSetPointLimit); CheckDeviation(); } private void CheckDeviation() { if (_scEnableToleranceCheck==null || !_scEnableToleranceCheck.BoolValue||!((Name == "HeaterChamber")|| (Name == "LEHeater1") || (Name == "LEHeater2")) || !IsPowerOnFeedback) return; _checkerWarning.Monitor(ControlTcFeedback, ControlTcSetPoint - Math.Abs(_scDeviationWarningRange.IntValue) , ControlTcSetPoint + Math.Abs(_scDeviationWarningRange.IntValue), _scDeviationWarningTime.IntValue); if (_checkerWarning.Trig) { if(Name == "HeaterChamber") { EV.PostWarningLog(Module, $"HeaterChamberWall temperature feedback deviation than {Math.Abs(_scDeviationWarningRange.IntValue)} from setpoint for {_scDeviationWarningTime.IntValue} seconds"); } else { EV.PostWarningLog(Module, $"{Name} temperature feedback deviation than {Math.Abs(_scDeviationWarningRange.IntValue)} from setpoint for {_scDeviationWarningTime.IntValue} seconds"); } } _checkerAlarm.Monitor(ControlTcFeedback, ControlTcSetPoint - Math.Abs(_scDeviationAlarmRange.IntValue) , ControlTcSetPoint + Math.Abs(_scDeviationAlarmRange.IntValue), _scDeviationAlarmTime.IntValue); if (_checkerAlarm.Trig) { if (Name == "HeaterChamber") { EV.PostAlarmLog(Module, $"HeaterChamberWall temperature feedback deviation than {Math.Abs(_scDeviationAlarmRange.IntValue)} from setpoint for {_scDeviationAlarmTime.IntValue} seconds"); } else { EV.PostAlarmLog(Module, $"{Name} temperature feedback deviation than {Math.Abs(_scDeviationAlarmRange.IntValue)} from setpoint for {_scDeviationAlarmTime.IntValue} seconds"); } EV.Notify(HeaterDeviationAlarm); } } public void Reset() { _trigControlTcBroken.RST = true; _trigMonitorTcBroken.RST = true; _trigDeviation.RST = true; _checkerWarning.RST = true; _checkerAlarm.RST = true; } private void SetBySC(AOAccessor acc, SCConfigItem scItem) { if (scItem != null && acc != null) { //acc.Value = (short)scItem.IntValue; _SetRealFloat(acc, scItem.IntValue); } } private float GetHeater1OffsetSetting(double val) { if (!SC.ContainsItem($"{Module}.BiasRf1.EnableBiasRF") || SC.GetValue($"{Module}.BiasRf1.EnableBiasRF")) return 0; if (!SC.ContainsItem($"{Module}.Chiller1.EnableChiller") || SC.GetValue($"{Module}.Chiller1.EnableChiller")) return 0; int[] iTempPoint = new int[10]; float[] fOffsetValue = new float[10]; try { for (int i = 1; i < 10; i++) { iTempPoint[i] = SC.GetValue($"{Module}.HeaterChamber1.TempOffsetPoint_{i}"); fOffsetValue[i] = (float)SC.GetValue($"{Module}.HeaterChamber1.OffsetValue_{i}"); if (val < iTempPoint[i]) { return (fOffsetValue[i] - fOffsetValue[i - 1]) / (iTempPoint[i] - iTempPoint[i - 1]) * ((float)val - iTempPoint[i - 1]) + fOffsetValue[i - 1]; } } } catch { } return 0; } private float GetHeater2OffsetSetting(double val) { if (!SC.ContainsItem($"{Module}.BiasRf1.EnableBiasRF") || SC.GetValue($"{Module}.BiasRf1.EnableBiasRF")) return 0; if (!SC.ContainsItem($"{Module}.Chiller1.EnableChiller") || SC.GetValue($"{Module}.Chiller1.EnableChiller")) return 0; int[] iTempPoint = new int[10]; float[] fOffsetValue = new float[10]; try { for (int i = 1; i < 10; i++) { iTempPoint[i] = SC.GetValue($"{Module}.HeaterChamber2.TempOffsetPoint_{i}"); fOffsetValue[i] = (float)SC.GetValue($"{Module}.HeaterChamber2.OffsetValue_{i}"); if (val < iTempPoint[i]) { return (fOffsetValue[i] - fOffsetValue[i - 1]) / (iTempPoint[i] - iTempPoint[i - 1]) * ((float)val - iTempPoint[i - 1]) + fOffsetValue[i - 1]; } } } catch { } return 0; } } }