alielie
2025-10-13 e3868d4d61ded0e76fc8fe3fdacdd9e6d9113cf1
Plugin.TsExecution/TsExecution.xaml.cs
@@ -13,6 +13,7 @@
using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using Panuon.WPF.UI;
using Plugin.TsSupport;
using ScottPlot;
using ScottPlot.Plottables;
using System;
@@ -249,6 +250,20 @@
            }
        }
        private bool _DisableScanner;
        public bool DisableScanner
        {
            get => _DisableScanner;
            set
            {
                if (WriteConfig("DisableScanner", value))
                {
                    Set(ref _DisableScanner, value);
                }
            }
        }
        private string tsModelPath;
        private string dataLogPath;
        private SqliteHelper sqliteHelper;
@@ -270,22 +285,25 @@
            base.SetBaseFolder(folder);
        }
        public override void InitFinish()
        private void CheckSqlHelper()
        {
            this.ReadCount(out int pass, out int fail);
            this.DisplayCount(pass, fail);
            InitProducts();
            ReadConfig();
            if (!File.Exists(dataLogPath))
            string today = DateTime.Now.ToString("yyyyMMdd");
            string dbPath = Path.Combine(dataLogPath, $"Data_{today}.db");
            if (!File.Exists(dbPath))
            {
                SqliteHelper.CreateDatabase(dataLogPath);
                SqliteHelper.CreateDatabase(dbPath);
            }
            sqliteHelper = new SqliteHelper(dataLogPath);
            sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
            if (sqliteHelper == null || sqliteHelper.DataBaseFile != dbPath)
            {
                sqliteHelper?.Dispose();
                sqliteHelper = new SqliteHelper(dbPath);
                sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    sn TEXT NOT NULL,
                    model TEXT,
                    station TEXT NOT NULL,
                    step TEXT NOT NULL,
                    position TEXT,
                    limitDown TEXT,
                    limitUp TEXT,
                    unit TEXT,
@@ -296,6 +314,25 @@
                    consumeTime TEXT, 
                    totalConsumeTime TEXT, 
                    time DATETIME NOT NULL);");
                sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS testResult (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    sn TEXT NOT NULL,
                    model TEXT,
                    station TEXT NOT NULL,
                    position TEXT,
                    status TEXT,
                    result TEXT NOT NULL,
                    time DATETIME NOT NULL);");
            }
        }
        public override void InitFinish()
        {
            this.ReadCount(out int pass, out int fail);
            this.DisplayCount(pass, fail);
            InitProducts();
            ReadConfig();
            CheckSqlHelper();
            base.InitFinish();
        }
@@ -430,13 +467,14 @@
        /// </summary>
        private void InitTsEngine()
        {
            AxApplicationMgr = new AxApplicationMgr();
            AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
            AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
            AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
            AxApplicationMgr.UIMessageEvent +=
                new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
            AxApplicationMgr.ExecutionClosed +=
                new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
            ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
            host.Child = AxApplicationMgr;
            ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
@@ -444,7 +482,25 @@
        private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
        {
            ReleaseSequenceFile();
            log.Info("AxApplicationMgr_EndExecution");
            if (ReleaseSequenceFile())
            {
                log.Info("Release SeqFile Success!");
            }
            else
            {
                log.Warn("Release SeqFile Fail!");
            }
        }
        /// <summary>
        /// 进程结束事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
        {
            //ReleaseSequenceFile();
        }
        private void PluginControl_Loaded(object sender, RoutedEventArgs e)
@@ -542,7 +598,7 @@
                this.AxApplicationMgr.IsEditor = true;
                this.AxApplicationMgr.LoginOnStart = false;
                this.AxApplicationMgr.Start();
                this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
                //this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
            }
            catch (Exception ex)
            {
@@ -571,28 +627,104 @@
        private void ReadConfig()
        {
            ParameterData value;
            bool flag = false;
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableMes");
                _enableMes = bool.Parse(value.Value);
                Set("EnableMes");
                value = ParameterManager.GetCommonParameterByName("DefaultEnableMes");
                if (value != null)
                {
                    flag = bool.Parse(value.Value);
                }
            }
            catch
            {
                _enableMes = false;
                Set("EnableMes");
                flag = false;
            }
            if (flag)
            {
                EnableMes = true;
            }
            else
            {
                try
                {
                    value = ParameterManager.GetCommonParameterByName("EnableMes");
                    if (value == null)
                    {
                        CbEnableMes.Visibility = Visibility.Collapsed;
                    }
                    else
                    {
                        _enableMes = bool.Parse(value.Value);
                        Set("EnableMes");
                    }
                }
                catch
                {
                    _enableMes = false;
                    Set("EnableMes");
                }
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableNGPause");
                _enableNGPause = bool.Parse(value.Value);
                Set("EnableNGPause");
                if (value == null)
                {
                    CbEnableNGPause.Visibility = Visibility.Collapsed;
                }
                else
                {
                    _enableNGPause = bool.Parse(value.Value);
                    Set("EnableNGPause");
                }
            }
            catch
            {
                _enableNGPause = false;
                Set("EnableNGPause");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
                if (value == null)
                {
                    CbEnableDebugMode.Visibility = Visibility.Collapsed;
                }
                else
                {
                    _enableDebugMode = bool.Parse(value.Value);
                    Set("EnableDebugMode");
                }
            }
            catch
            {
                _enableDebugMode = false;
                Set("EnableDebugMode");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("DisableScanner");
                if (value == null)
                {
                    CbDisableScanner.Visibility = Visibility.Collapsed;
                }
                else
                {
                    _DisableScanner = bool.Parse(value.Value);
                    Set("DisableScanner");
                }
            }
            catch
            {
                _DisableScanner = false;
                Set("DisableScanner");
            }
            try
@@ -607,22 +739,18 @@
                Set("EnableCanLog");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableDebugMode");
                _enableDebugMode = bool.Parse(value.Value);
                Set("EnableDebugMode");
            }
            catch
            {
                _enableDebugMode = false;
                Set("EnableDebugMode");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("EnableSimpleMode");
                EnableSimpleMode = bool.Parse(value.Value);
                if (value == null)
                {
                    CbEnableSimpleMode.Visibility = Visibility.Collapsed;
                }
                else
                {
                    EnableSimpleMode = bool.Parse(value.Value);
                }
            }
            catch
            {
@@ -632,7 +760,14 @@
            try
            {
                value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
                UI_ShowInfoDock = bool.Parse(value.Value);
                if (value == null)
                {
                    CbUI_ShowInfoDock.Visibility = Visibility.Collapsed;
                }
                else
                {
                    UI_ShowInfoDock = bool.Parse(value.Value);
                }
            }
            catch
            {
@@ -710,8 +845,21 @@
            }
            catch
            {
                dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard", "DataLog.db");
                dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard");
            }
            try
            {
                value = ParameterManager.GetCommonParameterByName("TsModelPath");
                tsModelPath = value.Value;
            }
            catch
            {
                //@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"
                tsModelPath = @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
            }
            //Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableMes", "true", CountIniPath));
            //EnableCanLog = Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableCanLog", "true", CountIniPath));
@@ -846,8 +994,8 @@
            {
                engine?.Globals.SetValString("StationState.ProductModel", 1, SelectedProduct?.Name);
                engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
                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.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
                this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
                this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
                IsTesting = true;
            }
@@ -976,16 +1124,6 @@
            //this.Close();
        }
        /// <summary>
        /// 进程结束事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
        {
            ReleaseSequenceFile();
        }
        public void UpdatePositionStatus(int index, string status)
        {
            this.tsSockets[index].UpdateStatus(status);
@@ -1009,22 +1147,32 @@
                TestItems[4], TestItems[5], TestItems[6]);
        }
        public void SetPositionBarcode(int index, string barcode)
        public void SetPositionBarcode(int index, string strData)
        {
            this.tsSockets[index].Barcode = barcode;
            if (strData.Contains(";"))
            {
                var strs = strData.Split(';');
                this.tsSockets[index].Barcode = strs[0];
                this.tsSockets[index].Model = strs[1];
            }
            else
            {
                this.tsSockets[index].Barcode = strData;
            }
        }
        public void SavePositionCSV(int index)
        public void SavePositionCSV(int index, string csvPath)
        {
            var time = DateTime.Now;
            string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
            string csvPath = Path.Combine(csvDir, SelectedProduct?.Name ?? "未知产品", time.ToString("yyyyMMdd"), status,
                $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
            //var time = DateTime.Now;
            //string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
            //string csvPath = Path.Combine(csvDir, SelectedProduct?.Name ?? "未知产品", time.ToString("yyyyMMdd"), status,
            //    $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
            this.tsSockets[index].WriteToCSV(csvPath);
        }
        public void SavePositionDB(int index)
        public void SavePositionDB(int index, string status)
        {
            CheckSqlHelper();
            var socket = this.tsSockets[index];
            var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            string snr = socket.Barcode;
@@ -1032,9 +1180,11 @@
            List<string> sqls = new List<string>();
            foreach (var data in socket.Datasource)
            {
                sqls.Add($@"INSERT INTO serialData (sn,station,step,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
('{snr}','','{data.Name}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
                sqls.Add($@"INSERT INTO serialData (sn,model,station,step,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
('{snr}','{socket.Model}','','{data.Name}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
            }
            sqls.Add($@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES
('{snr}','{socket.Model}','','{socket.Status}','{time}','{index}','{status}')");
            sqliteHelper.ExecuteBatchSql(sqls);
        }
@@ -1122,14 +1272,17 @@
                    this.tsSockets[index].SetTestProcess(ProcessVal);
                    break;
                case 10031://导出CSV
                    SavePositionCSV(index);
                    SavePositionDB(index);
                    string[] datas = strData.Split(';');
                    SavePositionCSV(index, datas[0]);
                    SavePositionDB(index, datas[1]);
                    break;
                case 10032://按下标暂停测试
                    this.tsSockets[index].ShowPausePanel();
                    break;
                case 10033:
                    ShowAlarm(strData);
                    break;
                case 10099:
                    break;
                default:
                    break;
@@ -1198,7 +1351,10 @@
            string name = product.Name;
            List<ParameterData> parameters = ProductManager.GetParametersByProductName(name);
            testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
            StartSequence();
            if (AutoExecuteSeq)
            {
                StartSequence();
            }
        }
        private void ClearNum()
@@ -1229,6 +1385,11 @@
            }
        }
        public override void DoClose(object sender, EventArgs e)
        {
            base.DoClose(sender, e);
        }
        /// <summary>
        /// 释放所有的序列文件
        /// </summary>
@@ -1238,18 +1399,35 @@
            {
                lock (this)
                {
                    if (this.testSeq == null)
                        return true;
                    if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
                    //execution.Abort();
                    int count = 10;
                    while (count > 0)
                    {
                        this.testSeq = null;
                        try
                        {
                            if (this.testSeq == null)
                                return true;
                            if (this.engine.ReleaseSequenceFileEx(this.testSeq, 4))
                            {
                                this.testSeq = null;
                            }
                            if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
                            {
                                this.modeSeq = null;
                            }
                            this.engine.UnloadAllModules();
                            return this.testSeq == null && this.modeSeq == null;
                        }
                        catch (Exception ex)
                        {
                            log.Warn($"ReleaseSequenceFile In {count} Times Fail.", ex);
                            count--;
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
                    if (this.engine.ReleaseSequenceFileEx(this.modeSeq, 4))
                    {
                        this.modeSeq = null;
                    }
                    this.engine.UnloadAllModules();
                    return true;
                    log.Warn($"ReleaseSequenceFile Failed.");
                    return false;
                }
            }
            catch (Exception ex)