Sic08/Modules/Mainframe/PMs/Routines/PMMfcValueTestRoutine.cs

806 lines
28 KiB
C#
Raw Normal View History

using Aitex.Common.Util;
using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.DBCore;
using Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Aitex.Core.Common.DeviceData.IoDevice;
using MECF.Framework.Common.Equipment;
using SicModules.PMs.Routines.Base;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Aitex.Core.RT.Log;
using Newtonsoft.Json;
namespace SicModules.PMs.Routines
{
public delegate bool ConditionMethodDelegate(string name, double value, out string reason);
public class PMMfcValueTestRoutine : PMBaseRoutine
{
enum RoutineStep
{
SetOpenOrClose,
OpenMfc,
TimeDelay,
Inspect,
CloseMfc,
SetReset,
WriteDatabase
}
/// <summary>
/// XML配置中Mfc名称
/// </summary>
public List<string> MfcNameList = new List<string>();
/// <summary>
/// XML配置中气阀名称
/// </summary>
public List<string> ValueNameList = new List<string>();
/// <summary>
/// XML配置中PC名称
/// </summary>
public List<string> PCNameList = new List<string>();
/// <summary>
/// MFC所有测试数据
/// </summary>
public List<MfcTestData> MfcTestList { get; set; } = new List<MfcTestData>();
/// <summary>
/// 气阀所有测试数据
/// </summary>
public List<ControlNameData> ValueTestList { get; set; } = new List<ControlNameData>();
/// <summary>
/// PC所有测试数据
/// </summary>
public List<ControlNameData> PCTestList { get; set; } = new List<ControlNameData>();
/// <summary>
/// 单个MFC测试数据
/// </summary>
public MfcTestData MfcTest = new MfcTestData();
/// <summary>
/// 输入项数据,重要用来存储数据库操作对象,保存输入条件中,所有气阀/PC/MFC测试结果
/// </summary>
public List<ControlNameData> AllControlNameDataList { get; set; } = new List<ControlNameData>();
private ControlNameData ControlNameData = new ControlNameData();
private List<MfcTestCondition> mfcDoTestList = new List<MfcTestCondition>();
private MfcTestCondition mfcDoTest = new MfcTestCondition();
ConditionMethodDelegate MethodDelegate;
private string moduleName;
private PMModule _pmModule;
private string MfcName;
private double _timeDelay;
private double _scValue;
private double _mfcDefaultValue;
private double _upperLimit;
private Stopwatch _swTimer = new Stopwatch();
private string _startTime;
private string _endTime;
2023-06-27 19:43:46 +08:00
private string _mfcValueConfigPath = PathManager.GetCfgDir() + @"PM\MfcDeviationValue\MfcTest.xml";
private string _controlUnitConfigPath = PathManager.GetCfgDir() + @"PM\MfcDeviationValue\ControlUnit.xml";
public PMMfcValueTestRoutine(ModuleName module, PMModule pm) : base(module, pm)
{
moduleName = module.ToString();
_pmModule = pm;
Name = "MfcValueTest";
MethodDelegate += SetValve;
MethodDelegate += SetPC;
MethodDelegate += SetMfcState;
InitializeMfc();
InitializeValue();
InitializeDataList();
}
private void InitializeMfc()
{
string reason = string.Empty;
try
{
XmlDocument xml = new XmlDocument();//初始化一个xml实例
xml.Load(_mfcValueConfigPath);
XmlElement root = xml.DocumentElement;
XmlNodeList nodelist = root.ChildNodes;
//遍历输出.
foreach (XmlNode node in nodelist)
{
MfcTestCondition mfcDoTest = new MfcTestCondition();
var nodeBlocks = node.SelectNodes("Condition/Names/Name");
if (nodeBlocks != null)
{
foreach (var nodeBlock in nodeBlocks)
{
if (!(nodeBlock is XmlElement xmlBlock))
{
continue;
}
mfcDoTest.Name = xmlBlock.GetAttribute("Name");
}
}
nodeBlocks = node.SelectNodes("Condition/Inputs/Input");
if (nodeBlocks != null)
{
foreach (var nodeBlock in nodeBlocks)
{
if (!(nodeBlock is XmlElement xmlBlock))
{
continue;
}
NameValue keyValue = new NameValue()
{
Name = xmlBlock.GetAttribute("Name"),
Value = Convert.ToDouble(xmlBlock.GetAttribute("Value")),
ControlName = xmlBlock.GetAttribute("ControlName")
};
mfcDoTest.StateList.Add(keyValue);
}
}
nodeBlocks = node.SelectNodes("Condition/Outputs/Output");
if (nodeBlocks != null)
{
foreach (var nodeBlock in nodeBlocks)
{
if (!(nodeBlock is XmlElement xmlBlock))
{
continue;
}
NameValue keyValue = new NameValue()
{
Name = xmlBlock.GetAttribute("Name"),
Value = Convert.ToDouble(xmlBlock.GetAttribute("Value")),
ControlName = xmlBlock.GetAttribute("ControlName")
};
mfcDoTest.CarryOut = keyValue;
}
}
2023-06-27 19:43:46 +08:00
if (mfcDoTest.Name is not null)
mfcDoTestList.Add(mfcDoTest);
}
}
catch (Exception ex)
{
LOG.Error(ex.Message, ex);
}
}
private void InitializeValue()
{
string reason = string.Empty;
try
{
XmlDocument xml = new XmlDocument();//初始化一个xml实例
xml.Load(_controlUnitConfigPath);
XmlElement root = xml.DocumentElement;
XmlNodeList nodelist = root.ChildNodes;
//遍历输出.
foreach (XmlNode node in nodelist)
{
var nodeBlocks = node.SelectNodes("Condition/Mfcs/Mfc");
if (nodeBlocks != null)
{
foreach (var nodeBlock in nodeBlocks)
{
if (!(nodeBlock is XmlElement xmlBlock))
{
continue;
}
MfcNameList.Add(xmlBlock.GetAttribute("Name"));
}
}
nodeBlocks = node.SelectNodes("Condition/Values/Value");
if (nodeBlocks != null)
{
foreach (var nodeBlock in nodeBlocks)
{
if (!(nodeBlock is XmlElement xmlBlock))
{
continue;
}
ValueNameList.Add(xmlBlock.GetAttribute("Name"));
}
}
nodeBlocks = node.SelectNodes("Condition/PCs/PC");
if (nodeBlocks != null)
{
foreach (var nodeBlock in nodeBlocks)
{
if (!(nodeBlock is XmlElement xmlBlock))
{
continue;
}
PCNameList.Add(xmlBlock.GetAttribute("Name"));
}
}
}
}
catch (Exception ex)
{
LOG.Error(ex.Message, ex);
}
}
private void InitializeDataList()
{
//初始化所有MFC
foreach (var name in MfcNameList)
MfcTestList.Add(new MfcTestData() { MfcName = name });
QueryAllMfcTestData();
//初始化所有气阀
foreach (var name in ValueNameList)
ValueTestList.Add(new ControlNameData() { ControlName = name });
//初始化所有PC
foreach (var name in PCNameList)
PCTestList.Add(new ControlNameData() { ControlName = name });
string str= JsonConvert.SerializeObject(ValueTestList);
QueryAllControlNameData();
}
public void DelectAllData()
{
foreach (var item in MfcTestList)
item.Delect();
foreach (var item in ValueTestList)
item.Delect();
foreach (var item in PCTestList)
item.Delect();
//truncate table
DB.ExcuteTransAction(new List<string> { "truncate control_name_data", "truncate mfc_test_data" });
}
public override Result Start(params object[] objs)
{
MfcTest = new MfcTestData();
AllControlNameDataList = new List<ControlNameData>();
Reset();
string selectedMfcName = (string)objs[0];
mfcDoTestList.ForEach(t =>
{
if (t.Name == selectedMfcName)
mfcDoTest = t;
});
MfcName = selectedMfcName.Contains("s") ? selectedMfcName.Replace("s", "") : selectedMfcName;
//开始测试
//有一个集合为空,不用循环
if (mfcDoTest.StateList.Count == 0 || mfcDoTest.CarryOut.Name == null)
return Result.FAIL;
_timeDelay = SC.GetValue<int>($"PM.MfcTestingDelayedTime");
_upperLimit = SC.GetValue<int>($"PM.{Module}.ThrottlePressureTimeout");
_mfcDefaultValue = SC.GetValue<double>($"PM.{Module}.MFC.{MfcName}.DefaultSetPoint") * mfcDoTest.CarryOut.Value;//将mfc设定到表XML中设定的倍数
_scValue = SC.GetValue<double>($"PM.MfcTestingPercentage");//上限参数
_startTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
_swTimer.Restart();
//初始化MFC操作对象,做界面显示用
MfcTest.MfcName = selectedMfcName;
MfcTest.Module = moduleName;
MfcTest.Result = "";
MfcTest.Values = "";
MfcTest.Infor = "";
MfcTest.BaseValue = _mfcDefaultValue.ToString();
Notify($"Start {MfcName} Test");
return Result.RUN;
}
public override Result Monitor()
{
try
{
//根据XML配置测试气路打开或关闭气阀、PC、MFC
PreSetValve((int)RoutineStep.SetOpenOrClose, false);
//打开要测试的MFC
PreMfcRamp((int)RoutineStep.OpenMfc, _mfcDefaultValue);
//延时等待气流上升
TimeDelay((int)RoutineStep.TimeDelay, _timeDelay);
//统计数据,并分析结果
PreInspect((int)RoutineStep.Inspect);
//关闭检测的MFC
PreMfcRamp((int)RoutineStep.CloseMfc, 0);
//根据XML配置测试气路关闭气阀、PC、MFC
PreSetValve((int)RoutineStep.SetOpenOrClose, true);
//数据结果写入数据库
PreWriteDatabase((int)RoutineStep.WriteDatabase);
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
_swTimer.Stop();
return Result.DONE;
}
protected void PreSetValve(int id, bool isReset)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
if (!SetInputs(isReset, out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
private bool SetInputs(bool isReset, out string reason)
{
reason = "";
for (int i = 0; i < mfcDoTest.StateList.Count; i++)
{
if (!MethodDelegate(mfcDoTest.StateList[i].ControlName, isReset ? 0 : mfcDoTest.StateList[i].Value, out reason))
return false;
}
return true;
}
private bool SetValve(string ioValveName, double value, out string reason)
{
reason = "";
if (!ioValveName.Contains("V"))
return true;
bool isOpen = value == 1 ? true : false;
var ioValve = DEVICE.GetDevice<IoValve>($"{moduleName}.{ioValveName}");
if (ioValve.TurnValve(isOpen, out reason))
return true;
reason = $" {(isOpen ? "Open" : "Close")} {ioValve} failed , {reason}";
return false;
}
private bool SetPC(string pcName, double value, out string reason)
{
reason = "";
if (!pcName.Contains("PC"))
return true;
var isOpen = value == 1 ? PcCtrlMode.Open : PcCtrlMode.Close;
var pc = DEVICE.GetDevice<IoPressure>($"{moduleName}.{pcName}");
if (pc.SetPcMode(isOpen, out reason))
return true;
reason = $" {isOpen} {pcName} failed , {reason}";
return false;
}
private bool SetMfcState(string mfcName, double value, out string reason)
{
reason = "";
if (!mfcName.Contains("M"))
return true;
var isOpen = value == 1 ? MfcCtrlMode.Open : MfcCtrlMode.Close;
var mfc = DEVICE.GetDevice<IoMFC>($"{moduleName}.{mfcName}");
if (mfc.SetMfcMode(isOpen, out reason))
return true;
reason = $" {isOpen} {mfcName} failed , {reason}";
return false;
}
protected void PreMfcRamp(int id, double value)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"{mfcDoTest.CarryOut.ControlName} ramp to {value} ");
MfcRamp(value);
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
private void MfcRamp(double value)
{
var mfc = DEVICE.GetDevice<IoMFC>($"{Module}.{MfcName}");
mfc.Ramp(value, 0);
}
protected void PreInspect(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Inspect values ");
Inspect();
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
/// <summary>
/// 对结果进行检查,赋值各种数据作为显示使用
/// </summary>
/// <param name="mfc"></param>
/// <param name="mfcDefaultDoubleValue"></param>
private void Inspect()
{
try
{
var mfc = DEVICE.GetDevice<IoMFC>($"{Module}.{MfcName}");
double volue = 0;
List<double> volueList = new List<double>();
StringBuilder strResult = new StringBuilder();
StringBuilder strValues = new StringBuilder();
for (int i = 0; i < 10; i++)
{
double feedBack = mfc.FeedBack;
volue = (feedBack - _mfcDefaultValue) / _mfcDefaultValue * 100;
volueList.Add(volue);
strValues.Append($"<{i + 1}>{feedBack.ToString("0.00")} ; ");
strResult.Append($"<{i + 1}>{volue.ToString("0.00")}% ; ");
System.Threading.Thread.Sleep(500);
}
EV.PostInfoLog($"{Module}", $" {MfcName} FeedBack Value {strValues} ");
EV.PostInfoLog($"{Module}", $" {MfcName} Deviation Value {strResult} ");
MfcTest.Values = strValues.ToString();
MfcTest.Result = strResult.ToString();
strResult.Clear();//清空后存储气路元器件名称
foreach (var item in mfcDoTest.StateList)
{
string operation = item.Value == 1 ? "Open" : "Close";
strResult.Append(item.Name + $"-{operation}; ");//提取所有气阀名称,打印输出用
}
for (int i = 0; i < volueList.Count; i++)
{
if (Math.Abs(volueList[i]) > _scValue)//循环判断是否有超设定值
{
EV.PostInfoLog($"{Module}", $" {MfcName} test failed,Please check {strResult}");
MfcTest.Infor = strResult.ToString();
MfcTest.IsPass = "NG";
return;
}
}
MfcTest.Infor = strResult.ToString();
MfcTest.IsPass = "OK";
}
catch (Exception ex)
{
EV.PostAlarmLog($"{Module}", $" failed {ex}");
return;
}
}
protected void PreWriteDatabase(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
if (!WriteDatabase(out string reason))
{
Stop(reason);
return false;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
private bool WriteDatabase(out string reason)
{
try
{
reason = "";
Notify($"Test over updata to database");
MfcTest.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
ReceiveMfcTestData();//MFC数据库操作
ReceiveControlNameData();//气阀数据库操作
return true;
}
catch (Exception ex)
{
reason = ex.Message;
return false;
}
}
#region MFC数据库操作
public void ReceiveMfcTestData()
{
UpdataMfcTestData();
UpdateMfcTestDataDatabase();
QueryAllMfcTestData();
}
private void UpdataMfcTestData()
{
foreach (var data in MfcTestList)
{
if (data.MfcName == MfcTest.MfcName)
{
data.Update(MfcTest);
return;
}
}
}
private void UpdateMfcTestDataDatabase()
{
string cmdID = $"select * from mfc_test_data where mfc_name = '{MfcTest.MfcName}'";
var dt = DB.ExecuteDataset(cmdID);
if (dt is null || dt.Tables[0].Rows.Count == 0)
DB.ExcuteTransAction(new List<string>() { InsertMfcTestDataCmd() });
else
DB.ExcuteTransAction(new List<string>() { UpdateMfcTestDataCmd() });
}
private string InsertMfcTestDataCmd()
{
string cmd_data_insert =
"insert into mfc_test_data" +
"(module,mfc_name,is_pass, result,values,base_value,infor,time)" +
$"values ('{MfcTest.Module}'," +
$"'{MfcTest.MfcName}'," +
$"'{MfcTest.IsPass}'," +
$"'{MfcTest.Result}'," +
$"'{MfcTest.Values}'," +
$"'{MfcTest.BaseValue}'," +
$"'{MfcTest.Infor}'," +
$"'{MfcTest.Time}')";
return cmd_data_insert;
}
private string UpdateMfcTestDataCmd()
{
string cmd_update =
$"update mfc_test_data set " +
$"is_pass= '{MfcTest.IsPass}'," +
$"result = '{MfcTest.Result}', " +
$"values= '{MfcTest.Values}'," +
$"base_value= '{MfcTest.BaseValue}'," +
$"infor= '{MfcTest.Infor}'," +
$"time= '{MfcTest.Time}'" +
$"where mfc_name = '{MfcTest.MfcName}' and module = '{MfcTest.Module}' ";
return cmd_update;
}
private List<MfcTestData> QueryAllMfcTestData()
{
try
{
string cmd = $"select * from mfc_test_data ";
var dt = DB.ExecuteDataset(cmd);
if (dt is null || dt.Tables[0].Rows.Count == 0)
return null;
for (int i = 0; i < dt.Tables[0].Rows.Count; i++)
{
if (dt.Tables[0].Rows[i].ItemArray.Length != 0)
{
MfcTestData mfcTestData = new MfcTestData()
{
Module = dt.Tables[0].Rows[i]["moudle"].ToString(),
MfcName = dt.Tables[0].Rows[i]["mfc_name"].ToString(),
IsPass = dt.Tables[0].Rows[i]["is_pass"].ToString(),
Result = dt.Tables[0].Rows[i]["result"].ToString(),
Values = dt.Tables[0].Rows[i]["values"].ToString(),
BaseValue = dt.Tables[0].Rows[i]["base_value"].ToString(),
Infor = dt.Tables[0].Rows[i]["infor"].ToString(),
Time = dt.Tables[0].Rows[i]["time"].ToString()
};
MfcTestList.ForEach(t =>
{
if (t.MfcName == mfcTestData.MfcName)
t.Update(mfcTestData);
});
}
}
return MfcTestList;
}
catch (Exception)
{
return null;
}
}
#endregion
#region
public void ReceiveControlNameData()
{
UpDataControlNameData();
foreach (var item in AllControlNameDataList)
{
UpdateControlNameDataDatabase(item);
}
QueryAllControlNameData();
}
private void UpDataControlNameData()
{
string _time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string str = MfcTest.IsPass == "NG" ? "NG" : "OK";
foreach (var item in mfcDoTest.StateList)
{
AllControlNameDataList.Add(new ControlNameData()
{
Module= moduleName,//这里是使用字段赋值所属PM名称
ControlName = item.Name,
State = str,
Time = _time
});;
}
}
private void UpdateControlNameDataDatabase(ControlNameData controlNameData)
{
string cmdID = $"select * from control_name_data where control_name = '{controlNameData.ControlName}'";
var dt = DB.ExecuteDataset(cmdID);
if (dt is null || dt.Tables[0].Rows.Count == 0)
DB.ExcuteTransAction(new List<string>() { InsertControlNameDataCmd(controlNameData) });
else
DB.ExcuteTransAction(new List<string>() { UpdateControlNameDataCmd(controlNameData) });
}
//public string ControlName { get; set; }
//public string State { get; set; }
//public string Time { get; set; }
private string InsertControlNameDataCmd(ControlNameData controlNameData)
{
string cmd_data_insert =
"insert into control_name_data" +
"(module,control_name,state,time)" +
$"values ('{controlNameData.Module}'," +
$"'{controlNameData.ControlName}'," +
$"'{controlNameData.State}'," +
$"'{controlNameData.Time}')";
return cmd_data_insert;
}
private string UpdateControlNameDataCmd(ControlNameData controlNameData)
{
string cmd_update =
$"update control_name_data set " +
$"state= '{controlNameData.State}'," +
$"time= '{controlNameData.Time}'" +
$"where control_name = '{controlNameData.ControlName}' and module = '{controlNameData.Module}'";
return cmd_update;
}
private List<MfcTestData> QueryAllControlNameData()
{
try
{
string cmd = $"select * from control_name_data ";
var dt = DB.ExecuteDataset(cmd);
if (dt is null || dt.Tables[0].Rows.Count == 0)
return null;
for (int i = 0; i < dt.Tables[0].Rows.Count; i++)
{
if (dt.Tables[0].Rows[i].ItemArray.Length != 0)
{
ControlNameData _controlNameData = new ControlNameData()
{
Module = dt.Tables[0].Rows[i]["module"].ToString(),
ControlName = dt.Tables[0].Rows[i]["control_name"].ToString(),
State = dt.Tables[0].Rows[i]["state"].ToString(),
Time = dt.Tables[0].Rows[i]["time"].ToString()
};
if (_controlNameData.ControlName.Contains("V"))
{
ValueTestList.ForEach(t =>
{
if (t.ControlName == _controlNameData.ControlName)
t.Update(_controlNameData);
});
}
else if (_controlNameData.ControlName.Contains("PC"))
{
PCTestList.ForEach(t =>
{
if (t.ControlName == _controlNameData.ControlName)
t.Update(_controlNameData);
});
}
}
}
return MfcTestList;
}
catch (Exception)
{
return null;
}
}
#endregion
}
}