alielie
2025-05-12 7bf89fd93bc487e8445d6d85bb527251b7371a04
Plugin.TsExecution/TsExecution.xaml.cs
@@ -1,28 +1,29 @@
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
{
@@ -54,6 +55,7 @@
        private Chart chart;
        #endregion
        public static ILog logger { get; private set; }
        private List<SingleControl> tsSockets = new List<SingleControl>();
        /// <summary>
        /// 样件模式状态
@@ -92,6 +94,12 @@
            }
        }
        public override void SetLogger(ILog logger)
        {
            base.SetLogger(logger);
            TsExecution.logger = logger;
        }
        private ObservableCollection<ProductData> products;
        public ObservableCollection<ProductData> Products
@@ -116,6 +124,40 @@
            }
        }
        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;
@@ -125,7 +167,6 @@
            InitTsEngine();
            //初始化TestStand引擎
            this.InitTestStandEngine();
        }
        public override void SetBaseFolder(string folder)
@@ -138,7 +179,6 @@
        {
            this.ReadCount(out int pass, out int fail);
            this.DisplayCount(pass, fail);
            UpdateChart(pass, fail);
            InitProducts();
            base.InitFinish();
        }
@@ -173,7 +213,7 @@
        private void InitProducts()
        {
            Products = ParameterManager.GetProducts<ObservableCollection<ProductData>>();
            Products = ProductManager.GetProducts<ObservableCollection<ProductData>>();
            if (Products != null && Products.Count > 0)
            {
                List<ParameterData> parameters =
@@ -214,6 +254,7 @@
                    {
                        try
                        {
                            ReadConfig();
                            //连接OPChandle
                            //this.OpcHandle.Connect2("127.0.0.1", 6543, 18081, out string ErrMsg, null);
                            //启动测试进程
@@ -248,11 +289,25 @@
        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);
            }
@@ -293,11 +348,38 @@
        /// <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);
@@ -308,9 +390,9 @@
        /// </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)
            {
@@ -324,6 +406,11 @@
            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);
        }
@@ -363,7 +450,6 @@
                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;
@@ -390,17 +476,31 @@
            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"));
        }
@@ -408,27 +508,32 @@
        /// <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;
            }
        }
@@ -508,6 +613,19 @@
            }
        }
        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>
@@ -527,14 +645,11 @@
                    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://发送测试过程信息
@@ -608,6 +723,9 @@
                        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;
                }
@@ -620,28 +738,20 @@
        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();
        }
@@ -651,13 +761,12 @@
            {
                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);
            }
        }