using HMI.Core.Entity; using HMI.Core.Manager; using HMI.Core.Util; using HMI.UI.Util; using NationalInstruments.TestStand.Interop.UI.Ax; using Plugin.BurnIn.Model; using Plugin.TsSupport; using System.Windows; using System.Windows.Controls; namespace Plugin.BurnIn { /// /// TestResultView.xaml 的交互逻辑 /// public partial class TestResultView : UserControl { private int rowCount; private int colCount; private int cellCount; public static DataTable[] tables { get; private set; } public static Dictionary nameTables { get; private set; } = new Dictionary(); private readonly BaseConfig config; public string testModelFile; public string testSeqFile; public bool inManualDebugMode = false; #region TS相关 //public AxApplicationMgr testApp; ///// ///// 测试序列 ///// //private SequenceFile testSeq = null; //public Engine engine; //private Execution execution = null; ///// ///// 测试序列操作句柄 ///// //public SequenceContext SequenceContext { get; private set; } = null; ///// ///// 测试模型序列 ///// //private SequenceFile modeSeq; public ITestExecutionWrapper executionWrapper; #endregion public TestResultView() : this(new BaseConfig { testing = false }) { } public bool IsRunning { get; set; } = false; public void RefreshCooler() { } private void RefreshNumberConfig(BaseConfig config) { ParameterData value = null; try { value = ParameterManager.GetCommonParameterByName("BurnInOvenCount"); string[] datas = value.Value.Trim().Split(','); config.Row = int.Parse(datas[0]); config.Column = int.Parse(datas[1]); } catch (Exception ex) { } try { value = ParameterManager.GetCommonParameterByName("BurnInOvenName"); config.NameStr = value.Value; } catch (Exception ex) { } try { value = ParameterManager.GetCommonParameterByName("BurnInOvenPort"); config.PortStart = int.Parse(value.Value); } catch (Exception ex) { } try { value = ParameterManager.GetCommonParameterByName("BurnInCellCount"); string[] datas = value.Value.Trim().Split(','); config.PositionColumn = int.Parse(datas[0]); config.PositionCount = int.Parse(datas[1]); } catch (Exception ex) { } } public TestResultView(BaseConfig config) { try { var value = ParameterManager.GetCommonParameterByName("TsModelPath"); testModelFile = value?.Value ?? @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq"; } catch { //@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq" testModelFile = @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq"; } RefreshNumberConfig(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(); } private void ExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e) { try { HandleUIMessage(e.EventCode, Convert.ToInt16(e.NumberData), e.StrData, e.Data); } catch (Exception ex) { } } private void Refresh() { } /// /// 探针计数配置路径 /// 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(bool isTap) { try { if (isTap) { executionWrapper = new TapWrapper(); } else { executionWrapper = new TeststandWrapper(); } executionWrapper.UIMessageEvent += ExecutionWrapper_UIMessageEvent; if (executionWrapper is TeststandWrapper tsWrapper) { ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).BeginInit(); host.Child = tsWrapper.AxApplicationMgr; ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).EndInit(); } //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(testModelFile); executionWrapper.Init(); } catch (Exception ex) { BurnInUI.Logger.Error("InitTestStandEngine Failed.", ex); throw new Exception($"{this.lang("Ts.InitTestStandEngineFail")}: {ex.Message}"); } } public void SetOvenName() { foreach (var oven in tables) { executionWrapper?.SetStationGlobalValue($"StationHMI.UUTHMI[{oven.index}].Name", 1, oven.title); } executionWrapper?.CommitToDisk(false); } public void StartTestSequence() { try { if (string.IsNullOrEmpty(testSeqFile)) return; executionWrapper?.StartSequence(this.testSeqFile, @"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"); executionWrapper.SetStationGlobalValue("StationHMI.AllStop", 0, false); } catch (Exception ex) { BurnInUI.Logger.Error("StartTestSequence Failed.", ex); throw new Exception($"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}"); } } public void StopTest() { try { executionWrapper?.SetStationGlobalValue("StationHMI.AllStop", 0, true, true); try { executionWrapper?.WaitForExit(); executionWrapper?.ReleaseSeqFile(); } catch (Exception ex) { BurnInUI.Logger.Error("Wait For Exit error.", ex); //if (ex is NullReferenceException ne) //{ //} //else //{ // throw ex; //} } } catch (Exception ex) { BurnInUI.Logger.Error("StopTest Failed.", ex); throw new Exception($"{this.lang("Ts.StopTestSequenceFailed")}: {ex.Message}"); } } [Obsolete] private void axApplicationMgr_ExitApplication(object sender, EventArgs e) { //Environment.ExitCode = testApp.ExitCode; //TSHelper.DoSynchronousGCForCOMObjectDestruction(); } [Obsolete] 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 HandleUIMessage(int EventCase, int MethodCode, string strData, object xData) { try { if (EventCase != 10014) return; if (MethodCode == 0) { /// 设置句柄 executionWrapper.SetContext(xData); return; } if (MethodCode == 1) { /// 更新炉子状态 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) { /// 更新炉子数量信息 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) { /// 更新炉子时间信息 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].SetEndTime(planEndTime); double? leftTime = null; /// 为了兼容旧版本,如果有剩余时间就传,没有就传null if (datas_10014.Length >= 5) { leftTime = double.Parse(datas_10014[4]); } tables[ovenIndex].UpdateConsumeTime(double.Parse(consumeTime), leftTime); return; } if (MethodCode == 4) { /// 更新老化炉底部状态栏 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) { /// 采集炉温度 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) { Dispatcher.Invoke(() => {/// 更新穴位状态 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) { /// 更新穴位参数 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], limitUp = values[2], limitDown = values[3], unit = values[4], result = values[5], updateTime = values[6] }); return; } if (MethodCode == 10) { /// 清空炉子的温度图表 int ovenIndex = int.Parse(strData); tables[ovenIndex].ClearChartData(); return; } if (MethodCode == 11) { /// 清除穴位参数 string[] datas_10015 = strData.Split(';'); int ovenIndex = int.Parse(datas_10015[0]); int cellIndex = int.Parse(datas_10015[1]); tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo(); //GC.Collect(); return; } if (MethodCode == 12) { /// 保存炉体温度文件 string[] datas = strData.Split(';'); int ovenIndex = int.Parse(datas[0]); string folder = datas[1]; tables[ovenIndex].SaveTempFile(folder); return; } if (MethodCode == 13) { /// 添加电流数据 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) { /// 清空电流和电压数据 int ovenIndex = int.Parse(strData); tables[ovenIndex].ClearCellData(); //tables[ovenIndex].ClearElectricData(); //tables[ovenIndex].ClearVData(); //tables[ovenIndex].ClearWaterData(); return; } if (MethodCode == 15) { /// 保存电流数据 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; } if (MethodCode == 16) { /// 添加电压图表数据 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).AddVData(eData); return; } if (MethodCode == 17) { /// 保存电压数据 string[] datas = strData.Split(';'); int ovenIndex = int.Parse(datas[0]); int cellIndex = int.Parse(datas[1]); string filePath = datas[2]; tables[ovenIndex].GetSingleCell(cellIndex).SaveVDataToCSV(filePath); return; } if (MethodCode == 18) { /// 保存穴位测试数据到CSV string[] datas = strData.Split(';'); int ovenIndex = int.Parse(datas[0]); int cellIndex = int.Parse(datas[1]); string filePath = datas[2]; tables[ovenIndex].GetSingleCell(cellIndex).SaveInfoToCSV(filePath); return; } if (MethodCode == 180) { /// 保存穴位测试数据到CSV string[] datas = strData.Split(';'); int ovenIndex = int.Parse(datas[0]); int cellIndex = int.Parse(datas[1]); string filePath = datas[2]; tables[ovenIndex].GetSingleCell(cellIndex).NormalCSV(filePath); return; } if (MethodCode == 19) { /// 保存穴位测试数据到Sqlite string[] datas = strData.Split(';'); int ovenIndex = int.Parse(datas[0]); int cellIndex = int.Parse(datas[1]); tables[ovenIndex].GetSingleCell(cellIndex).SaveInfoToDB(); return; } if (MethodCode == 20) { /// 清空条码 int ovenIndex = int.Parse(strData); tables[ovenIndex].ClearAllSN(); return; } if (MethodCode == 21) { /// 添加水流图表数据 string[] datas = strData.Split(';'); int ovenIndex = int.Parse(datas[0]); int cellIndex = int.Parse(datas[1]); double waterTemp = double.Parse(datas[2]); double backWaterTemp = double.Parse(datas[3]); double waterPressure = double.Parse(datas[4]); tables[ovenIndex].GetSingleCell(cellIndex).AddWaterData(waterTemp, backWaterTemp, waterPressure); return; } if (MethodCode == 99) { string[] datas = strData.Split(';'); int index = int.Parse(datas[0]); if (MsgBoxHelper2.WarnChoose(datas[1], "提示") == MessageBoxResult.OK) { executionWrapper.SetStationGlobalValue($"StationState.Pipe[{index}]", 1, 1); //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 1); } else { executionWrapper.SetStationGlobalValue($"StationState.Pipe[{index}]", 1, 0); //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 0); } return; } } catch (Exception ex) { BurnInUI.Logger.Warn("TestStand Event Error.", ex); } } private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e) { int EventCase = Convert.ToInt32(e.uiMsg.Event); int MethodCode = Convert.ToInt16(e.uiMsg.NumericData); string strData = e.uiMsg.StringData; HandleUIMessage(EventCase, MethodCode, strData, e.uiMsg.ActiveXData); } public void SetStartFlag(int index, bool data) { string name = tables[index].title; string key = string.Empty; if (data) { BurnInUI.Logger?.Info($"启动老化炉[{name}]"); key = $"StationHMI.UUTHMI[{index}].Start"; } else { BurnInUI.Logger?.Info($"停止老化炉[{name}]"); key = $"StationHMI.UUTHMI[{index}].Stop"; } executionWrapper?.SetStationGlobalValue(key, 1, true); } public void ReleaseResource() { executionWrapper.UIMessageEvent -= ExecutionWrapper_UIMessageEvent; executionWrapper.Dispose(); 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) { for (int i = 0; i < tables.Length; i++) { var table = tables[i]; string LookupStr = $"StationHMI.UUTHMI[{i}].Model"; string tableModel = executionWrapper?.GetStationGlobalValue(LookupStr, 1); //engine?.Globals?.GetValString(LookupStr, 1); table.SetCurrentProduct(tableModel); } } public void SetOvenProduct(int index, string product) { string LookupStr = $"StationHMI.UUTHMI[{index}].Model"; executionWrapper?.SetStationGlobalValue(LookupStr, 1, product); executionWrapper?.CommitToDisk(false); } public void RefreshProducts() { } } }