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

806 lines
28 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
using System.Collections.ObjectModel;
namespace SicModules.PMs.Routines
{
public delegate bool ConditionMethodDelegate(string name, double value, out string reason);
public class PMMfcValueTestRoutine : PMBaseRoutine
{
enum RoutineStep
{
OpenOrClose,
OpenMfc,
TimeDelay,
Inspect,
CloseMfc,
ResetState,
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 MfcName;
private double _timeDelay;
private double _scValue;
private double _mfcDefaultValue;
private double _upperLimit;
private Stopwatch _swTimer = new Stopwatch();
private string _startTime;
private string _endTime;
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)
{
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;
}
}
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.{Module}.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.{Module}.MfcTestingPercentage");//上限参数
_startTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
_swTimer.Restart();
//初始化MFC操作对象,做界面显示用
MfcTest.MfcName = selectedMfcName;
MfcTest.Module = Module;
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.OpenOrClose, false);
//根据XML配置打开要测试的MFC
PreMfcRamp((int)RoutineStep.OpenMfc, _mfcDefaultValue);
//延时等待气流上升
TimeDelay((int)RoutineStep.TimeDelay, _timeDelay);
//统计数据,并分析结果
PreInspect((int)RoutineStep.Inspect);
//根据XML配置关闭检测的MFC
PreMfcRamp((int)RoutineStep.CloseMfc, 0);
//根据XML配置测试气路关闭气阀、PC、MFC
PreSetValve((int)RoutineStep.ResetState, 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>($"{Module}.{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("P"))
return true;
var isOpen = value == 1 ? PcCtrlMode.Open : PcCtrlMode.Close;
var pc = DEVICE.GetDevice<IoPressure>($"{Module}.{pcName}");
if (pc.SetPcMode(isOpen, out reason))
{
Notify($"{pcName} {isOpen}");
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>($"{Module}.{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 ('{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 = '{Module}' ";
return cmd_update;
}
private List<MfcTestData> QueryAllMfcTestData()
{
try
{
string cmd = $"select * from mfc_test_data where module = '{Module}'";
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]["module"].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= Module,//这里是使用字段赋值所属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 ('{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 = '{Module}'";
return cmd_update;
}
private List<MfcTestData> QueryAllControlNameData()
{
try
{
string cmd = $"select * from control_name_data where module = '{Module}'";
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
}
}