| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 | 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 VirgoRT.Annotations;namespace VirgoRT.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 _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) + (float)_scMonitorTcFeedbackOffset.DoubleValue;            }        }        [Subscription(AITHeaterPropertyName.ControlTcFeedback)]        public float ControlTcFeedback        {            get            {                if (Name == "ForelineHeater")                {                    if (_aiControlTcFeedback == null) return -1;                    return _GetRealFloat(_aiControlTcFeedback) + (float)_scControlTcFeedbackOffset.DoubleValue;                }                if (_aiControlTcFeedback == null) return -1;                float real = _GetRealFloat(_aiControlTcFeedback);                return real - GetHeaterOffsetSetting(real - _offset) + (float)_scControlTcFeedbackOffset.DoubleValue;                //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)                {                    //_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 (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;            }        }        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 SCConfigItem _scMonitorTcFeedbackOffset;        private SCConfigItem _scControlTcFeedbackOffset;        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, SubscriptionAttribute.FLAG.IgnoreSaveDB);            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);            _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");            _scMonitorTcFeedbackOffset = SC.GetConfigItem($"{Module}.{Name}.MonitorTcFeedbackOffset");            _scControlTcFeedbackOffset = SC.GetConfigItem($"{Module}.{Name}.ControlTcFeedbackOffset");            EV.Subscribe(new EventItem("Event", HeaterDeviationAlarm, "Heater Deviation Out of Tolerance", EventLevel.Alarm, EventType.HostNotification));            return true;        }        public bool TurnOnOff(bool on)        {            if (Controller != null)            {                Controller.SetPowerOnOff(on);                return true;            }            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)        {            // 是否越界            if (setpoint > SetPointLimit || setpoint < 0)            {                EV.PostAlarmLog(Module, $"{Name} temp setpoint {setpoint} invalid, correct range (0, {SetPointLimit})");                return false;            }            if (setpoint == 0)            {                EV.PostInfoLog(Module, $"{Name} setpoint = {setpoint}, ignore temperature control");                return true;            }            if (Controller != null)            {                return Controller.Ramp(setpoint);            }            _offset = GetHeaterOffsetSetting(setpoint);            // offset 处理后的设定值            _controlTcSetPointView = setpoint;            if (Name == "ForelineHeater")                ControlTcSetPoint = setpoint;            else                ControlTcSetPoint = setpoint + _offset;            EV.PostInfoLog(Module, $"Set {Display} temp to {setpoint}");            return true;        }        public void Stop()        {            if (_aoSetPoint != null)            {                _aoSetPoint.Value = 0;            }        }        public void Terminate()        {        }        public void Monitor()        {            try            {                _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();            }            catch (Exception ex)            {                LOG.Write(ex);            }        }        private void CheckDeviation()        {            if (!_scEnableToleranceCheck.BoolValue)                return;            if (Controller != null && !Controller.GetIsOn())            {                return;            }            if (!IsPowerOnFeedback)                return;            _checkerWarning.Monitor(ControlTcFeedback, ControlTcSetPointView - Math.Abs(_scDeviationWarningRange.IntValue)                , ControlTcSetPoint + Math.Abs(_scDeviationWarningRange.IntValue),  _scDeviationWarningTime.IntValue);            if (_checkerWarning.Trig)            {                EV.PostWarningLog(Module, $"{Name} temperature feedback deviation than {Math.Abs(_scDeviationWarningRange.IntValue)} from setpoint for {_scDeviationWarningTime.IntValue} seconds");            }            _checkerAlarm.Monitor(ControlTcFeedback, ControlTcSetPointView - Math.Abs(_scDeviationAlarmRange.IntValue)                , ControlTcSetPoint + Math.Abs(_scDeviationAlarmRange.IntValue), _scDeviationAlarmTime.IntValue);            if (_checkerAlarm.Trig)            {                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 GetHeaterOffsetSetting(double val)        {            if (SC.GetValue<bool>($"{Module}.BiasRf.EnableBiasRF")) return 0;            if (SC.GetValue<bool>($"{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<int>($"{Module}.{Name}.TempOffsetPoint_{i}");                    fOffsetValue[i] = (float)SC.GetValue<double>($"{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;        }    }}
 |