| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702 | using System;using System.Collections;using System.Text;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.Communications;using MECF.Framework.Common.DataCenter;using MECF.Framework.Common.Device.Bases;using MECF.Framework.Common.Equipment;using VirgoCommon;namespace VirgoRT.Devices{    //interface IPumpControl    //{    //    bool IsRunning { get; }    //    void TurnON();    //    void TurnOFF();    //}    public enum SkyPumpState { ON = 0, OFF, Connected, Disconnected, Unknown, ERROR }    static class SkyPumpMessage    {        public const string EOF = "\r\n";        public const string SET_ON  = "@00CON_FDP_ON";        public const string SET_OFF = "@00CON_FDP_OFF";        public const string GET_ON  = "@00FDP_ONOK"; // \0\r\n        public const string GET_OFF = "@00FDP_OFFOK"; // \0\r\n        public const string READ_DATA = "@00READ_RUN_PARA";        public const string GET_DATA = "@00RUN_PARA";    }    class SkyPump : PumpBase    {        // ----------------------------Fields--------------------------        //        private const ushort CHK_ST_INTERVAL = 1000;        private const ushort CHK_REC_INTERVAL = 20 * 1000;        private const ushort CHK_PUMP_REC_INTERVAL = 10 * 1000;        private double _total;        private double _fromLast;        private const string EOF = "\r";        private const char MSG_DELIMITER = ' ';        private readonly string _PortNum = "COM91";        private const int _counterMax = 30;        private int _counter = 0;        private string _fdp_Current = null;        private string _roots_Current = null;        private string _fdp_Temp = null;        private string _roots_Temp = null;        private string _n2Flow = null;        private string _pressure = null;        private string _runTime = null;        private readonly AsyncSerialPort _serial;        private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();        private readonly DeviceTimer _timerReceiveStatus = new DeviceTimer();        private readonly DeviceTimer _timerPumpOn = new DeviceTimer();        private readonly DeviceTimer _timerPumpOff = new DeviceTimer();        private readonly DeviceTimer _timerTotal = new DeviceTimer();        private readonly DeviceTimer _timerFromLast = new DeviceTimer();        private readonly R_TRIG _trigPumpOn = new R_TRIG();        private readonly R_TRIG _trigPumpOff = new R_TRIG();        private readonly R_TRIG _trigReceiveStatus = new R_TRIG();        private readonly RD_TRIG _trigOnOff = new RD_TRIG();        private readonly R_TRIG _trigPMNeeded = new R_TRIG();        private StatsDataItemRFAndPump _statPumpOnTime;        // --------------------------Properties------------------------        //        public SkyPumpState StatusDry { get; set; }        public SkyPumpState StatusRoose { get; set; }        public string FDP_Current        {            get            {                return _fdp_Current;            }        }        public string ROOTS_Current        {            get            {                return _roots_Current;            }        }        public string FDP_Temp        {            get            {                return _fdp_Temp;            }        }        public string ROOTS_Temp        {            get            {                return _roots_Temp;            }        }        public string N2Flow        {            get            {                return _n2Flow;            }        }        public string Pressure        {            get            {                return _pressure;            }        }        public string RunTime        {            get            {                return _runTime;            }        }        public string LastPMTime        {            get            {                return _statPumpOnTime != null ? _statPumpOnTime.LastPMTime.ToString() : "";            }        }        public double DaysFromLastPM        {            get            {                return _statPumpOnTime == null ? 0 : _statPumpOnTime.fromLastPM;            }            set            {                if (_statPumpOnTime != null)                    _statPumpOnTime.fromLastPM = value;            }        }        public double TotalDays        {            get            {                return _statPumpOnTime != null ? _statPumpOnTime.Total : 0;            }            set            {                if (_statPumpOnTime != null)                    _statPumpOnTime.Total = value;            }        }        public double PMIntervalDays        {            get            {                return _statPumpOnTime != null ? _statPumpOnTime.PMInterval : 0;            }        }        public bool IsPMNeeded        {            get            {                return DaysFromLastPM > PMIntervalDays;            }        }        public bool EnableAlarm        {            get            {                return _statPumpOnTime == null || _statPumpOnTime.AlarmEnable;            }        }        [Subscription(AITPumpProperty.IsRunning)]        public override bool IsRunning        {            get            {                return StatusDry == SkyPumpState.ON;            }        }        [Subscription(AITPumpProperty.IsError)]        public override bool IsError        {            get            {                return StatusDry == SkyPumpState.ERROR || StatusDry == SkyPumpState.Disconnected;            }        }        public override AITPumpData DeviceData        {            get            {                AITPumpData deviceData = new AITPumpData                {                    DeviceName = Name,                    DeviceModule = Module,                    DeviceSchematicId = DeviceID,                    DisplayName = Display,                    IsError = false,                    IsWarning = false,                    IsOn = IsRunning,                    //WaterFlow = WaterFlowValue,                    IsDryPumpEnable = true,                    IsN2PressureEnable = false,                    IsWaterFlowEnable = false,                    //WaterFlowWarning = WaterFlowWarning,                    //WaterFlowAlarm = WaterFlowAlarm,                    //N2PressureAlarm = N2PressureAlarm,                    //N2PressureWarning = N2PressureWarning,                };                return deviceData;            }        }        // --------------------------Constructor-----------------------        //        public SkyPump(ModuleName mod) : base(mod.ToString(), VirgoDevice.MainPump.ToString(), "SKY pump", "")        {            _PortNum = SC.GetStringValue($"{mod}.DryPump.Port");            StatusDry = SkyPumpState.Unknown;            _serial = new AsyncSerialPort(_PortNum, 9600, 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One, "\r\n", false);        }        public override bool Initialize()        {            base.Initialize();            if (!_serial.Open())            {                StatusDry = SkyPumpState.Disconnected;                EV.PostAlarmLog(this.Module, "Sky Pump serial port open failed");                return false;            }            _statPumpOnTime = StatsDataManager.Instance.GetItemRFAndPump($"{Module}.PumpOnTime");            StatusDry = SkyPumpState.Connected;            _trigPumpOn.RST = true;            _trigPumpOff.RST = true;            _trigReceiveStatus.RST = true;            _serial.OnDataChanged += OnPortDataChanged;            _serial.OnBinaryDataChanged += OnPortBinaryDataChanged;            _serial.OnErrorHappened += OnErrorOccurred;            _timerQueryStatus.Start(CHK_ST_INTERVAL);            _timerReceiveStatus.Start(CHK_REC_INTERVAL);            return true;        }        private void OnPortBinaryDataChanged(byte[] obj)        {            try            {                _timerReceiveStatus.Stop();                _timerReceiveStatus.Start(CHK_REC_INTERVAL);                _trigReceiveStatus.RST = true;                ////if (SC.GetValue<bool>("System.IsSimulatorMode"))                ////{                ////    if (obj.Length != 40 || obj.Length != 15 || obj.Length != 14)                ////        return;                ////}                //bool condition1 = obj.Length >= 14 && Encoding.ASCII.GetString(obj, 12, 2) == SkyPumpMessage.EOF;                //bool condition2 = obj.Length >= 15 && Encoding.ASCII.GetString(obj, 13, 2) == SkyPumpMessage.EOF;                //bool condition3 = obj.Length >= 40 && Encoding.ASCII.GetString(obj, 38, 2) == SkyPumpMessage.EOF;                //bool valid = obj.Length > 2 && (condition1                //                                || condition2                //                                || condition3);                var strData = System.Text.Encoding.ASCII.GetString(obj);                if (strData.Contains(SkyPumpMessage.EOF))                    //if (valid)                {                    string cmd = "";                    if (obj.Length == 14 || obj.Length >= 40)                        cmd = Encoding.ASCII.GetString(obj, 0, 11);                    else if (obj.Length == 15)                        cmd = Encoding.ASCII.GetString(obj, 0, 12);                    if (cmd == SkyPumpMessage.GET_ON)                    {                        _trigPumpOn.CLK = true;                        _timerPumpOn.Start(CHK_PUMP_REC_INTERVAL);                        LOG.Info($"[{Module}] {SkyPumpMessage.GET_ON}");                        return;                    }                    if (cmd == SkyPumpMessage.GET_OFF)                    {                        _trigPumpOff.CLK = true;                        _timerPumpOff.Start(CHK_PUMP_REC_INTERVAL);                        LOG.Info($"[{Module}] {SkyPumpMessage.GET_OFF}");                        return;                    }                    if (cmd == SkyPumpMessage.GET_DATA)                    {                        _fdp_Current = Encoding.ASCII.GetString(obj, 11, 2);                        _roots_Current = Encoding.ASCII.GetString(obj, 13, 2);                        _fdp_Temp = Encoding.ASCII.GetString(obj, 15, 3);                        _roots_Temp = Encoding.ASCII.GetString(obj, 18, 3);                        _n2Flow = Encoding.ASCII.GetString(obj, 21, 2);                        _pressure = Encoding.ASCII.GetString(obj, 23, 4);                        _runTime = Encoding.ASCII.GetString(obj, 27, 5);                        ParaErrSta1(new BitArray(new byte[] { obj[32] }));                        ParaErrSta2(new BitArray(new byte[] { obj[33] }));                        ParaRunSta(new BitArray(new byte[] { obj[34] }));                        //ParaRunSta(new BitArray(new byte[] { obj[35] }));                        ParaErrSta3(new BitArray(new byte[] { obj[36] }));                    }                }                else                {                    if (!SC.GetValue<bool>("System.IsSimulatorMode"))                    {                        LOG.Info($"[{Module}] Sky Pump Data is Invalid:[{strData}]");                    }                                    }            }            catch (Exception ex)            {                if (!SC.GetValue<bool>("System.IsSimulatorMode"))                {                    LOG.Error($"[{Module}] sky pump data para error: [{ex.Message}]");                }            }        }        private void OnErrorOccurred(string obj)        {            //StatusDry = SkyPumpState.ERROR;            LOG.Error($"[{Module}] sky pump error: [{obj}]");        }        private void OnPortDataChanged(string obj)        {            if (string.IsNullOrEmpty(obj))                LOG.Error($"[{Module}] sky pump message IsNullOrEmpty");            try            {                string cmd = obj.ToString().Split('\n')[0].Split('\r')[0];                if (cmd == SkyPumpMessage.GET_ON)                {                    LOG.Info($"[{Module}] {SkyPumpMessage.GET_ON}");                    return;                }                if (cmd == SkyPumpMessage.GET_OFF)                {                    LOG.Info($"[{Module}] {SkyPumpMessage.GET_OFF}");                    return;                }                if (cmd.Substring(0, 11) == SkyPumpMessage.GET_DATA)                {                    _fdp_Current = cmd.Substring(11, 2);                    _roots_Current = cmd.Substring(13, 2);                    _fdp_Temp = cmd.Substring(15, 3);                    _roots_Temp = cmd.Substring(18, 3);                    _n2Flow = cmd.Substring(21, 2);                    _pressure = cmd.Substring(23, 4);                    _runTime = cmd.Substring(27, 5);                    ParaErrSta1(new BitArray(new byte[] { Convert.ToByte(cmd[32]) }));                    ParaErrSta2(new BitArray(new byte[] { Convert.ToByte(cmd[33]) }));                    ParaRunSta(new BitArray(new byte[] { Convert.ToByte(cmd[34]) }));                    //ParaRunSta(new BitArray(new byte[] { Convert.ToByte(cmd[35]) }));                    ParaErrSta3(new BitArray(new byte[] { Convert.ToByte(cmd[36]) }));                }            }            catch(Exception ex)            {                LOG.Error($"[{Module}] sky pump error: [{ex.Message}]");            }        }        public void ParaErrSta1(BitArray bits)        {            for (int i = 0; i < bits.Count; i++)            {                if (bits[i]) ErrSta1(i);            }        }        public void ParaErrSta2(BitArray bits)        {            for (int i = 0; i < bits.Count; i++)            {                if (bits[i]) ErrSta2(i);            }        }        public void ParaErrSta3(BitArray bits)        {            for (int i = 0; i < bits.Count; i++)            {                if (bits[i]) ErrSta3(i);            }        }        public void ParaRunSta(BitArray bits)        {            string sRes = "sky pump status: ";            for (int i = 0; i < bits.Count; i++)            {                if (bits[i])                    sRes += RunStaTure(i);                else                    sRes += RunStaFalse(i);            }            _counter++;            if (_counter == _counterMax)            {                _counter = 0;                //LOG.Info($"[{Module}] {sRes}");            }        }        public string RunStaTure(int code)        {            switch (code)            {                case 7:                    return "Remote。";                case 6:                    StatusDry = SkyPumpState.ON;                    if (_trigPumpOn.Q)                    {                        EV.PostInfoLog(this.Module, $"Dry Pump on");                    }                    if (_trigPumpOff.Q && _timerPumpOff.IsTimeout())                    {                        _trigPumpOff.RST = true;                        EV.PostMessage(Module, EventEnum.DefaultWarning, "Dry Pump off timeout");                    }                    _trigPumpOn.RST = true;                    return "Dry Pump on, ";                case 5:                    StatusRoose = SkyPumpState.ON;                    return "Roots Pump on, ";                case 4:                    return "Pump Cooling Valve Open, ";                case 3:                    return "Cleaning Valve Open, ";                case 2:                    return "Has warn, ";                case 1:                    return "Has error, ";                case 0:                    return "No water, ";                default:                    return "";            }        }        public string RunStaFalse(int code)        {            switch (code)            {                case 7:                    return "Local。";                case 6:                    StatusDry = SkyPumpState.OFF;                    if (_trigPumpOn.Q && _timerPumpOn.IsTimeout())                    {                        _trigPumpOn.RST = true;                        EV.PostMessage(Module, EventEnum.DefaultWarning, "Dry Pump off tiemout");                    }                    if (_trigPumpOff.Q)                    {                        EV.PostInfoLog(this.Module, $"Dry Pump off");                    }                    _trigPumpOff.RST = true;                    return "Dry Pump Off, ";                case 5:                    StatusRoose = SkyPumpState.OFF;                    return "Roots Pump Off, ";                case 4:                    return "Pump Cooling Valve Closed, ";                case 3:                    return "Clean Valve Closed, ";                case 2:                    return "No warn, ";                case 1:                    return "No error, ";                case 0:                    return "Has water, ";                default:                    return "";            }        }        public void ErrSta1(int error)        {            switch (error)            {                case 7:                    LOG.Error($"[{Module}]The above pump frequency converter is malfunctioning except for communication");                    break;                case 6:                    LOG.Error($"[{Module}]The below pump frequency converter is malfunctioning except for communication");                    break;                case 5:                    LOG.Error($"[{Module}]Upper pump contactor");                    break;                case 4:                    LOG.Error($"[{Module}]Lower pump contactor");                    break;                case 3:                    LOG.Error($"[{Module}]Overheating of the upper pump motor");                    break;                case 2:                    LOG.Error($"[{Module}]Pump motor overheating");                    break;                case 1:                    LOG.Error($"[{Module}]EMERGENCY STOP");                    break;                case 0:                    LOG.Error($"[{Module}]Water-Cooling");                    break;                default:                    break;            }        }        public void ErrSta2(int error)        {            switch (error)            {                case 7:                    LOG.Error($"[{Module}]Communication failure of below pump frequency converter");                    break;                case 6:                    LOG.Error($"[{Module}]Communication failure of above pump frequency converter");                    break;                case 5:                    LOG.Error($"[{Module}]Exhaust pressure");                    break;                case 4:                    LOG.Error($"[{Module}]Nitrogen Flow Rate");                    break;                case 3:                    LOG.Error($"[{Module}]The current of the pump below");                    break;                case 2:                    LOG.Error($"[{Module}]The current of the pump above");                    break;                case 1:                    LOG.Error($"[{Module}]The temperature of the pump below");                    break;                case 0:                    LOG.Error($"[{Module}]The temperature of the pump above");                    break;                default:                    break;            }        }        public void ErrSta3(int error)        {            switch (error)            {                case 7:                case 6:                case 5:                case 4:                case 3:                case 2:                    break;                case 1:                    LOG.Error($"[{Module}]The temperature sensor of the pump below is not connected");                    break;                case 0:                    LOG.Error($"[{Module}]The temperature sensor of the pump above is not connected");                    break;                default:                    break;            }        }        public override void Monitor()        {            try            {                // 状态查询                if (_timerQueryStatus.IsTimeout() && this.StatusDry != SkyPumpState.ERROR)                {                    this.SendCmd(SkyPumpMessage.READ_DATA);                    _timerQueryStatus.Start(CHK_ST_INTERVAL);                }                if (_timerReceiveStatus.IsTimeout() && this.StatusDry != SkyPumpState.ERROR)                {                    _trigReceiveStatus.CLK = true;                    if(_trigReceiveStatus.Q)                    {                        EV.PostMessage(Module, EventEnum.DefaultWarning, "Dry Pump Did not Reply");                    }                }                _trigOnOff.CLK = IsRunning;                //第一次检测到打开了,开始计时                if (_trigOnOff.R)                {                    _total = TotalDays;                    _fromLast = DaysFromLastPM;                    _timerTotal.Start(0);                    _timerFromLast.Start(0);                }                //第一次检测到从打开到关闭状态                if (_trigOnOff.T)                {                }                //如果开着,就更新SC                if (_trigOnOff.M)                {                    TotalDays = _total + _timerTotal.GetElapseTime() / 1000 / 60 / 60;                    DaysFromLastPM = _fromLast + _timerFromLast.GetElapseTime() / 1000 / 60 / 60;                }                if (PMIntervalDays > 0)                {                    _trigPMNeeded.CLK = IsPMNeeded;                    if (_trigPMNeeded.Q)                    {                        if (EnableAlarm)                        {                            EV.PostAlarmLog(Module, "pump on time value larger than setting interval days");                        }                    }                }                StatsDataManager.Instance.Increase($"{Module}.PumpOnTime", $"{Module} PumpOnTime", DaysFromLastPM, TotalDays);            }            catch (Exception ex)            {                throw ex;            }        }        private bool SendCmd(string str)        {            return _serial.Write(str + "\r");        }        public override void Reset()        {            _trigPumpOn.RST = true;            _trigPumpOff.RST = true;            _trigReceiveStatus.RST = true;            _trigPMNeeded.RST = true;            //SetPumpOnOff(false);        }        public override void Terminate()        {            //if (StatusDry == SkyPumpState.ON)            //    SetPumpOnOff(false);            _serial?.Close();        }        public override void SetPumpOnOff(bool on)        {            SendCmd(on ? SkyPumpMessage.SET_ON : SkyPumpMessage.SET_OFF);        }    }}
 |