| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560 | using Aitex.Core.RT.Device;using Aitex.Core.RT.Log;using Aitex.Core.RT.Routine;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.Routine;using PunkHPX8_Core;using PunkHPX8_RT.Devices.VpwCell;using PunkHPX8_RT.Devices.VpwMain;using PunkHPX8_RT.Modules.VpwCell;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace PunkHPX8_RT.Modules.VpwMain{    public class VpwPurgeRoutine : RoutineBase, IRoutine    {        private enum PurgeStep        {            ChameberUp,            SetRotationSpeed,            StartRotation,            CheckRotationRunning,            CloseDiwDegas,            N2PurgeDelay,            CloseN2Purge,            OpenDiwDegas,            FlowDelay,            CheckFlow,            CheckCellFlow,            StopRotation,            CheckStopStatus,            LastHomeRotation,            CheckLastHomeRotation,            CheckFlowOk,            ChamberDown,            LastCheckStatus,            End        }        #region 常量         /// <summary>        /// 增加额外一分钟        /// </summary>        private const int PLUS_TIME = 60000;        #endregion        #region 内部变量        /// <summary>        /// Cell device集合        /// </summary>        private List<VpwCellDevice> _vpwCellDevices = new List<VpwCellDevice>();        /// <summary>        /// Main Device        /// </summary>        private VpwMainDevice _mainDevice;        /// <summary>        /// cell集合        /// </summary>        private List<VpwCellDevice> _cellLst = new List<VpwCellDevice>();        /// <summary>        /// N2 Purge时长        /// </summary>        private int _n2PurgeTime = 15000;        /// <summary>        /// Flow holder off time        /// </summary>        private int _flowFaultHolderoffTime = 15000;        /// <summary>        /// Degas delay时间        /// </summary>        private int _degasEnableDelayTime = 2000;        /// <summary>        /// 旋转速度        /// </summary>        private int _rotationSpeed = 0;        /// <summary>        /// 总流量起始流量数值        /// </summary>        private double _totalFlowStartLimit = 2.0;        /// <summary>        /// Cell起始流量数值        /// </summary>        private double _cellFlowStartLimit = 2.0;        /// <summary>        /// total flow合格        /// </summary>        private bool _totalFlowOk = false;        /// <summary>        /// cell flow合格集合        /// </summary>        private Dictionary<string, bool> _cellFlowOk = new Dictionary<string, bool>();        /// <summary>        /// 检验流量是否ok        /// </summary>        private bool _checkFlowOk = false;        /// <summary>        /// 总流量        /// </summary>        private double _totalFlow = 0;        /// <summary>        /// Cell注意集合        /// </summary>        private Dictionary<string, double> _cellFlows = new Dictionary<string, double>();        /// <summary>        /// 检验chamber是否上升/下降到位        /// </summary>        private int _checkChamberUpDownTimes = 3;        #endregion        /// <summary>        /// 构造函数        /// </summary>        /// <param name="module"></param>        /// <param name="device"></param>        public VpwPurgeRoutine(string module) : base(module)        {        }        /// <summary>        /// 中止        /// </summary>        public void Abort()        {            Runner.Stop("Purge abort");        }        /// <summary>        /// 监控        /// </summary>        /// <returns></returns>        public RState Monitor()        {            Runner.Run(PurgeStep.ChameberUp, _mainDevice.ChamberUp, CheckChamberClosed, _checkChamberUpDownTimes*1000)                .Run(PurgeStep.SetRotationSpeed, SetRotationSpeed, _delay_1s)                .Run(PurgeStep.StartRotation, StartRotation, _delay_1ms)                .Wait(PurgeStep.CheckRotationRunning, CheckRotationRunningStatus, 500)                .Run(PurgeStep.CloseDiwDegas, CloseDiwDegas)                .Delay(PurgeStep.N2PurgeDelay, _n2PurgeTime)                .Run(PurgeStep.CloseN2Purge, _mainDevice.N2PurgeValveOff, _delay_1ms)                .Run(PurgeStep.OpenDiwDegas, OpenDiwDegas, _delay_1ms)                .Delay(PurgeStep.FlowDelay, _flowFaultHolderoffTime)                .Run(PurgeStep.CheckFlow, CheckTotalFlow, _delay_1ms)                .Run(PurgeStep.CheckCellFlow, CheckCellFlow, _delay_1ms)                .Run(PurgeStep.StopRotation, StopRotationAxis, _delay_1ms)                .WaitWithStopCondition(PurgeStep.CheckStopStatus, CheckStopPostionEndStatus, CheckStopPostionStopStatus)                .Run(PurgeStep.LastHomeRotation, HomeAllRotation, _delay_1ms)                .WaitWithStopCondition(PurgeStep.CheckLastHomeRotation, CheckAllRotationHomeStatus, CheckAllRotationHomeStopStatus)                .Run(PurgeStep.CheckFlowOk, CheckFlowOk, _delay_1ms)                .RunIf(PurgeStep.ChamberDown, _checkFlowOk, () => { return _mainDevice.ChamberDown(); },                    () => { return !_mainDevice.CommonData.ChamberClosed && _mainDevice.CommonData.ChamberOpened; })                .Run(PurgeStep.LastCheckStatus, LastCheckResult, _delay_1ms)                .End(PurgeStep.End, NullFun, _delay_1ms);            return Runner.Status;        }        /// <summary>        /// 检验Chamber关闭        /// </summary>        /// <returns></returns>        private bool CheckChamberClosed()        {            return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;        }        private bool SetRotationSpeed()        {            bool result = true;            foreach (var item in _cellLst)            {                result &= item.SetRotationSpeed(_rotationSpeed);            }            return result;        }        /// <summary>        /// 打开所有cell valve        /// </summary>        /// <returns></returns>        private bool OpenCellDrainValve()        {            foreach (var device in _cellLst)            {                bool result = device.DrainValveOn();                if (!result)                {                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{device.Module} open drain valve failed");                    CloseCellDrainValve();                    return false;                }            }            return true;        }        /// <summary>        /// 检验Cell Drain状态        /// </summary>        /// <returns></returns>        private bool CheckCellDrainValveStatus()        {            foreach (var item in _cellLst)            {                bool result = item.CommonData.DrainValve;                if (!result)                {                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{item.Module} drain valve is not opened");                    CloseCellDrainValve();                    return false;                }            }            return true;        }        /// <summary>        /// 关闭所有cell的Drain valve        /// </summary>        private void CloseCellDrainValve()        {            foreach (var item in _cellLst)            {                item.DrainValveOff();            }        }        /// <summary>        /// Home All Rotation        /// </summary>        /// <returns></returns>        private bool HomeAllRotation()        {            foreach (var item in _cellLst)            {                bool result = item.HomeRotation();                if (!result)                {                    CloseCellDrainValve();                    return false;                }            }            return true;        }        /// <summary>        /// 检验所有Rotation Home成功        /// </summary>        /// <returns></returns>        private bool CheckAllRotationHomeStatus()        {            int count = 0;            foreach (var item in _cellLst)            {                bool result = item.CheckHomeEndStatus();                if (result)                {                    count++;                }            }            bool success = count == _cellLst.Count;            if (success)            {                foreach (var item in _cellLst)                {                    item.SetRotationSpeed(_rotationSpeed);                }            }            return success;        }        /// <summary>        /// rotation电机 home是否停止        /// </summary>        /// <returns></returns>        private bool CheckAllRotationHomeStopStatus()        {            foreach (var item in _cellLst)            {                bool result = item.CheckRotationStopStatus();                if (result)                {                    return true;                }            }            return false;        }        /// <summary>        /// 启动rotation        /// </summary>        /// <returns></returns>        private bool StartRotation()        {            int totalTime = (_n2PurgeTime + _flowFaultHolderoffTime+ PLUS_TIME) / 1000;            int targetPsition = _rotationSpeed * totalTime;            foreach (var item in _cellLst)            {                bool result = item.RotationProfilePosition(targetPsition);                if (!result)                {                    StopAllRotation();                    return false;                }            }            return true;        }        /// <summary>        /// 检验Rotation是否运动        /// </summary>        /// <returns></returns>        private bool CheckRotationRunningStatus()        {            foreach (var item in _cellLst)            {                bool result = item.CheckRotationRunning();                if (!result)                {                    StopAllRotation();                    return false;                }            }            return true;        }        /// <summary>        /// 停止所有rotation电机        /// </summary>        private void StopAllRotation()        {            foreach (var item in _cellLst)            {                item.StopProfilePosition();            }        }        /// <summary>        /// 关闭DiwDegas等        /// </summary>        /// <returns></returns>        private bool CloseDiwDegas()        {            int count = 0;            count += _mainDevice.DiwDegasValveOff() ? 1 : 0;            count += _mainDevice.N2PurgeValveOn() ? 1 : 0;            foreach (var item in _cellLst)            {                count += item.FlowDripOn() ? 1 : 0;                count += item.FlowSmallOn() ? 1 : 0;                count += item.FlowLargeOn() ? 1 : 0;            }            return count == _cellLst.Count * 3 + 2;        }        /// <summary>        /// 打开DiwDegas        /// </summary>        /// <returns></returns>        private bool OpenDiwDegas()        {            return _mainDevice.DiwDegasValveOn();        }        /// <summary>        /// 检验流量        /// </summary>        /// <returns></returns>        private bool CheckTotalFlow()        {            double totalFlow = _mainDevice.CommonData.DiwTotalFlow;            if (totalFlow < _totalFlowStartLimit)            {                _totalFlowOk = false;            }            else            {                _totalFlowOk = true;            }            _totalFlow = totalFlow;            return true;        }        /// <summary>        /// 检验CellFlow        /// </summary>        /// <returns></returns>        private bool CheckCellFlow()        {            foreach (var item in _cellLst)            {                double cellFlow = item.CommonData.DiwFlow;                if (cellFlow < _cellFlowStartLimit)                {                    _cellFlowOk[item.Module] = false;                }                else                {                    _cellFlowOk[item.Module] = true;                    item.FlowSmallOff();                    item.FlowLargeOff();                }                _cellFlows[item.Module] = cellFlow;            }            return true;        }        /// <summary>        /// 停止rotation        /// </summary>        /// <returns></returns>        public bool StopRotationAxis()        {            foreach (var item in _cellLst)            {                bool result = item.StopProfilePosition();                if (!result)                {                    return false;                }            }            return true;        }        /// <summary>        /// 检验停止是否完成        /// </summary>        /// <returns></returns>        public bool CheckStopPostionEndStatus()        {            foreach (var item in _cellLst)            {                bool result = item.CheckRotationEndStatus();                if (!result)                {                    return false;                }            }            return true;        }        /// <summary>        /// 检验停止失败状态        /// </summary>        /// <returns></returns>        public bool CheckStopPostionStopStatus()        {            foreach (var item in _cellLst)            {                bool result = item.CheckRotationStopStatus();                if (result)                {                    return true;                }            }            return false;        }        /// <summary>        /// 检验流量是否ok        /// </summary>        /// <returns></returns>        private bool CheckFlowOk()        {            if (!_totalFlowOk)            {                _checkFlowOk = false;                return true;            }            foreach (var item in _cellLst)            {                if (!_cellFlowOk[item.Module])                {                    _checkFlowOk = false;                    return true;                }            }            _checkFlowOk = true;            return true;        }        /// <summary>        /// 最后确认结果        /// </summary>        /// <returns></returns>        private bool LastCheckResult()        {            AllCellPostMsg();            if (_totalFlowOk)            {                return true;            }            else            {                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"total flow {_totalFlow} is less than {_totalFlowStartLimit}");                return false;            }        }        /// <summary>        /// 所有cell推送消息        /// </summary>        private void AllCellPostMsg()        {            foreach (var item in _cellLst)            {                VpwCellEntity vpwCellEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(item.Module);                if (!_cellFlowOk[item.Module])                {                    vpwCellEntity.PostMsg((int)VPWCellMsg.Error);                    LOG.WriteLog(eEvent.WARN_VPW, item.Module, $"cell flow {_cellFlows[item.Module]} is less than {_cellFlowStartLimit}");                }            }        }        /// <summary>        /// 检验Rotation电机是否上电        /// </summary>        /// <param name="device"></param>        /// <returns></returns>        private bool CheckRotationSwitchOn(VpwCellDevice device)        {            if (!device.CheckRotationSwitchOn())            {                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{device.Module} rotation is not switch on");                return false;            }            return true;        }        /// <summary>        /// 启动        /// </summary>        /// <param name="objs"></param>        /// <returns></returns>        public RState Start(params object[] objs)        {            List<VpwCellDevice> lstDevice = (List<VpwCellDevice>)objs[0];            _vpwCellDevices.Clear();            _cellFlows.Clear();            _cellLst.Clear();            _cellFlowOk.Clear();            _totalFlowOk = false;            _checkFlowOk = false;            _totalFlow = 0;            for (int i = 0; i < lstDevice.Count; i++)            {                _vpwCellDevices.Add(lstDevice[i]);                VpwCellEntity vpwCellEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(lstDevice[i].Module);                if (vpwCellEntity.IsAuto || vpwCellEntity.IsManual)                {                    _cellLst.Add(lstDevice[i]);                    if (!CheckRotationSwitchOn(lstDevice[i]))                    {                        return RState.Failed;                    }                    _cellFlowOk[lstDevice[i].Module] = false;                }            }            _mainDevice = DEVICE.GetDevice<VpwMainDevice>(Module.ToString());            _n2PurgeTime = SC.GetValue<int>("VPWMain.Plumbing.N2PurgeTime");            _flowFaultHolderoffTime = SC.GetValue<int>("VPWMain.Plumbing.FlowFaultHoldoffTime");            double purgeMotorSpeed = SC.GetValue<double>("VPWMain.Plumbing.PurgeMotorSpeed");            _rotationSpeed = (int)(Math.Round(purgeMotorSpeed * 360 / 60, 0));            _totalFlowStartLimit = SC.GetValue<double>("VPWMain.Plumbing.TotalFlowStartLowLimit");            _cellFlowStartLimit = SC.GetValue<double>("VPWMain.Plumbing.CellFlowStartLowLimit");            _degasEnableDelayTime = SC.GetValue<int>("VPWMain.Plumbing.DegasEnableDelayTime");            _checkChamberUpDownTimes = SC.GetValue<int>("VPWMain.ChamberUpDownCheckTime");            return Runner.Start(Module, "VPW Purge");        }     }}
 |