| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069 | using Aitex.Core.RT.DataCenter;using Aitex.Core.RT.Device;using Aitex.Core.RT.Log;using Aitex.Core.RT.OperationCenter;using Aitex.Core.RT.Routine;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using MECF.Framework.Common.Alarm;using MECF.Framework.Common.Algorithm;using MECF.Framework.Common.Beckhoff.ModuleIO;using MECF.Framework.Common.CommonData.Prewet;using MECF.Framework.Common.CommonData.Vpw;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.IOCore;using MECF.Framework.Common.Persistent.Prewet;using MECF.Framework.Common.Persistent.VpwMain;using MECF.Framework.Common.ToolLayout;using PunkHPX8_Core;using PunkHPX8_RT.Devices.VpwCell;using PunkHPX8_RT.Modules;using PunkHPX8_RT.Modules.VpwCelMain;using PunkHPX8_RT.Modules.VpwMain;using SecsGem.Core.ItemModel;using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Net.NetworkInformation;using System.Reflection;using System.Text;using System.Threading.Tasks;using System.Windows.Media.Animation;namespace PunkHPX8_RT.Devices.VpwMain{    public class VpwMainDevice : BaseDevice, IDevice    {        #region 常量         private const string COMMON_DATA = "CommonData";        private const string PERSISTENT_VALUE = "PersistentValue";        private const string CHAMBER_CLOSED = "ChamberClosed";        private const string CHAMBER_OPENED = "ChamberOpened";        private const string CHAMBER_CLOSE = "ChamberClose";        private const string LEAK_DETECTED = "LeakDetected";        private const string VACUUM_PUMP_PRESSURE = "VacuumPumpPressure";        private const string VACUUM_PUMP_POWER = "VacuumPumpPower";        private const string VACUUM_PUMP_ENABLE = "VacuumPumpEnable";        private const string VACUUM_PUMP_SPEED_ENABLE = "VacuumPumpSpeedEnable";        private const string VACUUM_PUMP_SPEED = "VacuumPumpSpeed";        private const string BOOSTER_PUMP_SPEED = "BoosterPumpSpeed";        private const string BOOSTER_PUMP_CURRENT = "BoosterPumpCurrent";        private const string BOOSTER_PUMP_ENABLE = "BoosterPumpEnable";        private const string BOOSTER_PUMP_STATUS = "BoosterPumpStatus";        private const string DIW_ENABLE = "DiwEnable";        private const string DIW_PROCESS = "DiwProcess";        private const string DIW_DEGAS = "DiwDegas";        private const string DIW_TOTAL_FLOW = "DiwTotalFlow";        private const string DIW_PRESSURE = "DiwPressure";        private const string DEGAS_ADJUST = "DegasAdjust";        private const string DEGAS_PURGE = "DegasPurge";        private const string DEGAS_PUMP_ENABLE = "DegasPumpEnable";        private const string DEGAS_PUMP_PRESSURE = "DegasPumpPressure";        #endregion        private enum VPWOperation        {            None,            PumpEnable,            PumpDisable,            HomeAllRotation        }        #region 内部变量        /// <summary>        /// 变量是否初始化字典        /// </summary>        private Dictionary<string, bool> _variableInitializeDic = new Dictionary<string, bool>();        /// <summary>        /// 数据        /// </summary>        private VpwMainCommonData _commonData=new VpwMainCommonData();        /// <summary>        /// 持久性数值        /// </summary>        private VpwMainPersistentValue _vpwMainPersistentValue;        /// <summary>        /// Pump Enable routine        /// </summary>        private BoosterPumpEnableRoutine _boosterPumpEnableRoutine;        /// <summary>        /// Pump Disable routine        /// </summary>        private BoosterPumpDisableRoutine _boosterPumpDisableRoutine;        /// <summary>        /// 上一次Booster泵速        /// </summary>        private short _lastBoosterPumpSpeed = 0;        /// <summary>        /// 定时器任务        /// </summary>        private PeriodicJob _periodicJob;        /// <summary>        /// 是否数据完成初台化        /// </summary>        private bool _isDataInitialized;        /// <summary>        /// pdi控制中的p        /// </summary>        private double _pumpKp;        /// <summary>        /// pdi控制中的i        /// </summary>        private double _pumpKi;        /// <summary>        /// pdi控制中的d        /// </summary>        private double _pumpKd;        /// <summary>        /// flow pdi控制中的p        /// </summary>        private double _pumpFlowKp;        /// <summary>        /// flow pdi控制中的i        /// </summary>        private double _pumpFlowKi;        /// <summary>        /// flow pdi控制中的d        /// </summary>        private double _pumpFlowKd;        /// <summary>        /// Boost pump调速的目标类型        /// </summary>        private VPWBoostPumpTarget _boosterBoostPumpTarget;        /// <summary>        /// Boost pump目标流量        /// </summary>        private double _boosterTargetFlow;        /// <summary>        /// Cell Flow数值        /// </summary>        private double _cellFlow;        /// <summary>        /// 操作当前状态        /// </summary>        private RState _status;        /// <summary>        /// 当前操作        /// </summary>        private VPWOperation _currentOperation;        /// <summary>        /// 启动自动调泵速        /// </summary>        private bool _isStartAutoSpeed;        /// <summary>        /// Home 电机        /// </summary>        private VpwSimpleHomeRoutine _simpleHomeRoutine;        /// <summary>        /// 总流量计时器        /// </summary>        private Stopwatch _totalFlowWatch = new Stopwatch();        /// <summary>        /// 总流量上升沿        /// </summary>        private R_TRIG _totalFlowTrig = new R_TRIG();        /// <summary>        /// 检测到total flow 低于设定条件的时间        /// </summary>        private DateTime _totalFlowAbnormalDetectTime;        /// <summary>        /// 检测到cell flow 满足设定条件的时间        /// </summary>        private bool _totalFlowAbnormal;        #endregion        #region 属性        /// <summary>        /// 数据        /// </summary>        public VpwMainCommonData CommonData { get { return _commonData; } }        /// <summary>        /// Boost Pump目标类型        /// </summary>        public VPWBoostPumpTarget VPWBoostPumpTarget { set { _boosterBoostPumpTarget = value; } }        /// <summary>        /// Booster目标流量        /// </summary>        public double BoostTargetFlow { set { _boosterTargetFlow = value; } }        /// <summary>        /// Cell Flow        /// </summary>        public double CellFlow { set { _cellFlow = value; } }        #endregion        /// <summary>        /// 构造函数        /// </summary>        /// <param name="moduleName"></param>        public VpwMainDevice(string moduleName) : base(moduleName, moduleName, moduleName, moduleName)        {        }        #region 初始化        /// <summary>        /// 初始化        /// </summary>        /// <returns></returns>        public bool Initialize()        {            InitializeParameter();            InitializeRoutine();            SubscribeData();            SubscribeValueAction();            InitializeOperation();            return true;        }        /// <summary>        /// 初始化参数        /// </summary>        private void InitializeParameter()        {            _vpwMainPersistentValue = VpwMainPersistentManager.Instance.GetPersistentValue(Module);            if (_vpwMainPersistentValue != null)            {                _lastBoosterPumpSpeed = _vpwMainPersistentValue.Speed;            }            else            {                LOG.WriteLog(eEvent.ERR_PREWET, Module, "Persistent Value Object is not exist");            }            _commonData.BoosterPumpPressureData = new MECF.Framework.Common.CommonData.CommonLimitData();        }        /// <summary>        /// 初始化Routine        /// </summary>        private void InitializeRoutine()        {            _boosterPumpEnableRoutine = new BoosterPumpEnableRoutine(Module, this);            _boosterPumpDisableRoutine = new BoosterPumpDisableRoutine(Module, this);            _simpleHomeRoutine = new VpwSimpleHomeRoutine(Module.ToString());        }        /// <summary>        /// 订阅        /// </summary>        private void SubscribeData()        {            DATA.Subscribe($"{Module}.{PERSISTENT_VALUE}", () => _vpwMainPersistentValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.{COMMON_DATA}", () => CommonData, SubscriptionAttribute.FLAG.IgnoreSaveDB);            DATA.Subscribe($"{Module}.DiwEnable", () => CommonData.DiwEnable, SubscriptionAttribute.FLAG.IgnoreSaveDB);        }        /// <summary>        /// 订阅数据        /// </summary>        private void SubscribeValueAction()        {            IoSubscribeUpdateVariable(CHAMBER_CLOSED);            IoSubscribeUpdateVariable(CHAMBER_OPENED);            IoSubscribeUpdateVariable(BOOSTER_PUMP_STATUS);            IoSubscribeUpdateVariable(BOOSTER_PUMP_SPEED);            IoSubscribeUpdateVariable(BOOSTER_PUMP_ENABLE);            IoSubscribeUpdateVariable(BOOSTER_PUMP_CURRENT);            IoSubscribeUpdateVariable(DEGAS_PURGE);            IoSubscribeUpdateVariable(DEGAS_ADJUST);            IoSubscribeUpdateVariable(DEGAS_PUMP_PRESSURE);            IoSubscribeUpdateVariable(DEGAS_PUMP_ENABLE);            IoSubscribeUpdateVariable(DIW_ENABLE);            IoSubscribeUpdateVariable(DIW_PROCESS);            IoSubscribeUpdateVariable(DIW_PRESSURE);            IoSubscribeUpdateVariable(DIW_DEGAS);            IoSubscribeUpdateVariable(DIW_TOTAL_FLOW);            IoSubscribeUpdateVariable(VACUUM_PUMP_ENABLE);            IoSubscribeUpdateVariable(VACUUM_PUMP_POWER);            IoSubscribeUpdateVariable(VACUUM_PUMP_PRESSURE);            IoSubscribeUpdateVariable(VACUUM_PUMP_SPEED);            IoSubscribeUpdateVariable(VACUUM_PUMP_SPEED_ENABLE);            IoSubscribeUpdateVariable(LEAK_DETECTED);        }        /// <summary>        /// 初始化变量        /// </summary>        /// <param name="variable"></param>        private void IoSubscribeUpdateVariable(string variable)        {             _variableInitializeDic[variable] = false;            IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);        }        /// <summary>        /// 更新变量数值        /// </summary>        /// <param name="variable"></param>        /// <param name="value"></param>        private void UpdateVariableValue(string variable, object value)        {            if (!_commonData.IsDataInitialized)            {                _commonData.IsDataInitialized = true;                _commonData.BoosterPumpModel = "Manual";            }            PropertyInfo property = _commonData.GetType().GetProperty(variable);            if (property != null)            {                property.SetValue(_commonData, value);            }            if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])            {                _variableInitializeDic[variable] = true;            }            switch (variable)            {                case BOOSTER_PUMP_STATUS:                    string statusContent = _commonData.BoosterPumpStatus ? "On" : "Off";                    _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";                    break;                case DIW_PRESSURE:                    if (double.TryParse(value.ToString(), out var pressure))                    {                        _commonData.BoosterPumpPressureData.Value = pressure;                    }                    break;            }        }        /// <summary>        /// 初始化OP        /// </summary>        private void InitializeOperation()        {            OP.Subscribe($"{Module}.VacuumPumpPowerOn", (cmd,para)=> { return VacuumPumpPowerOn(); });            OP.Subscribe($"{Module}.VacuumPumpPowerOff", (cmd, para) => { return VacuumPumpPowerOff(); });            OP.Subscribe($"{Module}.VacuumPumpEnable", (cmd, para) => { return VacuumPumpEnable(); });            OP.Subscribe($"{Module}.VacuumPumpDisable", (cmd, para) => { return VacuumPumpDisable(); });            OP.Subscribe($"{Module}.VacuumPumpSpeedEnable", (cmd, para) => { return VacuumSpeedEnable(); });            OP.Subscribe($"{Module}.VacuumPumpSpeedDisable", (cmd, para) => { return VacuumSpeedDisable(); });            OP.Subscribe($"{Module}.VacuumPumpSpeed", (cmd, para) => { return WriteVacuumSpeedOperation(cmd, para); });            OP.Subscribe($"{Module}.DegasPumpEnable", (cmd, para) => { return DegasPumpEnable(); });            OP.Subscribe($"{Module}.DegasPumpDisable", (cmd, para) => { return DegasPumpDisable(); });            OP.Subscribe($"{Module}.DegasAdjustOn", (cmd, para) => { return DegasAdjustOn(); });            OP.Subscribe($"{Module}.DegasAdjustOff", (cmd, para) => { return DegasAdjustOff(); });            OP.Subscribe($"{Module}.DegasPurgeOn", (cmd, para) => { return N2PurgeValveOn(); });            OP.Subscribe($"{Module}.DegasPurgeOff", (cmd, para) => { return N2PurgeValveOff(); });            OP.Subscribe($"{Module}.DiwDegasValveOn", (cmd, para) => { return DiwDegasValveOn(); });            OP.Subscribe($"{Module}.DiwDegasValveOff", (cmd, para) => { return DiwDegasValveOff(); });            OP.Subscribe($"{Module}.DiwEnable", (cmd, para) => { return DiwEnable(); });            OP.Subscribe($"{Module}.DiwDisable", (cmd, para) => { return DiwDisable(); });            OP.Subscribe($"{Module}.DiwProcessOn", (cmd, para) => { return DiwProcessOn(); });            OP.Subscribe($"{Module}.DiwProcessOff", (cmd, para) => { return DiwProcessOff(); });            OP.Subscribe($"{Module}.BoosterPumpEnable", BoosterPumpEnableOperation);            OP.Subscribe($"{Module}.BoosterPumpDisable", BoosterPumpDisableOperation);            OP.Subscribe($"{Module}.BoosterPumpSpeed", BoosterPumpSpeedKeyDownOperation);            OP.Subscribe($"{Module}.ChamberUp", (cmd, para) => { return ChamberUp(); });            OP.Subscribe($"{Module}.ChamberDown", (cmd, para) => { return ChamberDown(); });                        OP.Subscribe($"{Module}.BoosterPumpSpeedAuto", (cmd, para) => { return BoosterPumpSpeedAutoOperation(); });            OP.Subscribe($"{Module}.BoosterPumpSpeedManual", (cmd, para) => { return BoosterPumpSpeedManualOperation(); });            OP.Subscribe($"{Module}.DisabledAction", DisabledOperation);            OP.Subscribe($"{Module}.ManualAction", ManualOperation);            OP.Subscribe($"{Module}.AutoAction", AutoOperation);            OP.Subscribe($"{Module}.EngineeringModeAction", EngineeringModeOperation);            OP.Subscribe($"{Module}.ProductionModeAction", ProductionModeOperation);                        OP.Subscribe($"{Module}.HomeAllRotation", HomeAllRotation);        }        #endregion        #region Action        #region HomeAllRotation        public bool HomeAllRotation(string cmd, object[] param)        {            if (_status == RState.Running)            {                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot home all rotation");                return false;            }            _status = _simpleHomeRoutine.Start();            _currentOperation = VPWOperation.HomeAllRotation;            return _status == RState.Running;        }        #endregion        #region Vacum Pump        /// <summary>        /// Pump Power On        /// </summary>        /// <returns></returns>        public bool VacuumPumpPowerOn()        {            return WriteVariableValue(VACUUM_PUMP_POWER, true);        }        /// <summary>        /// Pump Power Off        /// </summary>        /// <returns></returns>        public bool VacuumPumpPowerOff()        {            return WriteVariableValue(VACUUM_PUMP_POWER, false);        }        /// <summary>        /// Pump Enable        /// </summary>        /// <returns></returns>        public bool VacuumPumpEnable()        {            return WriteVariableValue(VACUUM_PUMP_ENABLE, true);        }        /// <summary>        /// Pump Disable        /// </summary>        /// <returns></returns>        public bool VacuumPumpDisable()        {            return WriteVariableValue(VACUUM_PUMP_ENABLE, false);        }        /// <summary>        /// Speed Enable        /// </summary>        /// <returns></returns>        public bool VacuumSpeedEnable()        {            return WriteVariableValue(VACUUM_PUMP_SPEED_ENABLE, true);        }        /// <summary>        /// Speed disable        /// </summary>        /// <returns></returns>        public bool VacuumSpeedDisable()        {            return WriteVariableValue(VACUUM_PUMP_SPEED_ENABLE, false);        }        /// <summary>        /// 写入Vacuum速度        /// </summary>        /// <param name="speed"></param>        /// <returns></returns>        private bool WriteVacuumSpeedOperation(string cmd, object[] param)        {            if (short.TryParse(param[0].ToString(), out var speed))            {                return WriteVariableValue(VACUUM_PUMP_SPEED, speed);            }            else            {                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"Write VacuumSpeed {param[0]} is not short");                return false;            }        }        /// <summary>        /// 写入速度        /// </summary>        /// <param name="speed"></param>        /// <returns></returns>        public bool WriteVacuumSpeed(short speed)        {            return WriteVariableValue(VACUUM_PUMP_SPEED, speed);        }        #endregion        #region Degas Pump        /// <summary>        /// Degas Pump Enable        /// </summary>        /// <returns></returns>        public bool DegasPumpEnable()        {            return WriteVariableValue(DEGAS_PUMP_ENABLE, true);        }        /// <summary>        /// Degas Pump disable        /// </summary>        /// <returns></returns>        public bool DegasPumpDisable()        {            return WriteVariableValue(DEGAS_PUMP_ENABLE, false);        }        /// <summary>        /// Degas Adjust On        /// </summary>        /// <returns></returns>        public bool DegasAdjustOn()        {            return WriteVariableValue(DEGAS_ADJUST, true);        }        /// <summary>        /// Degas Adjust Off        /// </summary>        /// <returns></returns>        public bool DegasAdjustOff()        {            return WriteVariableValue(DEGAS_ADJUST, false);        }        #endregion        #region Booster Pump        /// <summary>        /// Pump Enable操作        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        public bool BoosterPumpEnableOperation(string cmd, object[] param)        {            if (_status == RState.Running)            {                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump enable");                return false;            }            _status = _boosterPumpEnableRoutine.Start();            _currentOperation = VPWOperation.PumpEnable;            return _status == RState.Running;        }        /// <summary>         /// pump disable 操作        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        public bool BoosterPumpDisableOperation(string cmd, object[] param)        {            if (_status == RState.Running)            {                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump disable");                return false;            }            _status = _boosterPumpDisableRoutine.Start();            _currentOperation = VPWOperation.PumpDisable;            return _status == RState.Running;            //return PumpDisable();        }        /// <summary>        /// Booster Pump enable        /// </summary>        /// <returns></returns>        public bool BoosterPumpEnable()        {            return WriteVariableValue(BOOSTER_PUMP_ENABLE, true);        }        /// <summary>        /// Booster Pump Disable        /// </summary>        /// <returns></returns>        public bool BoosterPumpDisable()        {            return WriteVariableValue(BOOSTER_PUMP_ENABLE, false);        }        /// <summary>        /// 写入Booster泵速        /// </summary>        /// <param name="speed"></param>        /// <returns></returns>        public bool BoosterPumpSpeed(short speed=0)        {            return WriteVariableValue(BOOSTER_PUMP_SPEED, speed == 0 ? _lastBoosterPumpSpeed : speed);        }        /// Booster Pump Speed回车操作        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool BoosterPumpSpeedKeyDownOperation(string cmd, object[] param)        {            if (_commonData.BoosterPumpSpeedAuto)            {                LOG.WriteLog(eEvent.ERR_PREWET, Module, "Pump speed is auto,cannot change speed");                return false;            }            short speed = (short)param[0];            bool result = BoosterPumpSpeed(speed);            if (result)            {                _vpwMainPersistentValue.Speed = speed;                _lastBoosterPumpSpeed = speed;                VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);            }            return true;        }        /// <summary>        /// Pump Speed手动模式        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool BoosterPumpSpeedManualOperation()        {            _commonData.BoosterPumpSpeedAuto = false;            _commonData.BoosterPumpModel = "Manual";            string statusContent = _commonData.BoosterPumpStatus ? "On" : "Off";            _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";            return true;        }        /// <summary>        /// Pump Speed自动模式        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool BoosterPumpSpeedAutoOperation()        {            _commonData.BoosterPumpSpeedAuto = true;            _commonData.BoosterPumpModel = "Auto";            string statusContent = _commonData.BoosterPumpStatus ? "On" : "Off";            _commonData.BoosterPumpStatusContent = $"{_commonData.BoosterPumpModel}: {statusContent}";            return true;        }        #endregion        #region Chamber        /// <summary>        /// 上升        /// </summary>        /// <returns></returns>        public bool ChamberUp()        {            return WriteVariableValue(CHAMBER_CLOSE, true);        }        /// <summary>        /// 下降        /// </summary>        /// <returns></returns>        public bool ChamberDown()        {            return WriteVariableValue(CHAMBER_CLOSE, false);        }        #endregion        #region Mode switch        /// <summary>        /// DisabledAction        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool DisabledOperation(string cmd, object[] args)        {            string currentOperation = "Disabled";            VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(Module);            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)            {                string preOperation = _vpwMainPersistentValue.OperatingMode;                if (vpwMainEntity.IsBusy)                {                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Disabled mode");                    return false;                }                vpwMainEntity.EnterInit();                _vpwMainPersistentValue.OperatingMode = currentOperation;                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");            }            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);            return true;        }        /// <summary>        /// ManualAction        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool ManualOperation(string cmd, object[] args)        {            string currentOperation = "Manual";            VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(Module);            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)            {                string preOperation = _vpwMainPersistentValue.OperatingMode;                if (vpwMainEntity.IsBusy)                {                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Manual mode");                    return false;                }                vpwMainEntity.EnterInit();                _vpwMainPersistentValue.OperatingMode = currentOperation;                _boosterBoostPumpTarget = VPWBoostPumpTarget.Pressure;                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");            }            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);            return true;        }        /// <summary>        /// AutoAction        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool AutoOperation(string cmd, object[] args)        {            string currentOperation = "Auto";            VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(Module);            if (vpwMainEntity != null && _vpwMainPersistentValue != null && _vpwMainPersistentValue.OperatingMode != currentOperation)            {                string preOperation = _vpwMainPersistentValue.OperatingMode;                if (vpwMainEntity.IsBusy)                {                    LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"{Module} is Busy, can't switch to Auto mode");                    return false;                }                vpwMainEntity.EnterInit();                _vpwMainPersistentValue.OperatingMode = currentOperation;                LOG.WriteLog(eEvent.INFO_VPWMAIN, Module, $"Operating mode is switched from {preOperation} to {currentOperation}");            }            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);            return true;        }        /// <summary>        /// EngineeringModeAction        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool EngineeringModeOperation(string cmd, object[] args)        {            string currentRecipeOperation = "Engineering";            if (_vpwMainPersistentValue != null)            {                _vpwMainPersistentValue.RecipeOperatingMode = currentRecipeOperation;            }            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);            return true;        }        /// <summary>        /// ProductionAction        /// </summary>        /// <param name="cmd"></param>        /// <param name="param"></param>        /// <returns></returns>        private bool ProductionModeOperation(string cmd, object[] args)        {            string currentRecipeOperation = "Production";            if (_vpwMainPersistentValue != null)            {                _vpwMainPersistentValue.RecipeOperatingMode = currentRecipeOperation;            }            VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);            return true;        }        #endregion        #region DIW        /// <summary>        /// DIW Enable        /// </summary>        /// <returns></returns>        public bool DiwEnable()        {            return WriteVariableValue(DIW_ENABLE, true);        }        /// <summary>        /// DIW Disable        /// </summary>        /// <returns></returns>        public bool DiwDisable()        {            return WriteVariableValue(DIW_ENABLE, false);        }        /// <summary>        /// DIW Process On        /// </summary>        /// <returns></returns>        public bool DiwProcessOn()        {            return WriteVariableValue(DIW_PROCESS, true);        }        /// <summary>        /// DIW Process On        /// </summary>        /// <returns></returns>        public bool DiwProcessOff()        {            return WriteVariableValue(DIW_PROCESS, false);        }        /// <summary>        /// DIW Degas Valve On        /// </summary>        /// <returns></returns>        public bool DiwDegasValveOn()        {            return WriteVariableValue(DIW_DEGAS, true);        }        /// <summary>        /// DIW Degas Valve Off        /// </summary>        /// <returns></returns>        public bool DiwDegasValveOff()        {            return WriteVariableValue(DIW_DEGAS, false);        }        #endregion        #region N2Purge        /// <summary>        /// 打开N2 Purge        /// </summary>        /// <returns></returns>        public bool N2PurgeValveOn()        {            return WriteVariableValue(DEGAS_PURGE, true);        }        /// <summary>        /// 关闭N2 Purge        /// </summary>        /// <returns></returns>        public bool N2PurgeValveOff()        {            return WriteVariableValue(DEGAS_PURGE, false);        }        #endregion        /// <summary>        /// 写变量        /// </summary>        /// <param name="variable"></param>        /// <param name="value"></param>        /// <returns></returns>        private bool WriteVariableValue(string variable, object value)        {            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{variable}");            return IOModuleManager.Instance.WriteIoValue(ioName, value);        }        #endregion        /// <summary>        /// 定时器        /// </summary>        /// <returns></returns>        public bool OnTimer()        {            _commonData.BoosterPumpPressureData.MinError = SC.GetValue<double>($"VPWMain.PumpPressure.Error_Min");            _commonData.BoosterPumpPressureData.MinWarning = SC.GetValue<double>($"VPWMain.PumpPressure.Warning_Min");            _commonData.BoosterPumpPressureData.MaxError = SC.GetValue<double>($"VPWMain.PumpPressure.Error_Max");            _commonData.BoosterPumpPressureData.MaxWarning = SC.GetValue<double>($"VPWMain.PumpPressure.Warning_Max");            _commonData.PressureTarget = SC.GetValue<double>($"VPWMain.PressureTarget");            if (_status == RState.Running)            {                IRoutine routine = GetCurrentRoutine();                if (routine != null)                {                    RState rsState = routine.Monitor();                    if (rsState == RState.Failed || rsState == RState.Timeout)                    {                        _status = RState.Failed;                        _currentOperation = VPWOperation.None;                        LOG.WriteLog(eEvent.ERR_VPWMAIN, Module.ToString(), $"{_currentOperation} error");                        _isStartAutoSpeed = false;                    }                    else if (rsState == RState.End)                    {                        if (_currentOperation == VPWOperation.PumpEnable)                        {                            _isStartAutoSpeed = true;                        }                        else if (_currentOperation == VPWOperation.PumpDisable)                        {                            _isStartAutoSpeed = false;                        }                        _status = RState.End;                        _currentOperation = VPWOperation.None;                    }                }            }            if (_isStartAutoSpeed)            {                AdjustPumpSpeed();            }            MonitorTotalFlow();            BoosterPumpMonitor();            WaterPressureMonitor();            return true;        }        //Speed Auto模式同时pump enbled,对water pressure 上下限进行监控        private void WaterPressureMonitor()        {            if (_commonData.BoosterPumpSpeedAuto && _commonData.BoosterPumpEnable)            {                if(_commonData.DiwPressure > _commonData.BoosterPumpPressureData.MaxError)                {                    LOG.WriteLog(eEvent.ERR_VPW, Module, $"water pressure {_commonData.DiwPressure} is large than Error_max {_commonData.BoosterPumpPressureData.MaxError},Booster Pump Closed!");                    BoosterPumpDisable();                }                else if (_commonData.DiwPressure > _commonData.BoosterPumpPressureData.MaxWarning)                {                    if(!AlarmListManager.Instance.IsContainDataWarn(Module, "WaterPressure"))                    {                        AlarmListManager.Instance.AddWarn(Module, "WaterPressure", $"water pressure {_commonData.DiwPressure} is large than Warning_max {_commonData.BoosterPumpPressureData.MaxWarning}");                        LOG.WriteLog(eEvent.WARN_VPW, Module, $"water pressure {_commonData.DiwPressure} is large than Warning_max {_commonData.BoosterPumpPressureData.MaxWarning}");                    }                 }                else if (_commonData.DiwPressure < _commonData.BoosterPumpPressureData.MinError)                {                    LOG.WriteLog(eEvent.ERR_VPW, Module, $"water pressure {_commonData.DiwPressure} is lower than Error_min {_commonData.BoosterPumpPressureData.MinError},Booster Pump Closed!");                    BoosterPumpDisable();                }                else if (_commonData.DiwPressure < _commonData.BoosterPumpPressureData.MinWarning)                {                    if (!AlarmListManager.Instance.IsContainDataWarn(Module, "WaterPressure"))                    {                        AlarmListManager.Instance.AddWarn(Module, "WaterPressure", $"water pressure {_commonData.DiwPressure} is large than Warning_min {_commonData.BoosterPumpPressureData.MinWarning}");                        LOG.WriteLog(eEvent.WARN_VPW, Module, $"water pressure {_commonData.DiwPressure} is lower than Warning_min {_commonData.BoosterPumpPressureData.MinWarning}");                    }                }            }        }        //total flow不满足条件过一段时间自动关闭增压泵        private void BoosterPumpMonitor()        {            double totalFlowStartLimit = SC.GetValue<double>("VPWMain.Plumbing.TotalFlowStartLowLimit");            int flowFaultHoldOffTime = SC.GetValue<int>($"VPWMain.Plumbing.FlowFaultHoldoffTime");            if (_commonData.DiwTotalFlow < totalFlowStartLimit)            {                if (!_totalFlowAbnormal)                {                    _totalFlowAbnormal = true;                    _totalFlowAbnormalDetectTime = DateTime.Now;                }                if ((DateTime.Now - _totalFlowAbnormalDetectTime).TotalSeconds > flowFaultHoldOffTime && _commonData.BoosterPumpEnable)                {                    LOG.WriteLog(eEvent.WARN_VPW, Module, $"total flow is lower than start limit more than {flowFaultHoldOffTime} min,Booster Pump Closed!");                    BoosterPumpDisable();                    _totalFlowAbnormalDetectTime = DateTime.Now;                }            }            else            {                _totalFlowAbnormal = false;            }        }        /// <summary>        /// 调速        /// </summary>        public void AdjustPumpSpeed()        {            //Speed Auto模式同时pump enbled,根据kdi调整泵速            if (_commonData.BoosterPumpSpeedAuto && _commonData.BoosterPumpEnable)            {                _pumpKp = SC.GetValue<double>($"VPWMain.PumpKp");                _pumpKd = SC.GetValue<double>($"VPWMain.PumpKd");                _pumpKi = SC.GetValue<double>($"VPWMain.PumpKi");                double limit = SC.GetValue<double>("VPWMain.PrewetTargetLimit");                double downLimit = SC.GetValue<double>("VPWMain.PrewetDownTargetLimit");                double minSpeedDelta = SC.GetValue<double>("VPWMain.MinSpeedDelta");                short speed = 0;                if (_boosterBoostPumpTarget == VPWBoostPumpTarget.Pressure)                {                    speed= PdiAlgorithm.Instance.CalculateSpeed(_pumpKp, _pumpKi, _pumpKd, _commonData.PressureTarget,                    _commonData.BoosterPumpPressureData.Value, _lastBoosterPumpSpeed, limit, downLimit, minSpeedDelta);                }                else                {                    speed= PdiAlgorithm.Instance.CalculateSpeed(_pumpFlowKp, _pumpFlowKi, _pumpFlowKd, _boosterTargetFlow,                    _cellFlow, _lastBoosterPumpSpeed, limit, downLimit, minSpeedDelta);                }                //short speed = PdiAlgorithm.Instance.CalculateSpeed(PrewetPumpData.PressureTarget, PrewetPumpData.PumpPressureData.Value,                //    _lastPumpSpeed, limit, downLimit);                if (Math.Abs(speed - _lastBoosterPumpSpeed) >= 1)                {                    _lastBoosterPumpSpeed = speed;                    BoosterPumpSpeed(speed);                }            }        }        /// <summary>        /// 当前Routine;        /// </summary>        /// <returns></returns>        private IRoutine GetCurrentRoutine()        {            switch (_currentOperation)            {                case VPWOperation.PumpEnable:                    return _boosterPumpEnableRoutine;                case VPWOperation.PumpDisable:                    return _boosterPumpDisableRoutine;                case VPWOperation.HomeAllRotation:                    return _simpleHomeRoutine;                default:                    return null;            }        }        /// <summary>        /// 监控总流量         /// </summary>        private void MonitorTotalFlow()        {            double totalFlow = _commonData.DiwTotalFlow;            double totalFlowStartLimit = SC.GetValue<double>("VPWMain.Plumbing.TotalFlowStartLowLimit");            int dripValveOpenIdlePeriod = SC.GetValue<int>("VPWMain.DripValveOpenIdlePeriod")*60*1000;            if (dripValveOpenIdlePeriod == 0)            {                return;            }            if (totalFlow < totalFlowStartLimit&&_totalFlowWatch.IsRunning)            {                LOG.WriteLog(eEvent.INFO_VPW, Module, $"total flow is less then start limit");                _totalFlowWatch.Stop();                return;            }            _totalFlowTrig.CLK = totalFlow >= totalFlowStartLimit;            if (_totalFlowTrig.Q)            {                LOG.WriteLog(eEvent.INFO_VPW, Module, $"total flow is over start limit");                _totalFlowWatch.Start();            }            if (_totalFlowWatch.ElapsedMilliseconds >= dripValveOpenIdlePeriod)            {                LOG.WriteLog(eEvent.INFO_VPW, Module, $"the time of total flow is over DripValveOpenIdlePeriod");                List<VpwCellDevice> vpwCellDevices = new List<VpwCellDevice>();                VpwMainItem vpwMainItem = VpwMainItemManager.Instance.GetItem(ModuleName.VPWMain1.ToString());                if (vpwMainItem == null || vpwMainItem.VpwCells == null)                {                    return;                }                foreach (var item in vpwMainItem.VpwCells)                {                    VpwCellDevice cellDevice = DEVICE.GetDevice<VpwCellDevice>(item.ModuleName);                    vpwCellDevices.Add(cellDevice);                }                _totalFlowWatch.Reset();                foreach (var item in vpwCellDevices)                {                    VpwCellEntity vpwCellEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(item.Module);                    if (vpwCellEntity == null || vpwCellEntity.IsDisable)                    {                        continue;                    }                    if (item.CommonData.FlowDrip)                    {                        continue;                    }                    item.FlowDripOn();                    LOG.WriteLog(eEvent.INFO_VPW, Module, $"{item.Module} open drip valve after DripValveOpenIdlePeriod");                }            }        }        /// <summary>        /// 监控        /// </summary>        public void Monitor()        {        }        public void Reset()        {        }        public void Terminate()        {        }    }}
 |