From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点

---
 Plugin.StandardTest/StandardTestUI.xaml.cs | 1906 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,906 insertions(+), 0 deletions(-)

diff --git a/Plugin.StandardTest/StandardTestUI.xaml.cs b/Plugin.StandardTest/StandardTestUI.xaml.cs
new file mode 100644
index 0000000..6c910a3
--- /dev/null
+++ b/Plugin.StandardTest/StandardTestUI.xaml.cs
@@ -0,0 +1,1906 @@
+锘縰sing HMI.Base;
+using HMI.Core.Api;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.Simple.Util;
+using HMI.UI.Util;
+using HMI.Util;
+using LiveChartsCore;
+using LiveChartsCore.SkiaSharpView;
+using LiveChartsCore.SkiaSharpView.Painting;
+using log4net;
+using NationalInstruments.TestStand.Interop.API;
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using Plugin.TsSupport;
+using SkiaSharp;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.StandardTest
+{
+    /// <summary>
+    /// UserControl1.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class StandardTestUI : PluginMaskControl
+    {
+        #region TestStand浜嬩欢
+        /// <summary>
+        /// TS 寮曟搸
+        /// </summary>
+        //private Engine engine = null;
+
+        ///// <summary>
+        ///// 娴嬭瘯搴忓垪
+        ///// </summary>
+        //private SequenceFile testSeq = null;
+
+        ///// <summary>
+        ///// 娴嬭瘯妯″瀷搴忓垪
+        ///// </summary>
+        //private SequenceFile modeSeq = null;
+
+        //private Execution execution = null;
+
+        private string testSeqFile = string.Empty;
+
+        public ITestExecutionWrapper testExecutionWrapper { get; private set; }
+        #endregion
+
+        public static ILog logger { get; private set; }
+        public List<SingleControl> tsSockets { get; private set; } = new List<SingleControl>();
+        /// <summary>
+        /// 鏍蜂欢妯″紡鐘舵��
+        /// </summary>
+        private bool sampleStatus;
+        public bool SampleStatus
+        {
+            get { return sampleStatus; }
+            set
+            {
+                Set(ref sampleStatus, value);
+                SampleTest(value);
+            }
+        }
+
+        private string _currentUserCode;
+
+        public string CurrentUserCode
+        {
+            get { return _currentUserCode; }
+            set { Set(ref _currentUserCode, value); }
+        }
+
+
+        private bool isLoadOK = false;
+
+        private int PassAmount = 0;
+        private int FailAmount = 0;
+
+        /// <summary>
+        /// Socket鏁伴噺
+        /// </summary>
+        private int socketNum = 1;
+
+        private ProductData selectedProduct;
+
+        private MSMQHelper mSMQHelper = new MSMQHelper("HMI_Alarm");
+
+        public ProductData SelectedProduct
+        {
+            get { return selectedProduct; }
+            set
+            {
+                Set(ref selectedProduct, value);
+                CurrentProductModel = value?.Name;
+                if (tsSockets != null)
+                {
+                    foreach (SingleControl socket in tsSockets)
+                    {
+                        socket.RefreshProduct(value);
+                        // socket.RefreshProbeCount(value);
+                    }
+                }
+                SetTestSeqFile(value);
+            }
+        }
+
+        private string currentProductModel;
+        public string CurrentProductModel
+        {
+            get => currentProductModel;
+            set
+            {
+                Set(ref currentProductModel, value);
+            }
+        }
+
+        public override void SetLogger(ILog logger)
+        {
+            base.SetLogger(logger);
+            StandardTestUI.logger = logger;
+        }
+
+        private ObservableCollection<ProductData> products;
+
+        public ObservableCollection<ProductData> Products
+        {
+            get { return products; }
+            set
+            {
+                Set(ref products, value);
+            }
+        }
+
+        public List<double> FontSizeSource { get; set; } = new List<double> {
+            10,11,12,13,14,15,16,17,18,19,20
+        };
+
+        private string CountIniPath;
+        private bool IsOptRequirePassword;
+
+        private bool alarmVisiable;
+        public bool AlarmVisiable
+        {
+            get => alarmVisiable;
+            set
+            {
+                Set(ref alarmVisiable, value);
+            }
+        }
+
+        private bool _enableMes;
+        public bool EnableMes
+        {
+            get => _enableMes;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableMes", value))
+                    {
+                        Set(ref _enableMes, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableCanLog;
+        public bool EnableCanLog
+        {
+            get => _enableCanLog;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableCanLog", value))
+                    {
+                        Set(ref _enableCanLog, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableDebugMode;
+        public bool EnableDebugMode
+        {
+            get => _enableDebugMode;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableDebugMode", value))
+                    {
+                        Set(ref _enableDebugMode, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableNGPause;
+        public bool EnableNGPause
+        {
+            get => _enableNGPause;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableNGPause", value))
+                    {
+                        Set(ref _enableNGPause, value);
+                    }
+                }
+            }
+        }
+
+        private bool _enableSimpleMode;
+        public bool EnableSimpleMode
+        {
+            get => _enableSimpleMode;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("EnableSimpleMode", value))
+                    {
+                        Set(ref _enableSimpleMode, value);
+                        foreach (var cell in tsSockets) cell.SetSimpleUI(value);
+                    }
+                }
+            }
+        }
+
+        private bool _ui_showInfoDock;
+        public bool UI_ShowInfoDock
+        {
+            get => _ui_showInfoDock;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("UI_ShowInfoDock", value))
+                    {
+                        Set(ref _ui_showInfoDock, value);
+                        detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+                    }
+                }
+            }
+        }
+
+        private bool autoExecuteSeq;
+        public bool AutoExecuteSeq
+        {
+            get => autoExecuteSeq;
+            set
+            {
+                Set(ref autoExecuteSeq, value);
+            }
+        }
+
+        private string currentWorkorder;
+        public string CurrentWorkorder
+        {
+            get => currentWorkorder;
+            set
+            {
+                if (WriteIni("UI_CurrentWorkorder", value))
+                {
+                    Set(ref currentWorkorder, value);
+                    testExecutionWrapper?.SetStationGlobalValue("StationState.WorkOrder", 1, value);
+                    testExecutionWrapper?.CommitToDisk(false);
+                }
+            }
+        }
+
+        private bool _DisableScanner;
+        public bool DisableScanner
+        {
+            get => _DisableScanner;
+            set
+            {
+                if (RequirePassword() == true)
+                {
+                    if (WriteConfig("DisableScanner", value))
+                    {
+                        Set(ref _DisableScanner, value);
+                    }
+                }
+            }
+        }
+
+        private bool enableManualDebug;
+        public bool EnableManualDebug
+        {
+            get => enableManualDebug;
+            set
+            {
+                if (IsTesting)
+                {
+                    MsgBoxHelper2.Warn("璇峰厛缁撴潫鑷姩娴嬭瘯");
+                    return;
+                }
+                Set(ref enableManualDebug, value);
+            }
+        }
+
+        public string tsModelPath { get; private set; }
+        private string dataLogPath;
+        private SqliteHelper sqliteHelper;
+
+        private int probeWarn;
+
+        #region 鍥捐〃
+        private SolidColorPaint tooltipTextPaint = new SolidColorPaint(SKColors.Black)
+        {
+            SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+        };
+
+        public SolidColorPaint TooltipTextPaint
+        {
+            get => tooltipTextPaint;
+            set
+            {
+                Set(ref tooltipTextPaint, value);
+            }
+        }
+
+        public ISeries[] Chart1_series { get; set; } = new PieSeries<double>[]
+       {
+            new PieSeries<double> {
+                Name="Passed",
+                Values = new double[]{ 0},
+            DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Outer,
+             DataLabelsSize = 15,
+             DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
+                 SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+             },
+             Fill = new SolidColorPaint(new SKColor(0, 128, 0)),
+             DataLabelsFormatter =
+                point =>point.StackedValue.Total>0?
+                    $"Passed\r\n璁℃暟:{point.Coordinate.PrimaryValue}\r\n鍗犳瘮:{point.StackedValue.Share:P2}":"",
+             ToolTipLabelFormatter = point => $"{point.StackedValue.Share:P2}"
+            },
+            new PieSeries<double> { Values = new double[]{ 0} ,
+                Name="Failed",
+            DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Outer,
+             DataLabelsSize = 15,
+             DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
+                 SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+             },
+             Fill = new SolidColorPaint(new SKColor(255, 0, 0)),
+             DataLabelsFormatter =
+                point =>point.StackedValue.Total>0?
+                    $"Failed\r\n璁℃暟:{point.Coordinate.PrimaryValue}\r\n鍗犳瘮:{point.StackedValue.Share:P2}":"",
+             ToolTipLabelFormatter = point => $"{point.StackedValue.Share:P2}"},
+       };
+        #endregion
+
+        public StandardTestUI()
+        {
+            DataContext = this;
+            InitializeComponent();
+
+            InitChart();
+            InitTsEngine();
+        }
+
+        public override void SetBaseFolder(string folder)
+        {
+            CountIniPath = Path.Combine(folder, "Count.ini");
+            base.SetBaseFolder(folder);
+        }
+
+        private void CheckSqlHelper()
+        {
+            string today = DateTime.Now.ToString("yyyyMMdd");
+            string dbPath = Path.Combine(dataLogPath, $"Data_{today}.db");
+            if (!File.Exists(dbPath))
+            {
+                SqliteHelper.CreateDatabase(dbPath);
+            }
+            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,
+                    offset TEXT,
+                    value TEXT,
+                    status TEXT,
+                    finalStatus TEXT,
+                    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);
+            ReadConfig();
+            InitProducts();
+            CheckSqlHelper();
+            base.InitFinish();
+
+            if (ParamSetting.EnableAutoModel)
+            {
+                selectModelPanel.Visibility = Visibility.Collapsed;
+                autoModelPanel.Visibility = Visibility.Visible;
+                CurrentProductModel = string.Empty;
+            }
+
+            try
+            {
+                UserInfo user = UserInfo.User;
+                CurrentUserCode = user?.Code;
+
+                testExecutionWrapper?.SetStationGlobalValue("StationState.OPID", 1, CurrentUserCode);
+                testExecutionWrapper?.CommitToDisk(false);
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Get Login User Failed.", ex);
+            }
+            RefreshUIConfig();
+        }
+
+        /// <summary>
+        /// 鍒锋柊UI閰嶇疆
+        /// </summary>
+        private void RefreshUIConfig()
+        {
+            try
+            {
+                bool enableManualDebug = ParameterManager.GetCommonParameterByName("EnableManualDebug", false);
+                if (enableManualDebug)
+                {
+                    Cb_ManualDebug.Visibility = Visibility.Visible;
+                    EnableManualDebug = false;
+                }
+                else
+                {
+                    Cb_ManualDebug.Visibility = Visibility.Collapsed;
+                    EnableManualDebug = false;
+                }
+
+            }
+            catch (Exception ex)
+            {
+                log.Error("RefreshUIConfig Error.", ex);
+            }
+        }
+
+        //private MQConnector mqConnector;
+        //private void InitMQ()
+        //{
+        //    mqConnector = new MQConnector("UI");
+        //    mqConnector.BeginReceive(HandleMQUI);
+        //}
+        //void HandleMQUI(string msg)
+        //{
+        //    string[] arr = msg.Split('|');
+        //    int eventCode = int.Parse(arr[0]);
+        //    int index = int.Parse(arr[1]);
+        //    string strData = arr[2];
+        //    Dispatcher.BeginInvoke(new Action(() =>
+        //    {
+        //        HandleUIMessage(eventCode, index, strData);
+        //    }));
+        //}
+
+        /// <summary>
+        /// 鍒濆鍖朩inform鍥捐〃
+        /// </summary>
+        private void InitChart()
+        {
+            //        pieChart.Plot.Axes.Frameless();
+            //        pieChart.Plot.HideGrid();
+            //        pieChart.Plot.DataBackground.Color = ScottPlot.Colors.Transparent;
+
+            //        var legend = pieChart.Plot.ShowLegend(Alignment.UpperRight);
+            //        legend.Alignment = Alignment.UpperRight;
+            //        legend.Padding = new PixelPadding(0);
+            //        legend.FontSize = (float)WidthSizeConverter.CountFontSize(20, 300, 300);
+            //        pieChart.UserInputProcessor.Disable();
+            //        pieChart.Plot.Font.Automatic();
+
+            //        List<PieSlice> slices = new List<PieSlice> {
+            //new PieSlice() { Value = 5, FillColor = ScottPlot.Colors.Green,
+            //    LabelFontSize = (float)WidthSizeConverter.CountFontSize(20,300,300),
+            //    Label = "Pass",LegendText="Pass" },
+            //new PieSlice() { Value = 2, FillColor = ScottPlot.Colors.Red,
+            //    LabelFontSize = (float)WidthSizeConverter.CountFontSize(20,300,300),
+            //    Label = "Fail",LegendText="Fail" } };
+
+
+            //        pie = pieChart.Plot.Add.Pie(slices);
+        }
+
+        private bool? RequirePassword()
+        {
+            if (!IsOptRequirePassword) return true;
+            var win = new RequirePasswordWindow
+            {
+                Owner = Window.GetWindow(this)
+            };
+            return win.ShowDialog();
+        }
+
+        private void InitProducts()
+        {
+            RefershUI();
+            //Products = ProductManager.GetProducts<ObservableCollection<ProductData>>();
+            //if (Products != null && Products.Count > 0)
+            //{
+            //    string lastModel = testExecutionWrapper?.GetStationGlobalValue<string>("StationState.ProductModel", 1);
+            //    var tempProduct = Products[0];
+            //    if (!string.IsNullOrEmpty(lastModel))
+            //    {
+            //        var product = Products.FirstOrDefault(p => p.Name == lastModel);
+            //        if (product != null)
+            //        {
+            //            tempProduct = product;
+            //        }
+            //    }
+            //    SelectedProduct = tempProduct;
+            //}
+            //RefershUI();
+            //if (tsSockets != null)
+            //{
+            //    foreach (SingleControl socket in tsSockets)
+            //    {
+            //        socket.RefreshProduct(SelectedProduct);
+            //    }
+            //}
+            //SampleStatus = false;
+        }
+
+        private bool _isTesting = false;
+        public bool IsTesting
+        {
+            get { return _isTesting; }
+            set
+            {
+                Set(ref _isTesting, value);
+                Dispatcher.Invoke(() =>
+                {
+                    BtnStartSeq.IsEnabled = !value;
+                    BtnStopSeq.IsEnabled = value;
+                    CbProduct.IsEnabled = !value;
+                });
+            }
+        }
+
+        /// <summary>
+        /// 鍒濆鍖朤estStand寮曟搸
+        /// </summary>
+        private void InitTsEngine()
+        {
+            if (ParamSetting.EngineType == "Tap")
+            {
+                testExecutionWrapper = new TapWrapper();
+            }
+            else
+            {
+                testExecutionWrapper = new TeststandWrapper();
+            }
+
+            testExecutionWrapper.EndExecutionEvent += TestExecutionWrapper_EndExecutionEvent;
+            testExecutionWrapper.UIMessageEvent += TestExecutionWrapper_UIMessageEvent;
+            if (testExecutionWrapper is TeststandWrapper tsw)
+            {
+                var AxApplicationMgr = tsw.AxApplicationMgr;
+                ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
+                host.Child = AxApplicationMgr;
+                ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+            }
+            try
+            {
+
+                testSeqFile = ParameterManager.GetCommonParameterByName<string>("BurnInMainSeq", string.Empty);
+            }
+            catch
+            {
+
+            }
+            testExecutionWrapper.Init();
+        }
+
+        private void TestExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+        {
+            try
+            {
+                int eventCode = Convert.ToInt32(e.EventCode);
+                int MethodCode = Convert.ToInt16(e.NumberData);//SocketIndex
+                var data = e.Data;
+                string strData = e.StrData;
+
+                try
+                {
+                    log.Debug($"Event: {eventCode}, MethodCode: {MethodCode}, StringData: {strData}");
+                }
+                catch
+                {
+
+                }
+                HandleUIMessage(eventCode, MethodCode, strData, data);
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Ts Event Error.", ex);
+            }
+        }
+
+        private void TestExecutionWrapper_EndExecutionEvent(object sender, ExecutionEndEvent e)
+        {
+            log.Info("AxApplicationMgr_EndExecution");
+            if (ReleaseSequenceFile())
+            {
+                IsTesting = false;
+                log.Info("Release SeqFile Success!");
+                if (canSwitchModel) switchAction?.Invoke();
+            }
+            else
+            {
+                log.Warn("Release SeqFile Fail!");
+            }
+        }
+
+        private volatile bool canSwitchModel = false;
+        private volatile Action switchAction = null;
+
+        private void PluginControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            ShowMask(() =>
+            {
+                try
+                {
+                    //Dispatcher.Invoke(() =>
+                    //{
+
+                    //});
+                    isLoadOK = true;
+                    if (AutoExecuteSeq) StartSequence();
+                }
+                catch (Exception ex)
+                {
+                    log.Error("TsExecution Loaded Failed.", ex);
+                    MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
+                }
+
+                Dispatcher.Invoke(() =>
+                {
+                    if (isLoadOK) Loaded -= PluginControl_Loaded;
+                });
+            }, (ex) =>
+            {
+                ToastHelper.Error("Loaded Failed.");
+                log.Error("Loaded Error.", ex);
+            }, null, LangUtil.Get("App.UsercontrolIsLoading"));
+        }
+
+        private void RefershUI()
+        {
+            panel.Children.Clear();
+            string[] names = ParamSetting.SocketNames.Split(',');
+
+            //閲嶆柊鐢熸垚瀛愰潰鏉�
+            for (int i = 0; i < this.socketNum; i++)
+            {
+                string name = string.Empty;
+                if (i < names.Length)
+                {
+                    name = names[i];
+                }
+
+                SingleControl control = new SingleControl(i, CountIniPath, this.probeWarn)
+                {
+                    SocketName = name
+                };
+                control.parent = this;
+                panel.Children.Add(control);
+                tsSockets.Add(control);
+
+                //createChildInNewThread(i, CountIniPath, ProbeWarn);
+            }
+            if (tsSockets.Count == 1)
+            {
+                panel.Columns = 1;
+            }
+            else if (tsSockets.Count > 0 && (tsSockets.Count % 3) == 0)
+            {
+                panel.Columns = 3;
+            }
+            else
+            {
+                panel.Columns = 2;
+            }
+        }
+
+        /// <summary>
+        /// 璇诲彇Count閰嶇疆鏂囦欢鐨刾ass鍜宖ail鏁�
+        /// </summary>
+        /// <param name="pass">鍚堟牸鏁�</param>
+        /// <param name="fail">涓嶅悎鏍兼暟</param>
+        private void ReadCount(out int pass, out int fail)
+        {
+            pass = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Pass", "0", CountIniPath));
+            fail = Convert.ToInt32(IniFileHelper.ReadIniData("Count", "Fail", "0", CountIniPath));
+            var fontSize = Convert.ToDouble(IniFileHelper.ReadIniData("Config", "TableFontSize", "12", CountIniPath));
+            this.Resources["tableFontSize"] = 20d;
+            //CbFontSize.SelectedItem = fontSize;
+        }
+
+        private string csvDir;
+
+        /// <summary>
+        /// 璇诲彇閰嶇疆鏂囦欢閲岀殑鍑犱釜灞炴��
+        /// </summary>
+        /// <param name="pass"></param>
+        /// <param name="fail"></param>
+        private void ReadConfig()
+        {
+            HMI.Core.Entity.ParameterData value;
+
+
+            bool flag = false;
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("DefaultEnableMes");
+                if (value != null)
+                {
+                    flag = bool.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                flag = false;
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("SocketNum");
+                if (value != null)
+                {
+                    this.socketNum = int.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                this.socketNum = 2;
+            }
+
+            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");
+                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
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableCanLog");
+                _enableCanLog = bool.Parse(value.Value);
+                Set("EnableCanLog");
+            }
+            catch
+            {
+                _enableCanLog = false;
+                Set("EnableCanLog");
+            }
+
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableSimpleMode");
+                if (value == null)
+                {
+                    CbEnableSimpleMode.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    EnableSimpleMode = bool.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                EnableSimpleMode = false;
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
+                if (value == null)
+                {
+                    CbUI_ShowInfoDock.Visibility = Visibility.Collapsed;
+                }
+                else
+                {
+                    UI_ShowInfoDock = bool.Parse(value.Value);
+                }
+            }
+            catch
+            {
+                UI_ShowInfoDock = false;
+            }
+
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("AutoExecuteSeq");
+                AutoExecuteSeq = bool.Parse(value.Value);
+            }
+            catch
+            {
+                AutoExecuteSeq = true;
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("TestReportFolder");
+                csvDir = value.Value;
+                if (!Directory.Exists(csvDir))
+                {
+                    Directory.CreateDirectory(csvDir);
+                }
+            }
+            catch
+            {
+                csvDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("IsOptRequirePassword");
+                IsOptRequirePassword = bool.Parse(value.Value);
+            }
+            catch
+            {
+                IsOptRequirePassword = false;
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("UI_CurrentWorkorder");
+                CurrentWorkorder = value.Value;
+            }
+            catch
+            {
+                CurrentWorkorder = string.Empty;
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("TS_ShowTitleWorkorder");
+                var boo = bool.Parse(value.Value);
+                if (boo)
+                {
+                    workorderPanel.Visibility = Visibility.Visible;
+                }
+            }
+            catch
+            {
+            }
+
+            dataLogPath = ParamSetting.DataLogFolder;
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("TsModelPath");
+                tsModelPath = 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"
+                tsModelPath = @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
+            }
+
+            try
+            {
+
+                value = ParameterManager.GetCommonParameterByName("ProbeWarn");
+                probeWarn = int.Parse(value?.Value);
+            }
+            catch
+            {
+                probeWarn = 0;
+            }
+            //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 bool WriteConfig(string name, bool value)
+        {
+            try
+            {
+                if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+                {
+                    foreach (var ts in tsSockets)
+                    {
+                        testExecutionWrapper.SetStationGlobalValue($"SystemSetting.{name}", 1, value);
+                        if (testExecutionWrapper is TeststandWrapper tsw)
+                        {
+                            if (name == "EnableDebugMode" && tsw.context?.Sequence != null)
+                            {
+                                tsw.context.Sequence.FailureAction =
+                                    value ? FailureActions.FailureAction_None : FailureActions.FailureAction_GotoCleanup;
+                            }
+                        }
+
+                    }
+                    return true;
+                }
+                else
+                {
+                    throw new Exception(errMsg);
+                }
+            }
+            catch (Exception ex)
+            {
+                MsgBoxHelper2.Error(ex.Message);
+                return false;
+            }
+        }
+
+        private bool WriteIni(string name, object value)
+        {
+            //IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath);
+            try
+            {
+                if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+                {
+                    return true;
+                }
+                else
+                {
+                    throw new Exception(errMsg);
+                }
+            }
+            catch (Exception ex)
+            {
+                MsgBoxHelper2.Error(ex.Message);
+                return false;
+            }
+        }
+
+        private void WriteCount(double pass, double fail)
+        {
+            IniFileHelper.WriteIniData("Count", "Pass", pass.ToString(), CountIniPath);
+            IniFileHelper.WriteIniData("Count", "Fail", fail.ToString(), CountIniPath);
+        }
+
+        /// <summary>
+        /// 鍒锋柊璁℃暟
+        /// </summary>
+        /// <param name="pass">鍚堟牸鏁�</param>
+        /// <param name="fail">涓嶅悎鏍兼暟</param>
+        private void DisplayCount(double pass, double fail)
+        {
+            double total = pass + fail;
+            double passRate;
+            if (total == 0)
+            {
+                passRate = 0.00;
+            }
+            else
+            {
+                passRate = (double)pass / (double)total * 100.00;
+            }
+            this.TbPass.Text = pass.ToString();
+            this.TbFail.Text = fail.ToString();
+            this.TbTotal.Text = total.ToString();
+            this.TbPassRate.Text = string.Format("{0:0.00}", passRate) + "%";
+
+            Dispatcher.BeginInvoke(new Action(() =>
+            {
+                Chart1_series[0].Values = new double[] { pass };
+                Chart1_series[1].Values = new double[] { fail };
+                // webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
+            }));
+
+            WriteCount(pass, fail);
+        }
+
+        /// <summary>
+        /// 鍚姩鏍蜂欢娴嬭瘯
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <exception cref="Exception"></exception>
+        private void SampleTest(bool flag)
+        {
+            try
+            {
+                testExecutionWrapper.SetStationGlobalValue("StationState.Sample", 1, flag);
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(LangUtil.Get("Ts.SampleTestFail"), ex);
+            }
+        }
+
+        /// <summary>
+        /// 鍚姩娴嬭瘯搴忓垪
+        /// </summary>
+        private void StartSequence()
+        {
+            log.Info($"Start ATE Seq isLoadOK:{isLoadOK}");
+            if (!isLoadOK) return;
+            if (ParamSetting.EnableAutoModel)
+            {
+                try
+                {
+                    var path = ParameterManager.GetCommonParameterByName<string>("CommonMainSeq", "");
+                    if (string.IsNullOrEmpty(path))
+                    {
+                        Dispatcher.Invoke(() =>
+                        {
+                            MsgBoxHelper.Error(this, $"璇峰厛璁剧疆CommonMainSeq鍙傛暟");
+                        });
+                        return;
+                    }
+                    this.testSeqFile = path;
+                    testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath);
+                    //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;
+                }
+                catch (Exception ex)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        log.Error("Start Sequence Failed.", ex);
+                        MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StartSequenceFail")}: {ex.Message}");
+                    });
+                }
+            }
+            else
+            {
+                //MaskWindow mask = new MaskWindow();
+                try
+                {
+                    //for (int i = 0; i < tsSockets.Count; i++)
+                    //{
+                    //    testExecutionWrapper?.SetStationGlobalValue($"StationHMI.UUTHMI[{i}].Model", 1, CurrentProductModel);
+                    //}
+                    //testExecutionWrapper?.CommitToDisk(false);
+                    testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath);
+                    IsTesting = true;
+                }
+                catch (Exception ex)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        log.Error("Start Sequence Failed.", ex);
+                        MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StartSequenceFail")}: {ex.Message}");
+                    });
+                }
+                finally
+                {
+
+                }
+            }
+        }
+
+        public void StopSequenceClick()
+        {
+            canSwitchModel = false;
+            switchAction = null;
+            ShowMask(() =>
+            {
+                bool stoped = StopSequence();
+            }, null, null, LangUtil.Get("App.SequenceIsStopping"));
+        }
+
+        /// <summary>
+        /// 鍋滄娴嬭瘯搴忓垪
+        /// </summary>
+        private bool StopSequence()
+        {
+            try
+            {
+                testExecutionWrapper.SetStationGlobalValue("StationHMI.AllStop", 1, true);
+
+
+                //bool res = this.execution.WaitForEndEx(-1, true, null, null);
+                bool res = this.testExecutionWrapper.WaitForExit();
+                //if (this.execution != null)
+                //    Marshal.ReleaseComObject(this.execution);
+                //this.execution = null;
+                return res;
+            }
+            catch (Exception ex)
+            {
+                log.Error("Stop Sequence Failed.", ex);
+                MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StopSequenceFail")}: {ex.Message}");
+                return false;
+            }
+        }
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            Button btn = sender as Button;
+            switch (btn.Name)
+            {
+                case "BtnStartSeq":
+                    StartClick();
+                    break;
+                case "BtnStopSeq":
+                    StopSequenceClick();
+                    break;
+                case "BtnClearNum":
+                    ClearNum();
+                    break;
+                case "BtnSample":
+                    SampleStatus = !SampleStatus;
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void StartClick()
+        {
+            canSwitchModel = true;
+            ShowMask(() =>
+            {
+                StartSequence();
+            }, null, null, LangUtil.Get("Ts.SequenceIsStarting"));
+        }
+
+        public void UpdatePositionStatus(int index, string status)
+        {
+            this.tsSockets[index].UpdateStatus(status);
+            OnStatusPublished(index, status);
+            this.UpdateTestCounter();
+        }
+
+        private void OnStatusPublished(int index, string status)
+        {
+            if (ParamSetting.CustomerCode != "SOUND")
+            {
+                return;
+            }
+            if (status == "Passed" || status == "Failed")
+            {
+                SaveSOUNDExcel(index, status);
+            }
+        }
+
+        private string ConvertStatus(string status)
+        {
+            if (string.Equals(status, "passed", StringComparison.OrdinalIgnoreCase))
+            {
+                return "Pass";
+            }
+            else
+            {
+                return "Fail";
+            }
+        }
+
+        #region 妗戝痉瀹氬埗
+        private ICell CreateCell(ISheet sheet, int r, int c, ICellStyle style)
+        {
+            var row = sheet.GetRow(r);
+            if (row == null)
+            {
+                row = sheet.CreateRow(r);
+            }
+            var cell = row.GetCell(c);
+            if (cell == null)
+            {
+                cell = row.CreateCell(c);
+            }
+            if (style != null)
+            {
+                cell.CellStyle = style;
+            }
+            return cell;
+        }
+
+        private string GetOutputFolder()
+        {
+            var value = ParameterManager.GetCommonParameterByName("SOUND_Output");
+            if (value != null)
+            {
+                return value.Value;
+            }
+            return ParamSetting.DataLogFolder;
+        }
+
+        private void SaveSOUNDExcel(int index, string status)
+        {
+            lock (this)
+            {
+                try
+                {
+                    string outputFolder = GetOutputFolder();
+
+                    var socket = this.tsSockets[index];
+                    DateTime testTime = DateTime.Now;
+                    string filePath = Path.Combine(outputFolder, $"{testTime.ToString("yy-MM-dd")}_{CurrentProductModel}.xls");
+                    if (!File.Exists(filePath))
+                    {
+                        Dictionary<string, int> columnMap = new Dictionary<string, int>();
+                        HSSFWorkbook workbook = new HSSFWorkbook();
+                        ISheet sheet = workbook.CreateSheet("Sheet1");
+
+                        ICellStyle border = workbook.CreateCellStyle();
+                        border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
+                        border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                        border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                        border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                        border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+
+
+                        ICellStyle red = workbook.CreateCellStyle();
+                        red.CloneStyleFrom(border);
+                        red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
+                        red.FillPattern = FillPattern.SolidForeground;
+
+                        ICellStyle green = workbook.CreateCellStyle();
+                        green.CloneStyleFrom(border);
+                        green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index;
+                        green.FillPattern = FillPattern.SolidForeground;
+
+                        CreateCell(sheet, 1, 0, border);
+                        CreateCell(sheet, 1, 1, border);
+                        CreateCell(sheet, 1, 2, border);
+                        CreateCell(sheet, 1, 3, border);
+                        CreateCell(sheet, 1, 4, border);
+
+                        CreateCell(sheet, 2, 0, border);
+                        CreateCell(sheet, 2, 1, border);
+                        CreateCell(sheet, 2, 2, border);
+                        CreateCell(sheet, 2, 3, border);
+                        CreateCell(sheet, 2, 4, border).SetCellValue("涓婇檺");
+
+                        CreateCell(sheet, 3, 0, border).SetCellValue("娴嬭瘯鏃堕棿");
+                        CreateCell(sheet, 3, 1, border).SetCellValue("娴嬭瘯浜�");
+                        CreateCell(sheet, 3, 2, border).SetCellValue("娴嬭瘯璁惧");
+                        CreateCell(sheet, 3, 3, border).SetCellValue("鏉″舰鐮�");
+                        CreateCell(sheet, 3, 4, border).SetCellValue("涓嬮檺");
+
+                        int column = 5;
+                        int row = 4;
+
+                        CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*"));
+                        CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name);
+                        CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName);
+                        CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode);
+                        CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status));
+
+                        foreach (var data in socket.Datasource)
+                        {
+                            int col = column;
+                            if (columnMap.ContainsKey(data.Name))
+                            {
+                                col = columnMap[data.Name];
+                            }
+                            else
+                            {
+                                columnMap[data.Name] = column++;
+                            }
+
+                            CreateCell(sheet, 1, col, border).SetCellValue(data.Name);
+                            CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp);
+                            CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown);
+                            CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value);
+                        }
+                        using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
+                        {
+                            workbook.Write(fs);
+                        }
+                    }
+                    else
+                    {
+                        using (FileStream fs = File.OpenRead(filePath))
+                        {
+                            IWorkbook workbook = new HSSFWorkbook(fs);
+                            ICellStyle border = workbook.CreateCellStyle();
+                            border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
+                            border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                            border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                            border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+                            border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+
+
+                            ICellStyle red = workbook.CreateCellStyle();
+                            red.CloneStyleFrom(border);
+                            red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
+                            red.FillPattern = FillPattern.SolidForeground;
+
+                            ICellStyle green = workbook.CreateCellStyle();
+                            green.CloneStyleFrom(border);
+                            green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index;
+                            green.FillPattern = FillPattern.SolidForeground;
+
+                            ISheet sheet = workbook.GetSheet("Sheet1");
+                            Dictionary<string, int> columnMap = new Dictionary<string, int>();
+                            var titleRow = sheet.GetRow(1);
+                            for (int i = 0; i < titleRow.LastCellNum; i++)
+                            {
+                                if (!string.IsNullOrEmpty(titleRow.GetCell(i).StringCellValue))
+                                {
+                                    columnMap[titleRow.GetCell(i).StringCellValue] = i;
+                                }
+                            }
+                            int row = sheet.LastRowNum + 1;
+                            CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*"));
+                            CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name);
+                            CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName);
+                            CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode);
+                            CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status));
+
+                            foreach (var data in socket.Datasource)
+                            {
+                                int col = titleRow.LastCellNum;
+                                if (columnMap.ContainsKey(data.Name))
+                                {
+                                    col = columnMap[data.Name];
+                                }
+                                else
+                                {
+                                    columnMap[data.Name] = col;
+                                }
+
+                                CreateCell(sheet, 1, col, border).SetCellValue(data.Name);
+                                CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp);
+                                CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown);
+                                CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value);
+                            }
+                            using (FileStream nfs = new FileStream(filePath, FileMode.OpenOrCreate))
+                            {
+                                workbook.Write(nfs);
+                            }
+                        }
+                    }
+
+                }
+                catch (Exception ex)
+                {
+                    log.Error("SOUND Export Excel Data Error.", ex);
+                }
+            }
+        }
+        #endregion
+
+        public void UpdatePositionProcessValue(int index, int value)
+        {
+            this.tsSockets[index].SetTestProcess(value);
+        }
+
+        public void PausePosition(int index)
+        {
+            this.tsSockets[index].ShowPausePanel();
+        }
+
+        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]);
+        }
+
+        public void SetPositionBarcode(int index, string strData)
+        {
+            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, 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");
+            this.tsSockets[index].WriteToCSV(csvPath);
+        }
+
+        public void SaveTemplateCSV(int index)
+        {
+            var time = DateTime.Now;
+            string status = this.tsSockets[index].Status == "Passed" ? "PASS" : "FAIL";
+            string csvPath = Path.Combine(csvDir, CurrentProductModel ?? "鏈煡浜у搧", time.ToString("yyyyMMdd"), status, $"{this.tsSockets[index].Barcode}-{time.ToString("HHmmss")}.csv");
+            this.tsSockets[index].WriteToCSV(csvPath);
+        }
+
+        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;
+            string model = CurrentProductModel;
+
+            List<string> sqls = new List<string>();
+            foreach (var data in socket.Datasource)
+            {
+                sqls.Add($@"INSERT INTO serialData (sn,model,station,step,position,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
+('{snr}','{model}','','{data.Name}','{index}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
+            }
+            sqliteHelper.ExecuteBatchSql(sqls);
+
+            var ssql = $@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES 
+('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')";
+            sqliteHelper.ExecuteSql(ssql);
+        }
+
+        private void HandleUIMessage(int eventCode, int MethodCode, string strData, object xData)
+        {
+            if (eventCode == 10035)
+            {
+                string[] arr_10035 = strData.Split(';');
+
+                int[][] points = new int[arr_10035.Length - 1][];
+
+                for (int i = 1; i < arr_10035.Length; i++)
+                {
+                    string[] strs = arr_10035[i].Split(',');
+                    points[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
+                }
+                this.tsSockets[MethodCode].DrawScreenPoints(int.Parse(arr_10035[0]), points);
+                return;
+
+            }
+            else if (eventCode == 100350)
+            {
+                string[] arr_100350 = strData.Split(';');
+
+                int[][] points_0 = new int[arr_100350.Length - 1][];
+
+                for (int i = 1; i < arr_100350.Length; i++)
+                {
+                    if (string.IsNullOrEmpty(arr_100350[i]))
+                    {
+                        continue;
+                    }
+                    string[] strs = arr_100350[i].Split(',');
+                    points_0[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
+                }
+                this.tsSockets[MethodCode].DrawNewScreenPoints(int.Parse(arr_100350[0]), points_0);
+                return;
+            }
+            else if (eventCode == 10036)
+            {
+                this.tsSockets[MethodCode].ClearScreenPoint(int.Parse(strData));
+                return;
+            }
+            else if (eventCode == 10036)
+            {
+                this.tsSockets[MethodCode].ClearScreenPoint(int.Parse(strData));
+                return;
+            }
+            if (MethodCode == 0)
+            {
+                /// 璁剧疆鍙ユ焺
+                testExecutionWrapper?.SetContext((SequenceContext)xData);
+                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];
+                tsSockets[ovenIndex].ElapseTime = consumeTime;
+                return;
+            }
+            else if (MethodCode == 4)
+            {
+                /// 淇敼宸ヤ綅搴曢儴淇℃伅鏍�
+                string[] datas_10014 = strData.Split(';');
+                int ovenIndex = int.Parse(datas_10014[0]);
+                string statusBar = datas_10014[1];
+                this.tsSockets[ovenIndex].CurrentStep = statusBar;
+                return;
+            }
+            else 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];
+                    UpdatePositionStatus(ovenIndex, status_10015);
+                });
+                return;
+            }
+            else if (MethodCode == 9)
+            {
+                if (string.Equals(strData, "stop", StringComparison.OrdinalIgnoreCase))
+                {
+                    IsTesting = false;
+                }
+                return;
+            }
+            else if (MethodCode == 11)
+            {
+                // 娓呯┖娴嬭瘯鏁版嵁
+                string[] datas_10015 = strData.Split(';');
+                int ovenIndex = int.Parse(datas_10015[0]);
+                this.tsSockets[ovenIndex].IniTestData();
+                return;
+            }
+            else if (MethodCode == 18)
+            {
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                string filePath = datas[2];
+
+                if (ParamSetting.CustomerCode == "SOUND")
+                {
+                    this.tsSockets[ovenIndex].WriteToExcel(filePath);
+                    Dispatcher.Invoke(() =>
+                    {
+                        SavePositionDB(ovenIndex, tsSockets[ovenIndex].Status);
+                    });
+                    return;
+                }
+                try
+                {
+                    SavePositionCSV(ovenIndex, filePath);
+                    Dispatcher.Invoke(() =>
+                    {
+                        var sss = this.tsSockets[ovenIndex].Status;
+                        SavePositionDB(ovenIndex, sss);
+                    });
+                }
+                catch (Exception ex)
+                {
+                    log.Warn("鍐機SV/DB鏁版嵁澶辫触.", ex);
+                    SaveTemplateCSV(ovenIndex);
+                }
+                return;
+            }
+            else if (MethodCode == 9000)
+            {
+                //鏇存柊鍨嬪彿
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                CurrentProductModel = datas[2];
+                return;
+            }
+            else if (MethodCode == 9001)
+            {
+                //鏇存柊鏉$爜
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                SetPositionBarcode(ovenIndex, datas[2]);
+                return;
+            }
+            else if (MethodCode == 9002)
+            {
+                //鏄剧ず娴嬭瘯杩涘害
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                int ProcessVal = Convert.ToInt32(datas[2]);
+                this.tsSockets[ovenIndex].SetTestProcess(ProcessVal);
+                return;
+            }
+            else if (MethodCode == 9003)
+            {
+                //寮�濮嬭鏃�
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                tsSockets[ovenIndex].ElapseTime = "Start Timing";
+                return;
+            }
+            else if (MethodCode == 9004)
+            {
+                //缁撴潫璁℃椂
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                tsSockets[ovenIndex].ElapseTime = "Stop Timing";
+                return;
+            }
+            else if (MethodCode == 9005)
+            {
+                //鎵嬪姩璁剧疆鑰楁椂
+                string[] datas = strData.Split(';');
+                int ovenIndex = int.Parse(datas[0]);
+                int cellIndex = int.Parse(datas[1]);
+                tsSockets[ovenIndex].ElapseTime = datas[2];
+                return;
+            }
+        }
+
+        private void SwitchSequenceByModel(int index, string model, string snr)
+        {
+            Dispatcher.Invoke(() =>
+            {
+                var target = Products.FirstOrDefault(e => e.Name == model);
+
+                ShowMask(() =>
+                {
+                    bool stoped = StopSequence();
+                    //if (stoped)
+                    //{
+                    //    IsTesting = false;
+                    //}
+                }, null, null, "鎹㈠瀷涓紝璇风◢鍚�...");
+
+                if (target == null)
+                {
+                    MsgBoxHelper2.Warn($"璇峰厛鍦ㄤ骇鍝佺鐞嗛〉闈㈤厤缃瀷鍙� [{model}] 鐨勪骇鍝佷俊鎭紒");
+                    return;
+                }
+
+                switchAction = () =>
+                {
+                    switchAction = null;
+                    log?.Info($"灏濊瘯鑷姩鎹㈠瀷: {switchAction}");
+                    if (canSwitchModel)
+                    {
+                        Dispatcher.Invoke(() =>
+                        {
+                            try
+                            {
+                                log?.Info("寮�濮嬭嚜鍔ㄦ崲鍨�");
+                                SelectedProduct = target;
+                                testExecutionWrapper?.SetStationGlobalValue($"CacheSNR[{index}]", 1, snr);
+                                testExecutionWrapper?.CommitToDisk(false);
+                                StartClick();
+                            }
+                            catch (Exception ex)
+                            {
+                                log?.Error("鑷姩鎹㈠瀷澶辫触", ex);
+                            }
+                        });
+                    }
+                };
+            });
+        }
+
+        private void ShowAlarm(AlarmText alarm)
+        {
+            AlarmShowHelper.ShowAlarm(alarm);
+            mSMQHelper.Send("Alarm", "PC", $"ATE娴嬭瘯 {alarm.AlarmInfo}", 2);
+        }
+
+        private void UpdateTestCounter()
+        {
+            double PassNum = 0;
+            double FailNum = 0;
+            foreach (SingleControl socket in this.tsSockets)
+            {
+                PassNum += socket.PassNum;
+                FailNum += socket.FailNum;
+            }
+            this.DisplayCount(PassNum, FailNum);
+        }
+
+        private void SetTestSeqFile(ProductData product)
+        {
+            if (product == null)
+            {
+                testSeqFile = null;
+                return;
+            }
+            string name = product.Name;
+            List<HMI.Core.Entity.ParameterData> parameters = ProductManager.GetParametersByProductName(name);
+            testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
+            if (AutoExecuteSeq)
+            {
+                StartSequence();
+            }
+        }
+
+        private void ClearNum()
+        {
+            if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), LangUtil.Get("Ts.MakeSureClearNum")) == MessageBoxResult.OK)
+            {
+                PassAmount = 0;
+                FailAmount = 0;
+                //this.OpcHandle.DoFctWriteSingle("Count_Clear", "1", out string ErrMsg);
+                foreach (SingleControl socket in tsSockets)
+                {
+                    socket.ResetCounter();
+                }
+                DisplayCount(PassAmount, FailAmount);
+            }
+        }
+
+        public override void OnClose(object sender, CancelEventArgs e)
+        {
+            try
+            {
+                StopSequence();
+                base.OnClose(sender, e);
+            }
+            catch (Exception ex)
+            {
+                log.Error("OnClose Error.", ex);
+            }
+        }
+
+        public override void DoClose(object sender, EventArgs e)
+        {
+            testExecutionWrapper.Dispose();
+            base.DoClose(sender, e);
+        }
+
+        /// <summary>
+        /// 閲婃斁鎵�鏈夌殑搴忓垪鏂囦欢
+        /// </summary>
+        private bool ReleaseSequenceFile()
+        {
+            try
+            {
+                lock (this)
+                {
+                    //execution.Abort();
+                    int count = 10;
+                    while (count > 0)
+                    {
+                        try
+                        {
+                            return testExecutionWrapper.ReleaseSeqFile();
+                        }
+                        catch (Exception ex)
+                        {
+                            log.Warn($"ReleaseSequenceFile In {count} Times Fail.", ex);
+                            count--;
+                            System.Threading.Thread.Sleep(1000);
+                        }
+                    }
+                    log.Warn($"ReleaseSequenceFile Failed.");
+                    return false;
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Warn("ReleaseSequenceFile Error.", ex);
+                return false;
+            }
+        }
+
+        private void PluginControl_SizeChanged(object sender, SizeChangedEventArgs e)
+        {
+
+        }
+
+        private void CbFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            try
+            {
+                if (e.AddedItems != null && e.AddedItems.Count > 0)
+                {
+                    var fontSize = (double)e.AddedItems[0];
+                    this.Resources["tableFontSize"] = fontSize;
+                    IniFileHelper.WriteIniData("Config", "TableFontSize", fontSize.ToString(), CountIniPath);
+                }
+            }
+            catch
+            {
+            }
+        }
+
+        private void Label_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            //workOrderEditor.Focus();
+            //workOrderEditor.IsEditing = true;
+            if (RequirePassword() == true)
+            {
+                var win = new WorkOrderWin
+                {
+                    WorkOrder = CurrentWorkorder,
+                    Owner = Window.GetWindow(this)
+                };
+                if (win.ShowDialog() == true)
+                {
+                    CurrentWorkorder = win.WorkOrder;
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.1