using HMI.Core.Util;
using HMI.UI.Util;
using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using NationalInstruments.TestStand.Utility;
using Plugin.TestResult_WPF.Constant;
using Plugin.TestResult_WPF.Model;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace Plugin.TestResult_WPF
{
///
/// TestResultView.xaml 的交互逻辑
///
public partial class TestResultView : UserControl
{
private int rowCount;
private int colCount;
private int cellCount;
private DataTable[] tables;
public Dictionary nameTables { get; private set; }
private readonly BaseConfig config;
public AxApplicationMgr testApp;
public string testSeqFile;
///
/// 测试序列
///
private SequenceFile testSeq = null;
public Engine engine;
private Execution execution = null;
///
/// 测试序列操作句柄
///
public SequenceContext SequenceContext { get; private set; } = null;
///
/// 测试模型序列
///
private SequenceFile modeSeq;
public TestResultView() : this(new BaseConfig { testing = false })
{
}
public TestResultView(BaseConfig config)
{
this.rowCount = config.Row;
this.colCount = config.Column;
this.config = config;
if (config.CellCount < 0)
{
this.cellCount = rowCount * colCount;
}
else
{
this.cellCount = config.CellCount;
}
tables = new DataTable[this.cellCount];
InitializeComponent();
testApp = new AxApplicationMgr();
testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient为第三方控件名
host.Child = testApp;
((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit();
//InitTestStandEngine();
//StartTestSequence();
}
private void Refresh()
{
for (int i = 0; i < tables.Length; i++)
{
var sb = new System.Timers.Timer()
{
Interval = 1000,
AutoReset = true,
};
var table = tables[i];
Random random = new Random(i * 13);
sb.Elapsed += (s, e) =>
{
table.RefreshCount(1, 0);
table.SetTemperature(random.Next(100));
for (int j = 0; j < 3; j++)
{
table.SetTemperature(j + "89", random.Next(100));
}
//table.SetOkCount(random.Next(100));
//table.SetNgCount(random.Next(100));
table.SetStatus(CommonStatus.GetRandomStatus());
table.SetStartTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
table.SetEndTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
table.SetConsumeTime(random.Next(10000));
tables[0].GetSingleCell(0).AddElectricData(random.Next(100));
var cell = tables[0].GetSingleCell(0);//table.GetSingleCell(random.Next(table.GetSize()));
cell.SetStatus(CommonStatus.GetRandomStatus());
cell.SetInfos(new Info
{
step = random.Next(1000) + "",
value = random.Next(1000) + ""
});
table.SetStatusText(DateTime.Now + "");
};
sb.Start();
}
}
private string CountIniPath;
public void SetCountIniPath(string countIniPath)
{
CountIniPath = countIniPath;
}
public void InitMainGrid()
{
nameTables = new Dictionary();
for (int r = 0; r < rowCount; r++)
{
RowDefinition row = new RowDefinition();
mainGrid.RowDefinitions.Add(row);
}
for (int c = 0; c < colCount; c++)
{
ColumnDefinition col = new ColumnDefinition();
mainGrid.ColumnDefinitions.Add(col);
}
string[] names = config.NameStr.Split(',');
for (int n = 0; n < cellCount; n++)
{
string name = n < names.Length ? names[n] : "";
DataTable child = new DataTable(this, n, name, CountIniPath, config);
mainGrid.Children.Add(child);
tables[n] = child;
nameTables[name] = child;
int row = n / colCount;
int col = n % colCount;
Grid.SetRow(child, row);
Grid.SetColumn(child, col);
}
if (config.testing) Refresh();
}
public DataTable GetDataTable(int index)
{
if (index >= 0 && index < tables.Length) return tables[index];
return null;
}
///
/// 启动测试序列
///
public void InitTestStandEngine()
{
try
{
this.engine = this.testApp.GetEngine();
this.engine.PersistBreakpoints = false;
this.testApp.IsEditor = true;
this.testApp.LoginOnStart = false;
this.testApp.Start();
this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
}
catch (Exception ex)
{
ViewControl.Logger.Error("InitTestStandEngine Failed.", ex);
throw new Exception($"{this.lang("Ts.InitTestStandEngineFail")}: {ex.Message}");
}
}
public void StartTestSequence()
{
try
{
this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 0, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
this.engine.Globals.SetValBoolean("StationState.StopTest", 0, false);
}
catch (Exception ex)
{
ViewControl.Logger.Error("StartTestSequence Failed.", ex);
throw new Exception($"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}");
}
}
public void StopTest()
{
try
{
if (this.SequenceContext == null)
return;
bool val = this.SequenceContext.StationGlobals.Exists("StationState.StopTest", 0);
if (val)
{
this.SequenceContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true);
bool isStop = this.execution.WaitForEndEx(2000, true, null, null);
}
}
catch (Exception ex)
{
ViewControl.Logger.Error("StopTest Failed.", ex);
throw new Exception($"{this.lang("Ts.StopTestSequenceFailed")}: {ex.Message}");
}
}
private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
{
Environment.ExitCode = testApp.ExitCode;
TSHelper.DoSynchronousGCForCOMObjectDestruction();
}
private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
{
try
{
//this.ReleaseSequenceFile();
}
catch (Exception ex)
{
MsgBoxHelper.Error(Window.GetWindow(this),
$"{this.lang("Ts.ReleaseSequenceFileFail")}: {ex.Message}");
}
}
private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
{
try
{
int EventCase = Convert.ToInt32(e.uiMsg.Event);
int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
string strData;
if (EventCase != 10014) return;
if (MethodCode == 0)
{
/// 设置句柄
this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
return;
}
if (MethodCode == 1)
{
/// 更新炉子状态
strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
string status = datas_10014[1];
tables[ovenIndex].SetStatus(status);
return;
}
if (MethodCode == 2)
{
/// 更新炉子数量信息
strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
string okCount = datas_10014[1];
string ngCount = datas_10014[2];
tables[ovenIndex].SetOkCount(int.Parse(okCount));
tables[ovenIndex].SetNgCount(int.Parse(ngCount));
return;
}
if (MethodCode == 3)
{
/// 更新炉子时间信息
strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
string startTime = datas_10014[1];
string consumeTime = datas_10014[2];
string planEndTime = datas_10014[3];
tables[ovenIndex].SetStartTime(startTime);
tables[ovenIndex].SetConsumeTime(double.Parse(consumeTime));
tables[ovenIndex].SetEndTime(planEndTime);
return;
}
if (MethodCode == 4)
{
/// 更新老化炉底部状态栏
strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
string statusBar = datas_10014[1];
tables[ovenIndex].SetStatusText(statusBar);
return;
}
if (MethodCode == 5)
{
/// 采集炉温度
strData = e.uiMsg.StringData;
string[] datas_10016 = strData.Split(';');
int ovenIndex = int.Parse(datas_10016[0]);
string[] names = datas_10016[1].Split(',');
string[] values = datas_10016[2].Split(',');
for (int x = 0; x < values.Length; x++)
{
if (x == 0) tables[ovenIndex].SetTemperature(double.Parse(values[x]));
else tables[ovenIndex].SetTemperature(names[x - 1], double.Parse(values[x]));
}
return;
}
if (MethodCode == 6)
{
/// 更新穴位状态
strData = e.uiMsg.StringData;
string[] datas_10015 = strData.Split(';');
int ovenIndex = int.Parse(datas_10015[0]);
int cellIndex = int.Parse(datas_10015[1]);
string status_10015 = datas_10015[2];
tables[ovenIndex].GetSingleCell(cellIndex).SetStatus(status_10015);
if (status_10015 == "OK" || status_10015 == "ok")
{
tables[ovenIndex].RefreshCount(1, 0);
}
else if (status_10015 == "ng" || status_10015 == "NG")
{
tables[ovenIndex].RefreshCount(0, 1);
}
return;
}
if (MethodCode == 7)
{
/// 更新穴位参数
strData = e.uiMsg.StringData;
string[] datas_10015 = strData.Split(';');
int ovenIndex = int.Parse(datas_10015[0]);
int cellIndex = int.Parse(datas_10015[1]);
string strs = datas_10015[2];
string[] values = strs.Split(',');
//string step = datas_10015[2];
//string result = datas_10015[3];
tables[ovenIndex].GetSingleCell(cellIndex).SetInfos(new Info
{
step = values[0],
value = values[1],
result = values[2],
range = values[3],
condition = values[4],
updateTime = values[5]
});
return;
}
if (MethodCode == 10)
{
/// 清空炉子的温度图表
strData = e.uiMsg.StringData;
int ovenIndex = int.Parse(strData);
tables[ovenIndex].ClearChartData();
return;
}
if (MethodCode == 11)
{
/// 清除穴位参数
strData = e.uiMsg.StringData;
string[] datas_10015 = strData.Split(';');
int ovenIndex = int.Parse(datas_10015[0]);
int cellIndex = int.Parse(datas_10015[1]);
tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo();
return;
}
if (MethodCode == 12)
{
/// 保存温度文件
///
strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
string folder = datas[1];
tables[ovenIndex].SaveTempFile(folder);
return;
}
if (MethodCode == 13)
{
/// 添加电流数据
strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
double eData = double.Parse(datas[2]);
tables[ovenIndex].GetSingleCell(cellIndex).AddElectricData(eData);
return;
}
if (MethodCode == 14)
{
/// 清空电流数据
strData = e.uiMsg.StringData;
int ovenIndex = int.Parse(strData);
tables[ovenIndex].ClearElectricData();
return;
}
if (MethodCode == 15)
{
/// 清空电流数据
strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
string filePath = datas[2];
tables[ovenIndex].GetSingleCell(cellIndex).SaveElectricDataToCSV(filePath);
return;
}
}
catch (Exception ex)
{
ViewControl.Logger.Warn("TestStand Event Error.", ex);
}
}
public void SetStartFlag(int index, bool data)
{
if (this.SequenceContext == null) return;
string name = tables[index].title;
string key = $"StationState.Start_{name}";
this.engine.Globals.SetValBoolean(key, 0, data);
bool val = this.engine.Globals.GetValBoolean(key, 0);
//this.SequenceContext.StationGlobals.SetValBoolean(key, 0, data);
//bool val = this.SequenceContext.StationGlobals.GetValBoolean(key, 0);
}
public void ReleaseResource()
{
foreach (var table in tables)
{
table.RelaseResource();
}
}
///
/// 计数清零
///
public void ClearNumber()
{
foreach (var table in tables)
{
table.ClearNumber();
}
}
public void SetProductSource(List productSource)
{
foreach (var table in tables)
{
table.SetProductSource(productSource);
}
}
public void SetCurrentProduct(string currentProduct)
{
foreach (var table in tables)
{
table.SetCurrentProduct(currentProduct);
}
}
public void SetOvenProduct(int index, string product)
{
string LookupStr = $"StationState.ProductModel_{tables[index].title}";
engine?.Globals?.SetValString(LookupStr, 1, product);
}
}
}