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; /// /// 测试序列操作句柄 /// private SequenceContext SequenceContext = 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.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)); var cell = 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; } } catch (Exception ex) { ViewControl.Logger.Warn("TestStand Event Error.", ex); } } public void SetStartFlag(int index, bool data) { if (this.SequenceContext == null) return; char name = (char)(index + 65); 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(); } } } }