123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685 |
- 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串口无法打开");
- 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;
- var strData = System.Text.Encoding.ASCII.GetString(obj);
- if (strData.Contains(SkyPumpMessage.EOF))
- {
- 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 数据无效:[{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 "远程。";
- case 6:
- StatusDry = SkyPumpState.ON;
- if (_trigPumpOn.Q)
- {
- EV.PostInfoLog(this.Module, $"Dry Pump打开");
- }
- if (_trigPumpOff.Q && _timerPumpOff.IsTimeout())
- {
- _trigPumpOff.RST = true;
- EV.PostMessage(Module, EventEnum.DefaultWarning, "Dry Pump 无法关闭");
- }
- _trigPumpOn.RST = true;
- return "干泵开, ";
- case 5:
- StatusRoose = SkyPumpState.ON;
- return "罗茨泵开, ";
- case 4:
- return "泵冷阀开, ";
- case 3:
- return "清洗阀开, ";
- case 2:
- return "有警示, ";
- case 1:
- return "有故障, ";
- case 0:
- return "无水, ";
- default:
- return "";
- }
- }
- public string RunStaFalse(int code)
- {
- switch (code)
- {
- case 7:
- return "本地。";
- case 6:
- StatusDry = SkyPumpState.OFF;
- if (_trigPumpOn.Q && _timerPumpOn.IsTimeout())
- {
- _trigPumpOn.RST = true;
- EV.PostMessage(Module, EventEnum.DefaultWarning, "Dry Pump 无法打开");
- }
- if (_trigPumpOff.Q)
- {
- EV.PostInfoLog(this.Module, $"Dry Pump关闭");
- }
- _trigPumpOff.RST = true;
- return "干泵关, ";
- case 5:
- StatusRoose = SkyPumpState.OFF;
- return "罗茨泵关, ";
- case 4:
- return "泵冷阀关, ";
- case 3:
- return "清洗阀关, ";
- case 2:
- return "无警示, ";
- case 1:
- return "无故障, ";
- case 0:
- return "有水, ";
- default:
- return "";
- }
- }
- public void ErrSta1(int error)
- {
- switch (error)
- {
- case 7:
- LOG.Error($"[{Module}]上泵变频器除通讯外故障");
- break;
- case 6:
- LOG.Error($"[{Module}]下泵变频器除通讯外故障");
- break;
- case 5:
- LOG.Error($"[{Module}]上泵接触器");
- break;
- case 4:
- LOG.Error($"[{Module}]下泵接触器");
- break;
- case 3:
- LOG.Error($"[{Module}]上泵电机过热");
- break;
- case 2:
- LOG.Error($"[{Module}]下泵电机过热");
- break;
- case 1:
- LOG.Error($"[{Module}]急停");
- break;
- case 0:
- LOG.Error($"[{Module}]水冷");
- break;
- default:
- break;
- }
- }
- public void ErrSta2(int error)
- {
- switch (error)
- {
- case 7:
- LOG.Error($"[{Module}]下泵变频器通讯故障");
- break;
- case 6:
- LOG.Error($"[{Module}]上泵变频器通讯故障");
- break;
- case 5:
- LOG.Error($"[{Module}]排气压力");
- break;
- case 4:
- LOG.Error($"[{Module}]氮气流量");
- break;
- case 3:
- LOG.Error($"[{Module}]下泵电流");
- break;
- case 2:
- LOG.Error($"[{Module}]上泵电流");
- break;
- case 1:
- LOG.Error($"[{Module}]下泵温度");
- break;
- case 0:
- LOG.Error($"[{Module}]上泵温度");
- 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}]下泵温度传感器未连接");
- break;
- case 0:
- LOG.Error($"[{Module}]上泵温度传感器未连接");
- 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 没有回复");
- }
- }
- _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);
- }
- }
- }
|