| | |
| | | using HMI.Core.Util; |
| | | using HMI.Core.Entity; |
| | | using HMI.Core.Manager; |
| | | 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 Plugin.TsSupport; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Runtime.InteropServices; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | |
| | |
| | | private int rowCount; |
| | | private int colCount; |
| | | private int cellCount; |
| | | private DataTable[] tables; |
| | | public Dictionary<string, DataTable> nameTables { get; private set; } |
| | | |
| | | public static DataTable[] tables { get; private set; } |
| | | public static Dictionary<string, DataTable> nameTables { get; private set; } = new Dictionary<string, DataTable>(); |
| | | private readonly BaseConfig config; |
| | | |
| | | public AxApplicationMgr testApp; |
| | | |
| | | |
| | | public string testModelFile; |
| | | public string testSeqFile; |
| | | /// <summary> |
| | | /// 测试序列 |
| | | /// </summary> |
| | | private SequenceFile testSeq = null; |
| | | public Engine engine; |
| | | private Execution execution = null; |
| | | /// <summary> |
| | | /// 测试序列操作句柄 |
| | | /// </summary> |
| | | public SequenceContext SequenceContext { get; private set; } = null; |
| | | /// <summary> |
| | | /// 测试模型序列 |
| | | /// </summary> |
| | | private SequenceFile modeSeq; |
| | | public bool inManualDebugMode = false; |
| | | |
| | | #region TS相关 |
| | | //public AxApplicationMgr testApp; |
| | | ///// <summary> |
| | | ///// 测试序列 |
| | | ///// </summary> |
| | | //private SequenceFile testSeq = null; |
| | | //public Engine engine; |
| | | //private Execution execution = null; |
| | | ///// <summary> |
| | | ///// 测试序列操作句柄 |
| | | ///// </summary> |
| | | //public SequenceContext SequenceContext { get; private set; } = null; |
| | | ///// <summary> |
| | | ///// 测试模型序列 |
| | | ///// </summary> |
| | | //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; |
| | |
| | | |
| | | |
| | | 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); |
| | | |
| | | executionWrapper = new TsExecutionWrapper(); //new TsExecutionWrapper(); |
| | | if (executionWrapper is TsExecutionWrapper tsWrapper) |
| | | { |
| | | tsWrapper.AxApplicationMgr.ExitApplication += this.axApplicationMgr_ExitApplication; |
| | | tsWrapper.AxApplicationMgr.UIMessageEvent += this.axApplicationMgr_UIMessageEvent; |
| | | tsWrapper.AxApplicationMgr.ExecutionClosed += this.axApplicationMgr_ExecutionClosed; |
| | | ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).BeginInit();//myClient为第三方控件名 |
| | | host.Child = tsWrapper.AxApplicationMgr; |
| | | ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).EndInit(); |
| | | } |
| | | |
| | | |
| | | ((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient为第三方控件名 |
| | | host.Child = testApp; |
| | | ((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit(); |
| | | |
| | | //InitTestStandEngine(); |
| | | //StartTestSequence(); |
| | | //testApp = TestAppManager.GetAxApplicationMgr(); |
| | | //testApp.ExitApplication += this.axApplicationMgr_ExitApplication; |
| | | //testApp.UIMessageEvent += this.axApplicationMgr_UIMessageEvent; |
| | | //testApp.ExecutionClosed += this.axApplicationMgr_ExecutionClosed; |
| | | //((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient为第三方控件名 |
| | | //host.Child = testApp; |
| | | //((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit(); |
| | | } |
| | | |
| | | 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(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 探针计数配置路径 |
| | | /// </summary> |
| | | private string CountIniPath; |
| | | public void SetCountIniPath(string countIniPath) |
| | | { |
| | |
| | | { |
| | | 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"); |
| | | |
| | | //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) |
| | | { |
| | |
| | | { |
| | | 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); |
| | | if (string.IsNullOrEmpty(testSeqFile)) return; |
| | | executionWrapper?.StartSequence(this.testSeqFile, |
| | | @"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"); |
| | | |
| | | executionWrapper.SetStationGlobalValue<bool>("StationState.StopTest", 0, false); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | { |
| | | try |
| | | { |
| | | if (this.SequenceContext == null) |
| | | return; |
| | | bool val = this.SequenceContext.StationGlobals.Exists("StationState.StopTest", 0); |
| | | if (val) |
| | | executionWrapper?.SetStationGlobalValue<bool>("StationState.StopTest", 0, true, true); |
| | | |
| | | try |
| | | { |
| | | this.SequenceContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true); |
| | | bool isStop = this.execution.WaitForEndEx(2000, true, null, null); |
| | | executionWrapper?.WaitForExit(); |
| | | executionWrapper?.ReleaseSeqFile(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | ViewControl.Logger.Error("Wait For Exit error.", ex); |
| | | //if (ex is NullReferenceException ne) |
| | | //{ |
| | | |
| | | //} |
| | | //else |
| | | //{ |
| | | // throw ex; |
| | | //} |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | |
| | | |
| | | private void axApplicationMgr_ExitApplication(object sender, EventArgs e) |
| | | { |
| | | Environment.ExitCode = testApp.ExitCode; |
| | | TSHelper.DoSynchronousGCForCOMObjectDestruction(); |
| | | //Environment.ExitCode = testApp.ExitCode; |
| | | //TSHelper.DoSynchronousGCForCOMObjectDestruction(); |
| | | } |
| | | |
| | | private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e) |
| | |
| | | if (MethodCode == 0) |
| | | { |
| | | /// 设置句柄 |
| | | this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData; |
| | | //this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData; |
| | | if (executionWrapper is TsExecutionWrapper tsWrapper) |
| | | { |
| | | tsWrapper.context = (SequenceContext)e.uiMsg.ActiveXData; |
| | | } |
| | | return; |
| | | } |
| | | |
| | |
| | | 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); |
| | | 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) |
| | |
| | | { |
| | | step = values[0], |
| | | value = values[1], |
| | | result = values[2], |
| | | range = values[3], |
| | | condition = values[4], |
| | | updateTime = values[5] |
| | | limitUp = values[2], |
| | | limitDown = values[3], |
| | | unit = values[4], |
| | | result = values[5], |
| | | updateTime = values[6] |
| | | }); |
| | | return; |
| | | } |
| | |
| | | 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) |
| | | { |
| | | /// 保存温度文件 |
| | | /// |
| | | /// 保存炉体温度文件 |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas = strData.Split(';'); |
| | | int ovenIndex = int.Parse(datas[0]); |
| | |
| | | tables[ovenIndex].GetSingleCell(cellIndex).AddElectricData(eData); |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 14) |
| | | { |
| | | /// 清空电流数据 |
| | | /// 清空电流和电压数据 |
| | | strData = e.uiMsg.StringData; |
| | | int ovenIndex = int.Parse(strData); |
| | | tables[ovenIndex].ClearElectricData(); |
| | | tables[ovenIndex].ClearCellData(); |
| | | //tables[ovenIndex].ClearElectricData(); |
| | | //tables[ovenIndex].ClearVData(); |
| | | //tables[ovenIndex].ClearWaterData(); |
| | | 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; |
| | | } |
| | | |
| | | if (MethodCode == 16) |
| | | { |
| | | /// 添加电压图表数据 |
| | | 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).AddVData(eData); |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 17) |
| | | { |
| | | /// 保存电压数据 |
| | | 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).SaveVDataToCSV(filePath); |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 18) |
| | | { |
| | | /// 保存穴位测试数据到CSV |
| | | 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).SaveInfoToCSV(filePath); |
| | | return; |
| | | } |
| | | if (MethodCode == 180) |
| | | { |
| | | /// 保存穴位测试数据到CSV |
| | | 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).NormalCSV(filePath); |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 19) |
| | | { |
| | | /// 保存穴位测试数据到Sqlite |
| | | strData = e.uiMsg.StringData; |
| | | 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) |
| | | { |
| | | /// 清空条码 |
| | | strData = e.uiMsg.StringData; |
| | | int ovenIndex = int.Parse(strData); |
| | | tables[ovenIndex].ClearAllSN(); |
| | | return; |
| | | } |
| | | |
| | | if (MethodCode == 21) |
| | | { |
| | | /// 添加水流图表数据 |
| | | strData = e.uiMsg.StringData; |
| | | 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) |
| | | { |
| | | strData = e.uiMsg.StringData; |
| | | string[] datas = strData.Split(';'); |
| | | int index = int.Parse(datas[0]); |
| | | if (MsgBoxHelper2.WarnChoose(datas[1], "提示") == MessageBoxResult.OK) |
| | | { |
| | | executionWrapper.SetStationGlobalValue<int>($"StationState.Pipe[{index}]", 1, 1); |
| | | //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 1); |
| | | } |
| | | else |
| | | { |
| | | executionWrapper.SetStationGlobalValue<int>($"StationState.Pipe[{index}]", 1, 0); |
| | | //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 0); |
| | | } |
| | | return; |
| | | } |
| | | } |
| | |
| | | |
| | | 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); |
| | | ViewControl.Logger?.Info($"将老化炉[{name}] 的Start变量设置为 {data};"); |
| | | string key = $"StationState.Start[{index}]"; |
| | | |
| | | executionWrapper?.SetStationGlobalValue<bool>(key, 1, data); |
| | | |
| | | if (data == false) |
| | | { |
| | | key = $"StationState.Scanner[{index}]"; |
| | | executionWrapper?.SetStationGlobalValue<bool>(key, 1, false); |
| | | } |
| | | } |
| | | |
| | | public bool? GetStartFlag(int index) |
| | | { |
| | | string key = $"StationState.Start[{index}]"; |
| | | return executionWrapper.GetStationGlobalValue<bool>(key, 0); |
| | | } |
| | | |
| | | public void ReleaseResource() |
| | | { |
| | | if (executionWrapper is TsExecutionWrapper tsWrapper) |
| | | { |
| | | tsWrapper.AxApplicationMgr.ExitApplication -= this.axApplicationMgr_ExitApplication; |
| | | tsWrapper.AxApplicationMgr.UIMessageEvent -= this.axApplicationMgr_UIMessageEvent; |
| | | tsWrapper.AxApplicationMgr.ExecutionClosed -= this.axApplicationMgr_ExecutionClosed; |
| | | } |
| | | |
| | | foreach (var table in tables) |
| | | { |
| | | table.RelaseResource(); |
| | |
| | | |
| | | public void SetCurrentProduct(string currentProduct) |
| | | { |
| | | foreach (var table in tables) |
| | | for (int i = 0; i < tables.Length; i++) |
| | | { |
| | | table.SetCurrentProduct(currentProduct); |
| | | var table = tables[i]; |
| | | string LookupStr = $"StationState.Model[{i}]"; |
| | | |
| | | string tableModel = executionWrapper?.GetStationGlobalValue<string>(LookupStr, 1); |
| | | //engine?.Globals?.GetValString(LookupStr, 1); |
| | | table.SetCurrentProduct(tableModel); |
| | | } |
| | | } |
| | | |
| | | public void SetOvenProduct(int index, string product) |
| | | { |
| | | string LookupStr = $"StationState.ProductModel_{tables[index].title}"; |
| | | engine?.Globals?.SetValString(LookupStr, 1, product); |
| | | string LookupStr = $"StationState.Model[{index}]"; |
| | | executionWrapper?.SetStationGlobalValue<string>(LookupStr, 1, product); |
| | | executionWrapper?.CommitToDisk(false); |
| | | } |
| | | |
| | | public void RefreshProducts() |
| | | { |
| | | } |
| | | } |
| | | } |