| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 | 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.ParameterCenter;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using FurnaceRT.Devices;using FurnaceRT.Equipments.Systems;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.Event;using MECF.Framework.Common.OperationCenter;using System;using System.Collections;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Xml;namespace FurnaceRT.Equipments.PMs{    public partial class PMModule    {        private string _currentLeakCheckFileName = "";        private Dictionary<int, LeakCheckTableParameter> _leakCheckDic;        private int _currentRetryCount = 0;        private int _currentLeakCheckIndex = -1;        private double _basePressure = -1;        private double _leakCheckDelayStartPressure = 0;        private double _leakCheckDelayMonitorPressure = 0;        private double _leakCheckStartPressure = 0;        private double _leakCheckMonitorPressure = 0;        private double _leakCheckActualLeak = 0;        private bool _isLeakCheckFinished = false;        private Stopwatch _leakCheckDelayTimer = new Stopwatch();        private Stopwatch _leakCheckTimer = new Stopwatch();        private string _leakCheckStatus = "None";        private LeakCheckTableParameter _leakCheckTableParameter = null;        private void InitLeakCheckData()        {            DATA.Subscribe($"{Module}.LeakCheckPressureSensorName", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.PressureSensorName : "");            DATA.Subscribe($"{Module}.LeakCheckTable", () => _leakCheckTableParameter != null ? $"{_leakCheckTableParameter.No}:{_leakCheckTableParameter.Name}" : "0:Not Select");            DATA.Subscribe($"{Module}.LeakCheckHightLimitCommand", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.HightLimitCommand : "None");            DATA.Subscribe($"{Module}.LeakCheckLowLimitCommand", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.LowLimitCommand : "None");            DATA.Subscribe($"{Module}.LeakCheckBasePressureLimitCommand", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.BasePressureLimitCommand : "None");            DATA.Subscribe($"{Module}.LeakCheckErrorCommand", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.ErrorCommand : "None");            DATA.Subscribe($"{Module}.LeakCheckRetryOverCommand", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.RetryOverCommand : "None");            DATA.Subscribe($"{Module}.LeakCheckHighLimit", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.HighLimit : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckLowLimit", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.LowLimit : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckBasePressureLimit", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.BasePressureLimit : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckDelayTime", () => _leakCheckTableParameter != null? _leakCheckTableParameter.DelayTime : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckDelayElapseTime", () => (_leakCheckTableParameter != null && !_leakCheckStatus.Equals("None") && _leakCheckDelayTimer.IsRunning) || _leakCheckTimer.IsRunning ? _leakCheckDelayTimer.ElapsedMilliseconds / 1000 : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckCheckTime", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.CheckTime : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckElapseTime", () => _leakCheckTableParameter != null && !_leakCheckStatus.Equals("None") && _leakCheckTimer.IsRunning ? _leakCheckTimer.ElapsedMilliseconds / 1000 : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckBasePressure", () => _leakCheckTableParameter != null ? _basePressure : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckLeakLimit", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.LeakLimit : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckDelayMonitorPressure", () => _leakCheckTableParameter != null && _leakCheckDelayTimer.IsRunning && !_leakCheckTimer.IsRunning ? (float)_leakCheckDelayMonitorPressure : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckDelayStartPressure", () => _leakCheckTableParameter != null && _leakCheckDelayTimer.IsRunning ? (float)_leakCheckDelayStartPressure : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckMonitorPressure", () => _leakCheckTableParameter != null && _leakCheckDelayTimer.IsRunning && _isLeakCheckFinished ? (float)_leakCheckMonitorPressure : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckStartPressure", () => _leakCheckTableParameter != null && _leakCheckDelayTimer.IsRunning && _leakCheckTimer.IsRunning ? (float)_leakCheckStartPressure : 0.0f);            DATA.Subscribe($"{Module}.LeakCheckActualLeak", () => (float)_leakCheckActualLeak);            DATA.Subscribe($"{Module}.LeakCheckRetryCurrentCount", () => _currentRetryCount);            DATA.Subscribe($"{Module}.LeakCheckRetryLimit", () => _leakCheckTableParameter != null ? _leakCheckTableParameter.RetryLimit : 0);            DATA.Subscribe($"{Module}.LeakCheckStatus", () => _leakCheckStatus);        }        public void SetLeakCheckTableIndex(int index)        {            _leakCheckDelayStartPressure = 0;            _currentLeakCheckIndex = -1;            _basePressure = -1;            _isLeakCheckFinished = false;            _leakCheckActualLeak = 0;            _leakCheckDelayStartPressure = 0;            _leakCheckDelayMonitorPressure = 0;            _leakCheckStartPressure = 0;                    _leakCheckMonitorPressure = 0;            if (_leakCheckDic == null)                return;            var ret = _leakCheckDic.TryGetValue(index, out _leakCheckTableParameter);            if (!ret)                return;            _leakCheckStatus = "BasePressureCheck";            _currentLeakCheckIndex = index;            _basePressure = _leakCheckTableParameter.PressureSensor.Value;                        if (_basePressure > _leakCheckTableParameter.HighLimit && _leakCheckTableParameter.HighLimit > 0)            {                LeakCheckAlarm.Set($"Leak check alarm: PH={_leakCheckTableParameter.HighLimit} < BP={_basePressure}");                ProcessLeakCheckErrorCommand(_leakCheckTableParameter.HightLimitCommand);                return;            }            if (_basePressure > _leakCheckTableParameter.LowLimit && _leakCheckTableParameter.LowLimit > 0 &&                _basePressure <= _leakCheckTableParameter.HighLimit)            {                LeakCheckAlarm.Set($"Leak check alarm: PL={_leakCheckTableParameter.LowLimit} < BP={_basePressure} <= PH={_leakCheckTableParameter.HighLimit}");                ProcessLeakCheckErrorCommand(_leakCheckTableParameter.LowLimitCommand);                return;            }            if (_basePressure < _leakCheckTableParameter.BasePressureLimit && _leakCheckTableParameter.BasePressureLimit > 0)            {                LeakCheckAlarm.Set($"Leak check alarm: BP={_basePressure} < BPLIMIT={_leakCheckTableParameter.HighLimit}");                ProcessLeakCheckErrorCommand(_leakCheckTableParameter.BasePressureLimitCommand);                return;            }            _leakCheckDelayStartPressure = _leakCheckTableParameter.PressureSensor.Value;            _leakCheckDelayTimer.Restart();            _leakCheckDelayStartPressure = _leakCheckTableParameter.PressureSensor.Value;            _leakCheckTimer.Stop();        }        public void InitLeakCheck(string fileName)        {            _leakCheckStatus = "None";            _currentRetryCount = 0;            if (string.IsNullOrEmpty(fileName))            {                return;            }            _currentLeakCheckFileName = fileName;            var content = ParameterFileManager.Instance.LoadParameter("Parameter\\LeakCheckCondition", fileName, false);            if (string.IsNullOrEmpty(content))            {                return;            }            var doc = new XmlDocument();            doc.LoadXml(content);            XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");            if (nodeSteps == null)                nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");            if (nodeSteps == null)            {                EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid leak check file {fileName}");                return;            }            _leakCheckDic = new Dictionary<int, LeakCheckTableParameter>();            for (int i = 0; i < nodeSteps.Count; i++)            {                var step = nodeSteps[i];                XmlElement stepNode = step as XmlElement;                int tableIndex = i + 1;                LeakCheckTableParameter table = new LeakCheckTableParameter();                foreach (XmlAttribute att in stepNode.Attributes)                {                    switch (att.Name)                    {                        case "StepNo":                            int.TryParse(att.Value, out int no);                            table.No = no;                            break;                        case "Name":                            table.Name = att.Value;                            break;                        case "PressSensor":                            table.PressureSensor = DEVICE.GetDevice<IoPressureMeter>($"{Module}.VG13");//给一个默认值,防止LeakCheck没有选择导致报错                            if (!string.IsNullOrEmpty(att.Value))                            {                                var paras = att.Value.Split(':');                                if(paras.Length > 1)                                {                                    table.PressureSensor = DEVICE.GetDevice<IoPressureMeter>($"{Module}.{paras[1]}");                                }                            }                            table.PressureSensorName = att.Value;                            break;                        case "PHHighLimit":                            if (!string.IsNullOrEmpty(att.Value))                            {                                float.TryParse(att.Value, out float value);                                table.HighLimit = value;                            }                            break;                        case "PLLowLimit":                            if (!string.IsNullOrEmpty(att.Value))                            {                                float.TryParse(att.Value, out float value);                                table.LowLimit = value;                            }                            break;                        case "BPLimit":                            if (!string.IsNullOrEmpty(att.Value))                            {                                float.TryParse(att.Value, out float value);                                table.BasePressureLimit = value;                            }                            break;                        case "DelayTime":                            if (!string.IsNullOrEmpty(att.Value))                            {                                float.TryParse(att.Value, out float value);                                table.DelayTime = value;                            }                            break;                        case "CheckTime":                            if (!string.IsNullOrEmpty(att.Value))                            {                                float.TryParse(att.Value, out float value);                                table.CheckTime = value;                            }                            break;                        case "LeakLimit":                            if (!string.IsNullOrEmpty(att.Value))                            {                                float.TryParse(att.Value, out float value);                                table.LeakLimit = value;                            }                            break;                        case "RetryLimit":                            if (!string.IsNullOrEmpty(att.Value))                            {                                int.TryParse(att.Value, out int value);                                table.RetryLimit = value;                            }                            break;                        case "HightLimitCommand":                            table.HightLimitCommand = att.Value;                            break;                        case "LowLimitCommand":                            table.LowLimitCommand = att.Value;                            break;                        case "BasePressureLimitCommand":                            table.BasePressureLimitCommand = att.Value;                            break;                        case "ErrorCommand":                            table.ErrorCommand = att.Value;                            break;                        case "RetryOverCommand":                            table.RetryOverCommand = att.Value;                            break;                    }                }                _leakCheckDic.Add(tableIndex, table);            }        }        public bool CheckLeakCheckFinish()        {            if (_leakCheckStatus == "None")//没在leakCheck状态            {                _currentRetryCount = 0;                return true;            }            if (_leakCheckDic == null || _currentLeakCheckIndex < 0)                return true;            var ret = _leakCheckDic.TryGetValue(_currentLeakCheckIndex, out var leakCheckParameter);            if (!ret)                return true;            if (_isLeakCheckFinished)            {                if (_leakCheckDelayTimer.IsRunning)                    _leakCheckDelayTimer.Stop();                if (_leakCheckTimer.IsRunning)                    _leakCheckTimer.Stop();            }            if (!_leakCheckDelayTimer.IsRunning && !_leakCheckTimer.IsRunning)            {                _leakCheckDelayStartPressure = leakCheckParameter.PressureSensor.Value;                _leakCheckDelayTimer.Restart();            }            if (_leakCheckDelayTimer.IsRunning && _leakCheckDelayTimer.ElapsedMilliseconds >= leakCheckParameter.DelayTime* 1000)            {                _leakCheckStatus = "LeakCheck";                if (!_leakCheckTimer.IsRunning)                {                    _leakCheckDelayMonitorPressure = leakCheckParameter.PressureSensor.Value;                    _leakCheckStartPressure = leakCheckParameter.PressureSensor.Value;                    _leakCheckTimer.Restart();                }                _leakCheckDelayTimer.Stop();            }            else            {                if(!_leakCheckTimer.IsRunning)                    _leakCheckStatus = "LeakCheckDelay";            }            if (_leakCheckTimer.IsRunning && _leakCheckTimer.ElapsedMilliseconds >= leakCheckParameter.CheckTime * 1000)            {                _leakCheckMonitorPressure = leakCheckParameter.PressureSensor.Value;                _leakCheckActualLeak = leakCheckParameter.PressureSensor.Value - _leakCheckStartPressure;                if (_leakCheckActualLeak > leakCheckParameter.LeakLimit)                {                    if (leakCheckParameter.RetryLimit > 0)                    {                        if (_currentRetryCount < leakCheckParameter.RetryLimit)                        {                            _currentRetryCount++;                            _processRoutine.LeakCheckRetry();                            LOG.Write($"Leak check retry {_currentRetryCount}/{leakCheckParameter.RetryLimit}");                        }                        else                        {                            LeakCheckAlarm.Set($"Leak check alarm: already retry count={_currentRetryCount} >= retry limit={leakCheckParameter.RetryLimit}");                            ProcessLeakCheckErrorCommand(leakCheckParameter.RetryOverCommand);                        }                    }                    else                    {                        LeakCheckAlarm.Set($"Leak check alarm: actual leak={_leakCheckActualLeak} > leak limit={leakCheckParameter.LeakLimit}");                        ProcessLeakCheckErrorCommand(leakCheckParameter.ErrorCommand);                    }                    return false;                }                else                {                    _isLeakCheckFinished = true;                    _leakCheckStatus = "None";                    _leakCheckTimer.Stop();                    _leakCheckDelayTimer.Stop();                    LOG.Write($"Leak check completed, leak rate={_leakCheckActualLeak}, delay time={leakCheckParameter.DelayTime}, check time={leakCheckParameter.CheckTime}, leak limit={leakCheckParameter.LeakLimit}, retry info={_currentRetryCount}/{leakCheckParameter.RetryLimit}");                }            }            return _isLeakCheckFinished;        }        public void AbortLeakCheck()        {            _leakCheckStatus = "None";            _currentRetryCount = 0;            if (_leakCheckDelayTimer.IsRunning)                _leakCheckDelayTimer.Stop();            if (_leakCheckTimer.IsRunning)                _leakCheckTimer.Stop();        }        private void ProcessLeakCheckErrorCommand(string command)        {            _isLeakCheckFinished = true;            _leakCheckStatus = "None";            var recipe = "";            var recipeType = "";            var recipeTable = "";            switch (command)            {                case "Reset":                    recipe = SC.GetStringValue("System.Recipe.Reset Recipe");                    recipeType = "Reset";                    CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType);                    LOG.Write($"Leak check: command={command} recipe={recipe}");                    break;                case "End":                    //因为要跳到执行最后一步,所以stepNumber需要减一                    _processRoutine.JumpCurrentRecipeStep(RecipeRunningInfo.RecipeStepList.Count - 1, RecipeRunningInfo.RecipeStepList[RecipeRunningInfo.RecipeStepList.Count - 1].StepName);                    LOG.Write($"Leak check: command={command} step name={RecipeRunningInfo.RecipeStepList[RecipeRunningInfo.RecipeStepList.Count - 1].StepName}");                    break;                case "Hold":                    _processRoutine.PauseRecipe();                    LOG.Write($"Leak check: command={command}");                    break;                case "Monitor":                    LOG.Write($"Leak check: command={command}");                    break;                case "Buzzer":                    Singleton<EquipmentManager>.Instance.IsAlarmConditionBuzzerOn = true;                    LOG.Write($"Leak check: command={command}");                    break;                default:                    if (command.StartsWith("JUMP"))                    {                        //Jump step                        //Jump 1:                        var stepName = command.Replace("JUMP ", "");                        var jumpStepNumber = RecipeRunningInfo.RecipeStepList.FindIndex(x => x.StepName == stepName);                        if (jumpStepNumber > 0)                            _processRoutine.JumpCurrentRecipeStep(jumpStepNumber, stepName);                        LOG.Write($"Leak check: command={command} step name={stepName}");                    }                    else if (command.StartsWith("CALL"))                    {                        //call Alarm recipe                        //Call 1:                        var paras = command.Split(':');                        if (paras.Length > 0)                        {                            recipe = RecipeRunningInfo.Head.AlarmRecipe;                            recipeType = "Alarm";                            recipeTable = paras[0].Replace("CALL", "").Replace(" ", "").Replace(":", "").Replace(":", "");                            CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType, recipeTable);                            LOG.Write($"Leak check: command={command} recipe={recipe}");                        }                    }                    else if (command.StartsWith("ABORT"))                    {                        //call Abort recipe                        //Abort 1:                        var paras = command.Split(':');                        if (paras.Length > 0)                        {                            recipe = RecipeRunningInfo.Head.AbortRecipe;                            recipeType = "Abort";                            recipeTable = paras[0].Replace("ABORT", "").Replace(" ", "").Replace(":", "").Replace(":", "");                            CheckToPostMessage((int)MSG.RunOtherRecipe, recipe, recipeType, recipeTable);                            LOG.Write($"Leak check: command={command} recipe={recipe}");                        }                    }                    break;            }        }        class LeakCheckTableParameter        {            public int No { get; set; }            public string Name { get; set; }            public string PressureSensorName { get; set; }            public IoPressureMeter PressureSensor { get; set; }            public float HighLimit { get; set; } = 0;            public float LowLimit { get; set; } = 0;            public float BasePressureLimit { get; set; } = 0;            public float DelayTime { get; set; } = 0;            public float CheckTime { get; set; } = 0;            public float LeakLimit { get; set; } = 0;            public int RetryLimit { get; set; }            public string HightLimitCommand { get; set; }            public string LowLimitCommand { get; set; }            public string BasePressureLimitCommand { get; set; }            public string ErrorCommand { get; set; }            public string RetryOverCommand { get; set; }        }    }}
 |