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.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Tolerance; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; //using Venus_Core; namespace Venus_RT.Devices { //public interface IoHeaterController //{ // bool SetPowerOnOff(bool isOn); // bool Ramp(float temp); // float GetFeedback(); // float GetSetPoint(); // bool GetIsOn(); //} public class IoHeater : BaseDevice, IDevice { //public IoHeaterController Controller { get; set; } public double SetPointLimit { get { if (_aoSetPointLimit != null) return _GetRealFloat(_aoSetPointLimit); return 100; } } //public float CoolantInletTcFeedback //{ // get // { // if (_aiCoolantInletTempFeedback == null) return -1; // return _GetRealFloat(_aiCoolantInletTempFeedback); // } //} //public float CoolantOutletTcFeedback //{ // get // { // if (_aiCoolantOutletTempFeedback == null) return -1; // return _GetRealFloat(_aiCoolantOutletTempFeedback); // } //} //public float MonitorTcFeedback //{ // get // { // if (_aiMonitorTcFeedback == null) return -1; // 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); return real; //return real - GetHeaterOffsetSetting(real - _offset); //return ((real - GetHeaterOffsetSetting(real - _offset)) >= ControlTcSetPoint - _offset) ? (real - _offset) : (real - GetHeaterOffsetSetting(real - _offset)); } } //[Subscription(AITHeaterPropertyName.ControlTcSetPoint)] public float ControlTcSetPoint { get { if (_aoSetPoint != null) //return _aoSetPoint.Value; return _GetRealFloat(_aoSetPoint); //if (Controller != null) // return Controller.GetSetPoint(); return 0; } private set { if (_aoSetPoint != null) { _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 (Controller != null) //{ // return Controller.GetIsOn(); //} 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; } set { if (_doPowerOn != null) { _doPowerOn.Value = value; } } } 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 readonly R_TRIG _trigCHBWallOTSW = 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"; private bool isinit; private bool _isOn; public bool IsOn { set { _isOn = value; } } private float _TemperatureSetPoint; public float TemperatureSetPoint { set { if (value != _TemperatureSetPoint) { RampTemp(value); _TemperatureSetPoint = value; } } } 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 = ControlTcSetPoint, IsPowerOn = IsPowerOnFeedback, IsPowerOnSetPoint = IsPowerOnSetPoint, IsControlTcBroken = IsControlTcBroken, IsMonitorTcBroken = IsMonitorTcBroken, Unit = Unit, IsTcDeviation = IsTcDeviation, }; return data; }, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.{Name}.Temperature", () => ControlTcFeedback, SubscriptionAttribute.FLAG.IgnoreSaveDB); OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.SetPowerOnOff}", (functionName, param) => { bool isEnable = (bool)param[0]; return this.TurnOnOff(isEnable); }); OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.Ramp}", (functionName, param) => { float setpoint; float.TryParse((string)param[0], out setpoint); if (!RampTemp(setpoint)) return false; _controlTcSetPointView = setpoint; return true; }); this.SetBySC(_aoSetPointLimit, _scSetPointLimit); _scEnableToleranceCheck = SC.GetConfigItem($"{Module}.{Name}.HeaterEnableTolerance"); _scDeviationAlarmRange = SC.GetConfigItem($"{Module}.{Name}.HeaterAlarmRange"); _scDeviationAlarmTime = SC.GetConfigItem($"{Module}.{Name}.HeaterAlarmTime"); _scDeviationWarningRange = SC.GetConfigItem($"{Module}.{Name}.HeaterWarningRange"); _scDeviationWarningTime = SC.GetConfigItem($"{Module}.{Name}.HeaterWarningTime"); EV.Subscribe(new EventItem("Event", HeaterDeviationAlarm, "Heater Deviation Out of Tolerance", EventLevel.Alarm, EventType.HostNotification)); isinit = true; return true; } public bool TurnOnOff(bool on) { //if (Controller != null) //{ // Controller.SetPowerOnOff(on); // return true; //} if (!_doPowerOn.SetValue(on, out string reason)) { LOG.Write(eEvent.WARN_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), reason); return false; } SC.SetItemValue($"{Module}.{Name}.IsOn", on); LOG.Write(eEvent.INFO_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"Set Heater {Name} Power {(on ? "ON" : "OFF")}"); return true; } public bool RampTemp(float setpoint) { // 是否越界 if (setpoint > SetPointLimit || setpoint < 0) { LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Name} 温度设定 {setpoint} 无效, 正确范围是 (0, {SetPointLimit})"); return false; } if (setpoint == 0) { LOG.Write(eEvent.INFO_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Name} setpoint = {setpoint}, ignore temperature control"); return true; } SC.SetItemValue($"{Module}.{Name}.TemperatureSetPoint", setpoint); //if (Controller != null) //{ // SC.SetItemValue($"{Module}.{Name}.TemperatureSetPoint", setpoint); // return Controller.Ramp(setpoint); //} //_offset = GetHeaterOffsetSetting(setpoint); // offset 处理后的设定值 _controlTcSetPointView = setpoint; if (Name == "ForelineHeater") ControlTcSetPoint = setpoint; else ControlTcSetPoint = setpoint + _offset; LOG.Write(eEvent.INFO_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"设定 {Display} 温度到 {setpoint}"); return true; } public void Stop() { if (_aoSetPoint != null) { _aoSetPoint.Value = 0; } } public void Terminate() { } public void Monitor() { try { if (isinit == false) { return; } _trigControlTcBroken.CLK = IsControlTcBroken; if (_trigControlTcBroken.Q) { LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Display}, Found control TC broken"); } _trigMonitorTcBroken.CLK = IsMonitorTcBroken; if (_trigMonitorTcBroken.Q) { LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Display}, Found monitor TC broken"); } _trigDeviation.CLK = IsTcDeviation; if (_trigDeviation.Q) { LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Display}, Found TC Deviation out of range"); } this.SetBySC(_aoSetPointLimit, _scSetPointLimit); CheckDeviation(); TemperatureSetPoint = (float)SC.GetValue($"{Module}.{Name}.TemperatureSetPoint"); IsPowerOnSetPoint = SC.GetValue($"{Module}.{Name}.IsOn"); } catch (Exception ex) { LOG.WriteExeption(ex); } } private void CheckDeviation() { if (!_scEnableToleranceCheck.BoolValue) return; //if (Controller != null && !Controller.GetIsOn()) //{ // return; //} if (!IsPowerOnFeedback) return; _checkerWarning.Monitor(ControlTcFeedback, ControlTcSetPoint - Math.Abs(_scDeviationWarningRange.IntValue) , ControlTcSetPoint + Math.Abs(_scDeviationWarningRange.IntValue), _scDeviationWarningTime.IntValue); if (_checkerWarning.Trig) { LOG.Write(eEvent.WARN_DEVICE_IO_HEATER, ModuleHelper.Converter(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) { LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(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 GetHeaterOffsetSetting(double val) //{ // //if (SC.GetValue($"{Module}.BiasRf.EnableBiasRF")) return 0; // //if (SC.GetValue($"{Module}.Chiller.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}.{Name}.TempOffsetPoint_{i}"); // fOffsetValue[i] = (float)SC.GetValue($"{Module}.{Name}.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; //} } }