| | |
| | | using HMI.Base; |
| | | using HMI.Core; |
| | | using HMI.Core.Entity; |
| | | using HMI.Core.Manager; |
| | | using HMI.Core.Util; |
| | | using HMI.ParameterManage.Entity; |
| | | using HMI.ParameterManage.Util; |
| | | using HMI.ParameterManage; |
| | | using HMI.UI; |
| | | using HMI.UI.Util; |
| | | using HMI.Util; |
| | | using log4net; |
| | | using NationalInstruments.TestStand.Interop.API; |
| | | using NationalInstruments.TestStand.Interop.UI.Ax; |
| | | using Panuon.WPF.UI; |
| | | using ScottPlot; |
| | | using ScottPlot.AxisLimitManagers; |
| | | using ScottPlot.Plottables; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Drawing; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Timers; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | using System.Windows.Forms.DataVisualization.Charting; |
| | | using System.Windows.Markup; |
| | | |
| | | namespace Plugin.TsExecution |
| | | { |
| | |
| | | private Chart chart; |
| | | #endregion |
| | | |
| | | public static ILog logger { get; private set; } |
| | | private List<SingleControl> tsSockets = new List<SingleControl>(); |
| | | /// <summary> |
| | | /// 样件模式状态 |
| | |
| | | } |
| | | } |
| | | |
| | | public override void SetLogger(ILog logger) |
| | | { |
| | | base.SetLogger(logger); |
| | | TsExecution.logger = logger; |
| | | } |
| | | |
| | | private ObservableCollection<ProductData> products; |
| | | |
| | | public ObservableCollection<ProductData> Products |
| | |
| | | } |
| | | } |
| | | |
| | | private bool _enableMes; |
| | | public bool EnableMes |
| | | { |
| | | get => _enableMes; |
| | | set |
| | | { |
| | | Set(ref _enableMes, value); |
| | | WriteConfig("EnableMes", value); |
| | | } |
| | | } |
| | | |
| | | private bool _enableCanLog; |
| | | public bool EnableCanLog |
| | | { |
| | | get => _enableCanLog; |
| | | set |
| | | { |
| | | Set(ref _enableCanLog, value); |
| | | WriteConfig("EnableCanLog", value); |
| | | } |
| | | } |
| | | |
| | | private bool _enableDebugMode; |
| | | public bool EnableDebugMode |
| | | { |
| | | get => _enableDebugMode; |
| | | set |
| | | { |
| | | Set(ref _enableDebugMode, value); |
| | | WriteConfig("EnableDebugMode", value); |
| | | } |
| | | } |
| | | |
| | | |
| | | public TsExecution() |
| | | { |
| | | DataContext = this; |
| | |
| | | InitTsEngine(); |
| | | //初始化TestStand引擎 |
| | | this.InitTestStandEngine(); |
| | | |
| | | } |
| | | |
| | | public override void SetBaseFolder(string folder) |
| | |
| | | { |
| | | this.ReadCount(out int pass, out int fail); |
| | | this.DisplayCount(pass, fail); |
| | | UpdateChart(pass, fail); |
| | | InitProducts(); |
| | | base.InitFinish(); |
| | | } |
| | |
| | | |
| | | private void InitProducts() |
| | | { |
| | | Products = ParameterManager.GetProducts<ObservableCollection<ProductData>>(); |
| | | Products = ProductManager.GetProducts<ObservableCollection<ProductData>>(); |
| | | if (Products != null && Products.Count > 0) |
| | | { |
| | | List<ParameterData> parameters = |
| | |
| | | { |
| | | try |
| | | { |
| | | ReadConfig(); |
| | | //连接OPChandle |
| | | //this.OpcHandle.Connect2("127.0.0.1", 6543, 18081, out string ErrMsg, null); |
| | | //启动测试进程 |
| | |
| | | |
| | | private void RefershUI() |
| | | { |
| | | ParameterData p = ParameterManager.GetCommonParameterByName("ProbeWarn"); |
| | | int ProbeWarn = 0; |
| | | if (p != null) |
| | | { |
| | | try |
| | | { |
| | | ProbeWarn = Convert.ToInt32(p.Value); |
| | | } |
| | | catch |
| | | { |
| | | ProbeWarn = 0; |
| | | } |
| | | } |
| | | |
| | | panel.Children.Clear(); |
| | | //重新生成子面板 |
| | | for (int i = 0; i < this.socketNum; i++) |
| | | { |
| | | SingleControl control = new SingleControl(i, CountIniPath); |
| | | SingleControl control = new SingleControl(i, CountIniPath, ProbeWarn); |
| | | panel.Children.Add(control); |
| | | tsSockets.Add(control); |
| | | } |
| | |
| | | /// <param name="fail">不合格数</param> |
| | | private void ReadCount(out int pass, out int fail) |
| | | { |
| | | pass = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Pass", "", CountIniPath)); |
| | | fail = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Fail", "", CountIniPath)); |
| | | pass = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Pass", "0", CountIniPath)); |
| | | fail = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Fail", "0", CountIniPath)); |
| | | } |
| | | |
| | | private void WriteCount(int pass, int fail) |
| | | /// <summary> |
| | | /// 读取配置文件里的几个属性 |
| | | /// </summary> |
| | | /// <param name="pass"></param> |
| | | /// <param name="fail"></param> |
| | | private void ReadConfig() |
| | | { |
| | | try |
| | | { |
| | | var p = ParameterManager.GetCommonParameterByName("EnableMes"); |
| | | EnableMes = bool.Parse(p?.Value); |
| | | } |
| | | catch |
| | | { |
| | | EnableMes = false; |
| | | } |
| | | //Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableMes", "true", CountIniPath)); |
| | | EnableCanLog = Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableCanLog", "true", CountIniPath)); |
| | | EnableDebugMode = Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableDebugMode", "true", CountIniPath)); |
| | | } |
| | | |
| | | private void WriteConfig(string name, bool value) |
| | | { |
| | | IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath); |
| | | //this.engine.Globals.SetValBoolean($"StationState.{name}", 1, value); |
| | | } |
| | | |
| | | private void WriteCount(double pass, double fail) |
| | | { |
| | | IniFileHelper.WriteIniData("Count", "Pass", pass.ToString(), CountIniPath); |
| | | IniFileHelper.WriteIniData("Count", "Fail", fail.ToString(), CountIniPath); |
| | |
| | | /// </summary> |
| | | /// <param name="pass">合格数</param> |
| | | /// <param name="fail">不合格数</param> |
| | | private void DisplayCount(int pass, int fail) |
| | | private void DisplayCount(double pass, double fail) |
| | | { |
| | | int total = pass + fail; |
| | | double total = pass + fail; |
| | | double passRate; |
| | | if (total == 0) |
| | | { |
| | |
| | | this.TbFail.Text = fail.ToString(); |
| | | this.TbTotal.Text = total.ToString(); |
| | | this.TbPassRate.Text = string.Format("{0:0.00}", passRate) + "%"; |
| | | |
| | | pie.Slices[0].Value = pass; |
| | | pie.Slices[1].Value = fail; |
| | | pieChart.Refresh(); |
| | | |
| | | WriteCount(pass, fail); |
| | | } |
| | | |
| | |
| | | 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); |
| | | |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | this.CbProduct.IsEnabled = false; |
| | |
| | | new MaskWindow((WindowX)Window.GetWindow(this), |
| | | (win) => |
| | | { |
| | | Dispatcher.Invoke(() => |
| | | try |
| | | { |
| | | try |
| | | bool stoped = StopSequence(); |
| | | if (stoped) |
| | | { |
| | | StopSequence(); |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | this.CbProduct.IsEnabled = true; |
| | | this.BtnStartSeq.IsEnabled = true; |
| | | this.BtnStopSeq.IsEnabled = false; |
| | | }); |
| | | } |
| | | finally |
| | | } |
| | | finally |
| | | { |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | |
| | | win.Close(); |
| | | } |
| | | }); |
| | | }); |
| | | } |
| | | //Dispatcher.Invoke(() => |
| | | //{ |
| | | |
| | | //}); |
| | | } |
| | | ).Info(LangUtil.Get("App.SequenceIsStopping")); |
| | | } |
| | |
| | | /// <summary> |
| | | /// 停止测试序列 |
| | | /// </summary> |
| | | private void StopSequence() |
| | | private bool StopSequence() |
| | | { |
| | | try |
| | | { |
| | | if (this.tsSockets.Count > 0 && this.tsSockets[0]?.SequenceFileContext != null) |
| | | if (this.tsSockets.Count > 0) |
| | | { |
| | | bool val = this.tsSockets[0].SequenceFileContext.StationGlobals.Exists("StationState.StopTest", 0); |
| | | if (val) |
| | | for (int i = 0; i < tsSockets.Count; i++) |
| | | { |
| | | tsSockets[0].SequenceFileContext.StationGlobals.SetValBoolean("StationState.StopTest", 0, true); |
| | | bool isStop = this.execution.WaitForEndEx(2000, true, null, null); |
| | | var context = this.tsSockets[i].SequenceFileContext; |
| | | //bool val = context.StationGlobals.Exists("StationState.StopTest", 0); |
| | | //if (val) |
| | | //{ |
| | | // context.StationGlobals.SetValBoolean("StationState.StopTest", 0, true); |
| | | // bool isStop = this.execution.WaitForEndEx(2000, true, null, null); |
| | | //} |
| | | context?.StationGlobals.SetValBoolean("StationState.StopTest", 0, true); |
| | | } |
| | | } |
| | | this.CbProduct.IsEnabled = true; |
| | | this.BtnStartSeq.IsEnabled = true; |
| | | this.BtnStopSeq.IsEnabled = false; |
| | | if (this.execution == null) return true; |
| | | return this.execution.WaitForEndEx(2000, true, null, null); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("Stop Sequence Failed.", ex); |
| | | MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StopSequenceFail")}: {ex.Message}"); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | public void UpdatePositionStatus(int index, string status) |
| | | { |
| | | this.tsSockets[index].UpdateStatus(status); |
| | | this.UpdateTestCounter(); |
| | | } |
| | | |
| | | public void AddTestData(int index, string data) |
| | | { |
| | | string[] TestItems = data.Split(','); |
| | | tsSockets[index].AddTestData(TestItems[0], TestItems[1], TestItems[2], TestItems[3], |
| | | TestItems[4], TestItems[5], TestItems[6]); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// TestStand用户交互事件 |
| | | /// </summary> |
| | |
| | | |
| | | case 10002://更新测试状态 |
| | | string status = e.uiMsg.StringData; |
| | | this.tsSockets[Index].UpdateStatus(status); |
| | | this.UpdateTestCounter(); |
| | | UpdatePositionStatus(Index, status); |
| | | break; |
| | | |
| | | case 10003://发送测试数据 |
| | | string[] TestItems = e.uiMsg.StringData.Split('\t'); |
| | | tsSockets[Index].AddTestData(TestItems[0], TestItems[4], TestItems[1], TestItems[2], TestItems[3], TestItems[5]); |
| | | |
| | | AddTestData(Index, e.uiMsg.StringData); |
| | | break; |
| | | |
| | | case 10004://发送测试过程信息 |
| | |
| | | int ProcessVal = Convert.ToInt32(e.uiMsg.StringData); |
| | | this.tsSockets[Index].SetTestProcess(ProcessVal); |
| | | break; |
| | | case 10031://导出CSV |
| | | this.tsSockets[Index].WriteToCSV(e.uiMsg.StringData); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | |
| | | |
| | | private void UpdateTestCounter() |
| | | { |
| | | int PassNum = 0; |
| | | int FailNum = 0; |
| | | double PassNum = 0; |
| | | double FailNum = 0; |
| | | foreach (SingleControl socket in this.tsSockets) |
| | | { |
| | | PassNum += socket.PassNum; |
| | | FailNum += socket.FailNum; |
| | | } |
| | | this.DisplayCount(PassNum, FailNum); |
| | | UpdateChart(PassNum, FailNum); |
| | | } |
| | | |
| | | private void UpdateChart(int pass, int fail) |
| | | { |
| | | pie.Slices[0].Value = pass; |
| | | pie.Slices[1].Value = fail; |
| | | pieChart.Refresh(); |
| | | } |
| | | |
| | | private void SetTestSeqFile(ProductData product) |
| | | { |
| | | string name = product.Name; |
| | | List<ParameterData> parameters = ParameterManager.GetParametersByProductName(name); |
| | | List<ParameterData> parameters = ProductManager.GetParametersByProductName(name); |
| | | testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString(); |
| | | } |
| | | |
| | |
| | | { |
| | | PassAmount = 0; |
| | | FailAmount = 0; |
| | | DisplayCount(PassAmount, FailAmount); |
| | | UpdateChart(PassAmount, FailAmount); |
| | | //this.OpcHandle.DoFctWriteSingle("Count_Clear", "1", out string ErrMsg); |
| | | foreach (SingleControl socket in tsSockets) |
| | | { |
| | | socket.ResetCounter(); |
| | | } |
| | | DisplayCount(PassAmount, FailAmount); |
| | | } |
| | | } |
| | | |