| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 | 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.Util; namespace VirgoRT.Devices{    public class IoThrottleValve : BaseDevice, IDevice    {        public struct Context        {            public string tvName;            public string aoPressureModeName;            public string aoPressureSetPointName;            public string aoPositionSetPointName;            public string aiPressureFeedbackName;            public string aiPositionFeedbackName;            public string aiStateName;        };        public PressureCtrlMode PressureMode        {            get            {                if (_aoPressureMode == null)                    return PressureCtrlMode.TVPositionCtrl;                byte[] high = BitConverter.GetBytes(_aoPositionSetPoint.Buffer[_aoPressureMode.Index]);                byte[] low = BitConverter.GetBytes(_aoPositionSetPoint.Buffer[_aoPressureMode.Index + 1]);                float _pressureMode = BitConverter.ToSingle(new[] { high[0], high[1], low[0], low[1] }, 0);                return Math.Abs(_pressureMode - 2) < 0.1 ? PressureCtrlMode.TVPositionCtrl : PressureCtrlMode.TVPressureCtrl;            }            set            {                if (_aoPositionSetPoint == null || _aoPressureSetPoint == null || _aoPressureMode == null)                    return;                short setpoint = (short)(value == PressureCtrlMode.TVPositionCtrl ? 2 : 1);                byte[] high = BitConverter.GetBytes(_aoPositionSetPoint.Buffer[_aoPressureMode.Index]);                byte[] low = BitConverter.GetBytes(_aoPositionSetPoint.Buffer[_aoPressureMode.Index + 1]);                float _pressureMode = BitConverter.ToSingle(new[] { high[0], high[1], low[0], low[1] }, 0);                if (Math.Abs(_pressureMode - setpoint) > 0.01)                {                    if (value == PressureCtrlMode.TVPositionCtrl)                    {                        //_aoPositionSetPoint.Value = PositionFeedback;                        byte[] _position = BitConverter.GetBytes(PositionFeedback);                        _aoPositionSetPoint.Buffer[_aoPositionSetPoint.Index] = BitConverter.ToInt16(_position, 0);                        _aoPositionSetPoint.Buffer[_aoPositionSetPoint.Index + 1] = BitConverter.ToInt16(_position, 2);                    }                    else                    {                        //_aoPressureSetPoint.Value = PressureFeedback;                        byte[] _pressure = BitConverter.GetBytes(PressureFeedback);                        _aoPressureSetPoint.Buffer[_aoPressureSetPoint.Index] = BitConverter.ToInt16(_pressure, 0);                        _aoPressureSetPoint.Buffer[_aoPressureSetPoint.Index + 1] = BitConverter.ToInt16(_pressure, 2);                    }                    //_aoPressureMode.Value = setpoint;                    byte[] flow = BitConverter.GetBytes((float)setpoint);                    _aoPressureMode.Buffer[_aoPressureMode.Index] = BitConverter.ToInt16(flow, 0);                    _aoPressureMode.Buffer[_aoPressureMode.Index + 1] = BitConverter.ToInt16(flow, 2);                }            }        }        public int State => _aiState == null ? 1 : (int)_aiState.Value;        [Subscription("ProcessPressureOffset")]        public double ProcessPressureOffset        {            get            {                if (_scProcessPressureOffset != null)                    return _scProcessPressureOffset.DoubleValue;                return 0;            }        }        [Subscription(AITThrottleValvePropertyName.TVPositionSetPoint)]        public float PositionSetpoint        {            get            {                if (_aoPositionSetPoint != null)                {                    byte[] high = BitConverter.GetBytes(_aoPositionSetPoint.Buffer[_aoPositionSetPoint.Index]);                    byte[] low = BitConverter.GetBytes(_aoPositionSetPoint.Buffer[_aoPositionSetPoint.Index + 1]);                    float flow = BitConverter.ToSingle(new[] { high[0], high[1], low[0], low[1] }, 0);                    return flow;                }                return 0;            }            set            {                if (_aoPositionSetPoint != null)                {                    byte[] flow = BitConverter.GetBytes(value);                    _aoPositionSetPoint.Buffer[_aoPositionSetPoint.Index] = BitConverter.ToInt16(flow, 0);                    _aoPositionSetPoint.Buffer[_aoPositionSetPoint.Index + 1] = BitConverter.ToInt16(flow, 2);                }            }        }         [Subscription(AITThrottleValvePropertyName.TVPosition)]        public float PositionFeedback //=> _aiPositionFeedback?.Value ?? 0;        {            get            {                if (_aiPositionFeedback != null)                {                    byte[] high = BitConverter.GetBytes(_aiPositionFeedback.Buffer[_aiPositionFeedback.Index]);                    byte[] low = BitConverter.GetBytes(_aiPositionFeedback.Buffer[_aiPositionFeedback.Index + 1]);                    float flow = BitConverter.ToSingle(new[] { high[0], high[1], low[0], low[1] }, 0);                    return flow;                }                return 0;            }        }        [Subscription(AITThrottleValvePropertyName.TVPressureSetPoint)]        public float PressureSetpoint        {            get            {                if (_aoPressureSetPoint != null)                {                    byte[] high = BitConverter.GetBytes(_aoPressureSetPoint.Buffer[_aoPressureSetPoint.Index]);                    byte[] low = BitConverter.GetBytes(_aoPressureSetPoint.Buffer[_aoPressureSetPoint.Index + 1]);                    float flow = BitConverter.ToSingle(new[] { high[0], high[1], low[0], low[1] }, 0);                    return flow;                }                return 0;            }            set            {                if (_aoPressureSetPoint != null)                {                    byte[] flow = BitConverter.GetBytes(value);                    _aoPressureSetPoint.Buffer[_aoPressureSetPoint.Index] = BitConverter.ToInt16(flow, 0);                    _aoPressureSetPoint.Buffer[_aoPressureSetPoint.Index + 1] = BitConverter.ToInt16(flow, 2);                }            }        }        [Subscription(AITThrottleValvePropertyName.TVPressure)]        public float PressureFeedback //=> _aiPressureFeedback?.Value ?? 0;        {            get            {                if (_aiPressureFeedback != null)                {                    byte[] high = BitConverter.GetBytes(_aiPressureFeedback.Buffer[_aiPressureFeedback.Index]);                    byte[] low = BitConverter.GetBytes(_aiPressureFeedback.Buffer[_aiPressureFeedback.Index + 1]);                    float flow = BitConverter.ToSingle(new[] { high[0], high[1], low[0], low[1] }, 0);                    return flow;                }                return 0;            }        }        public bool IsIndependent { get; set; }        public bool IsOffline => _diOffline != null && _diOffline.RawData;        private readonly DIAccessor _diOffline;        private readonly AIAccessor _aiPressureFeedback;        private readonly AIAccessor _aiPositionFeedback;        private readonly AOAccessor _aoPressureSetPoint;        private readonly AOAccessor _aoPositionSetPoint;        private readonly AOAccessor _aoPressureMode;        private readonly AIAccessor _aiState;        private SCConfigItem _scProcessPressureOffset;        private readonly R_TRIG _tvStatusAlmTrig = new R_TRIG();        private readonly R_TRIG _trigOffline = new R_TRIG();        public IoThrottleValve(string module, XmlElement node, string ioModule = "")        {            base.Module         = module;            base.Name           = node.GetAttribute("id");            base.Display        = node.GetAttribute("display");            base.DeviceID       = node.GetAttribute("schematicId");            _aiPositionFeedback = ParseAiNode("aiPositionFeedback", node, ioModule);            _aiPressureFeedback = ParseAiNode("aiPressureFeedback", node, ioModule);            _aoPositionSetPoint = ParseAoNode("aoPositionSetPoint", node, ioModule);            _aoPressureSetPoint = ParseAoNode("aoPressureSetPoint", node, ioModule);            _aiState            = ParseAiNode("aiState", node, ioModule);            _aoPressureMode     = ParseAoNode("aoPressureMode", node, ioModule);            _diOffline          = ParseDiNode("diOffline", node, ioModule);            _scProcessPressureOffset = SC.GetConfigItem($"{Module}.ProcessPressureOffset");        }        public bool Initialize()        {            DATA.Subscribe($"{Module}.{Name}", Getter, SubscriptionAttribute.FLAG.IgnoreSaveDB);            PressureMode = PressureCtrlMode.TVPressureCtrl;            DEVICE.Register($"{Module}.{Name}.{AITThrottleValveOperation.SetMode}", _setMode);            DEVICE.Register($"{Module}.{Name}.{AITThrottleValveOperation.SetPosition}", _setPosition);            DEVICE.Register($"{Module}.{Name}.{AITThrottleValveOperation.SetPressure}", _setPressure);            OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetMode}", _setMode2);            OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetPressure}", _setPressure2);            OP.Subscribe($"{Module}.{Name}.{AITThrottleValveOperation.SetPosition}", _setPosition2);            return true;        }        private bool _setPosition2(string arg1, object[] arg2)        {            return this._setPosition(out string str1, 0, arg2).Value;        }        private bool _setMode2(string arg1, object[] arg2)        {            return this._setMode(out string str, 0, arg2).Value;        }        private bool _setPressure2(string arg1, object[] arg2)        {            return this._setPressure(out string str, 0, arg2).Value;        }        private bool? _setPressure(out string reason, int time, object[] param)        {            PressureMode = PressureCtrlMode.TVPressureCtrl;            //double target = Convert.ToDouble((string) param[0]);            double target = (double)param[0];            PositionSetpoint = 0.0f;            PressureSetpoint = (float)target - (float)ProcessPressureOffset;            reason = $"pressure set {target} mTorr";            return true;        }        private bool? _setPosition(out string reason, int time, object[] param)        {            //double target = Convert.ToDouble((string) param[0]);            double target = (double)param[0];            PressureMode = PressureCtrlMode.TVPositionCtrl;            PositionSetpoint = (short) target;            PressureSetpoint = 0.0f;            reason = $"position set to {target:F1}%";            return true;        }        private bool? _setMode(out string reason, int time, object[] param)        {            PressureMode = (PressureCtrlMode) Enum.Parse(typeof(PressureCtrlMode), (string) param[0], true);            reason = $"Throttle valve set to {PressureMode} mode";            return true;        }        private object Getter()        {            AITThrottleValveData data = new AITThrottleValveData()            {                Module = Module,                DeviceName        = Name,                DeviceSchematicId = DeviceID,                DisplayName       = Display,                Mode              = (int) PressureMode,                PositionFeedback  = PositionFeedback,                PositionSetPoint  = PositionSetpoint,                PressureFeedback  = PressureFeedback,                PressureSetPoint  = PressureSetpoint,                State             = State,            };            return data;        }        public void Terminate()        {        }        public void Monitor()        {            try            {                _tvStatusAlmTrig.CLK = State != 1;                if (_tvStatusAlmTrig.Q)                {                    EV.PostAlarmLog(Module, "Throttle valve status error");                }                _trigOffline.CLK = IsOffline;                if (_trigOffline.Q)                {                    EV.PostAlarmLog(Module, "Throttle valve offline");                }            }            catch (Exception ex)            {                LOG.Write(ex);                throw ex;            }        }        public void Reset()        {            _tvStatusAlmTrig.RST = true;            _trigOffline.RST = true;        }        public void SetPositionMode(int position)        {            PressureMode = PressureCtrlMode.TVPositionCtrl;            PositionSetpoint = (short)position;        }    }}
 |