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.JarUI/JarUI.xaml.cs |  635 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 635 insertions(+), 0 deletions(-)

diff --git a/Plugin.JarUI/JarUI.xaml.cs b/Plugin.JarUI/JarUI.xaml.cs
new file mode 100644
index 0000000..2279e7a
--- /dev/null
+++ b/Plugin.JarUI/JarUI.xaml.cs
@@ -0,0 +1,635 @@
+锘縰sing HMI.Base;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Util;
+using HMI.UI;
+using HMI.UI.Entity;
+using HMI.UI.Util;
+using NationalInstruments.TestStand.Interop.API;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using Panuon.WPF.UI;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.IO.Ports;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.JarUI
+{
+    /// <summary>
+    /// UserControl1.xaml 鐨勪氦浜掗�昏緫
+    /// </summary>
+    public partial class JarUI : PluginControl
+    {
+        public JarUI()
+        {
+            DataContext = this;
+            InitializeComponent();
+            InitTsEngine();
+            InitProducts();
+        }
+
+        public override void InitFinish()
+        {
+            string iniFile = Path.Combine(BaseFolder, "Config.ini");
+            if (!File.Exists(iniFile))
+            {
+                File.Create(iniFile);
+            }
+            this.iniFile = iniFile;
+        }
+
+        #region Properties
+
+        #region TestStand鐩稿叧
+        private AxApplicationMgr AxApplicationMgr;
+        /// <summary>
+        /// TS 寮曟搸
+        /// </summary>
+        private Engine engine = null;
+
+        private string testSeqFile = string.Empty;
+        /// <summary>
+        /// 娴嬭瘯搴忓垪
+        /// </summary>
+        private SequenceFile testSeq = null;
+
+        /// <summary>
+        /// 娴嬭瘯妯″瀷搴忓垪
+        /// </summary>
+        private SequenceFile modeSeq = null;
+        public SequenceContext SequenceContext { get; private set; } = null;
+        private Execution execution = null;
+        #endregion
+
+        private bool _isRunning;
+        public bool IsRunning
+        {
+            get => _isRunning;
+            set
+            {
+                Dispatcher.Invoke(() =>
+                {
+                    startBtn.IsEnabled = !value;
+                    stopBtn.IsEnabled = value;
+                    CbProduct.IsEnabled = !value;
+                });
+                Set(ref _isRunning, value);
+            }
+        }
+
+        private ObservableCollection<ProductData> _products;
+
+        public ObservableCollection<ProductData> Products
+        {
+            get { return _products; }
+            set { Set(ref _products, value); }
+        }
+
+        private ProductData _selectedProduct;
+
+        public ProductData SelectedProduct
+        {
+            get { return _selectedProduct; }
+            set
+            {
+                Set(ref _selectedProduct, value);
+                SetTestSeqFile(value);
+            }
+        }
+
+        private bool _enableMes;
+        public bool EnableMes
+        {
+            get => _enableMes;
+            set
+            {
+                if (WriteConfig("EnableMes", value))
+                {
+                    Set(ref _enableMes, value);
+                }
+            }
+        }
+
+
+        private bool isLoadOk = false;
+        private string iniFile;
+        private JarCell selectedCell;
+
+        private JarCell[] tsSockets;
+        private Dictionary<string, JarCell> socketMap = new Dictionary<string, JarCell>();
+        private SerialPort serialPort;
+        #endregion
+
+        private void RefershUI()
+        {
+            tsSockets = new JarCell[18];
+            for (int i = 0; i < 18; i++)
+            {
+                var cell = new JarCell(i);
+                cell.GotFocus += Cell_GotFocus;
+                uGrid.Children.Add(cell);
+                tsSockets[i] = cell;
+                socketMap.Add(cell.Name, cell);
+            }
+        }
+
+        private void Cell_GotFocus(object sender, RoutedEventArgs e)
+        {
+            selectedCell = sender as JarCell;
+        }
+
+        private void SetTestSeqFile(ProductData product)
+        {
+            if (product == null)
+            {
+                testSeqFile = null;
+                return;
+            }
+            string name = product.Name;
+            List<ParameterData> parameters = ProductManager.GetParametersByProductName(name);
+            testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
+            StartSequence();
+        }
+
+        private void InitProducts()
+        {
+            Products = ProductManager.GetProducts<ObservableCollection<ProductData>>();
+            if (Products != null && Products.Count > 0)
+            {
+                List<ParameterData> parameters =
+                    ParameterManager.GetCommonParameter<List<ParameterData>>();
+                string tmpNum = parameters?.FirstOrDefault(p => p.Name == "SocketNum")?.Value?.ToString();
+                string lastModel = engine?.Globals.GetValString("StationState.ProductModel", 1);
+
+                if (!string.IsNullOrEmpty(lastModel))
+                {
+                    var product = Products.FirstOrDefault(p => p.Name == lastModel);
+                    if (product != null)
+                    {
+                        SelectedProduct = product;
+                        RefershUI();
+                        return;
+                    }
+                }
+                SelectedProduct = Products[0];
+                RefershUI();
+            }
+        }
+
+        private bool WriteConfig(string name, bool value)
+        {
+            //IniFileHelper.WriteIniData("Config", name, value.ToString(), CountIniPath);
+            try
+            {
+                if (ParameterManager.UpdateCommonParameter(name, value, out string errMsg))
+                {
+                    SequenceContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value);
+                    return true;
+                }
+                else
+                {
+                    throw new Exception(errMsg);
+                }
+            }
+            catch (Exception ex)
+            {
+                MsgBoxHelper2.Error(ex.Message);
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 璇诲彇閰嶇疆鏂囦欢閲岀殑鍑犱釜灞炴��
+        /// </summary>
+        /// <param name="pass"></param>
+        /// <param name="fail"></param>
+        private void ReadConfig()
+        {
+            ParameterData value;
+            try
+            {
+                value = ParameterManager.GetCommonParameterByName("EnableMes");
+                _enableMes = bool.Parse(value.Value);
+                Set("EnableMes");
+            }
+            catch
+            {
+                _enableMes = false;
+                Set("EnableMes");
+            }
+
+            //try
+            //{
+            //    value = ParameterManager.GetCommonParameterByName("EnableNGPause");
+            //    _enableNGPause = bool.Parse(value.Value);
+            //    Set("EnableNGPause");
+            //}
+            //catch
+            //{
+            //    _enableNGPause = false;
+            //    Set("EnableNGPause");
+            //}
+
+            //try
+            //{
+            //    value = ParameterManager.GetCommonParameterByName("EnableCanLog");
+            //    _enableCanLog = bool.Parse(value.Value);
+            //    Set("EnableCanLog");
+            //}
+            //catch
+            //{
+            //    _enableCanLog = false;
+            //    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);
+            //}
+            //catch
+            //{
+            //    EnableSimpleMode = false;
+            //}
+
+            //try
+            //{
+            //    value = ParameterManager.GetCommonParameterByName("UI_ShowInfoDock");
+            //    UI_ShowInfoDock = bool.Parse(value.Value);
+            //}
+            //catch
+            //{
+            //    UI_ShowInfoDock = false;
+            //}
+
+            //try
+            //{
+
+            //    value = ParameterManager.GetCommonParameterByName("TestReportFolder");
+            //    csvDir = value.Value;
+            //    if (!Directory.Exists(csvDir))
+            //    {
+            //        Directory.CreateDirectory(csvDir);
+            //    }
+            //}
+            //catch
+            //{
+            //    csvDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestReport");
+            //}
+        }
+
+        #region 鎵爜鏋浉鍏�
+        /// <summary>
+        /// 璁剧疆鎵爜鏋�
+        /// </summary>
+        private void InitScanner()
+        {
+            if (serialPort != null) return;
+            ScannerConfig common = ScannerConfig.ReadFromIni(iniFile, "Config");
+            // 閰嶇疆涓插彛
+            serialPort = new SerialPort
+            {
+                PortName = common.PortName,
+                BaudRate = common.BaudRate,
+                Parity = Parity.None,
+                DataBits = common.DataBits,
+                StopBits = common.StopBits,
+                Handshake = Handshake.None,
+                DtrEnable = common.DtrEnable,
+                RtsEnable = common.RtsEnable
+                //ReadTimeout = 500,
+                //WriteTimeout = 500,
+                //ReciveBufferSize=4096
+            };
+
+            try
+            {
+                // 鎵撳紑涓插彛
+                serialPort.Open();
+                // 娉ㄥ唽鎺ユ敹鏁版嵁浜嬩欢
+                serialPort.DataReceived += SerialPort_DataReceived;
+            }
+            catch (Exception ex)
+            {
+                log.Error("Init Scan Gun Failed.", ex);
+                Dispatcher.Invoke(() =>
+                {
+                    MsgBoxHelper.Error(this, $"{this.lang("Tr.InitGunFailed")}: {ex.StackTrace}");
+                });
+            }
+        }
+        private string ReadDataFrom(SerialPort sp)
+        {
+            string barcode = "";
+            while (sp.BytesToRead > 0)
+            {
+                byte[] buffer = new byte[sp.BytesToRead];
+                sp.Read(buffer, 0, buffer.Length);
+                barcode += System.Text.Encoding.UTF8.GetString(buffer);
+                System.Threading.Thread.Sleep(50);
+            }
+            return barcode;
+        }
+
+        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
+        {
+            try
+            {
+                SerialPort sp = (SerialPort)sender;
+                string barcode = ReadDataFrom(sp);
+                if (selectedCell != null)
+                {
+                    Dispatcher.Invoke(() =>
+                    {
+                        selectedCell.SetSn(barcode);
+                    });
+                    SequenceContext.StationGlobals.SetValString($"StationState.SN[{selectedCell.Index}]", 1, barcode);
+                    SequenceContext.StationGlobals.SetValBoolean($"StationState.Socket_{selectedCell.Index}", 1, true);
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error("Get Scan Gun Data Failed.", ex);
+                MessageBox.Show($"{this.lang("Tr.GetGunData")}: {ex.StackTrace}");
+            }
+        }
+        #endregion
+
+        private void Button_Click(object sender, RoutedEventArgs e)
+        {
+            Button btn = sender as Button;
+            switch (btn?.Name)
+            {
+                case "startBtn":
+                    StartBtnClick();
+                    break;
+                case "stopBtn":
+                    StopBtnClick();
+                    break;
+                case "scannerSettingBtn":
+                    ScannerSetting ss = new ScannerSetting
+                    {
+                        Owner = Window.GetWindow(this)
+                    };
+                    if (ss.Open(true, "Config", iniFile) == true)
+                    {
+                        serialPort?.Close();
+                        InitScanner();
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        private void StartBtnClick()
+        {
+            new MaskWindow(Window.GetWindow(this),
+                (win) =>
+                {
+                    try
+                    {
+                        StartSequence();
+                    }
+                    finally
+                    {
+                        win.Dispatcher.Invoke(() =>
+                        {
+                            win.Close();
+                        });
+                    }
+                }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
+        }
+
+        public void StopBtnClick()
+        {
+            new MaskWindow((WindowX)Window.GetWindow(this),
+                    (win) =>
+                    {
+                        try
+                        {
+                            bool stoped = StopSequence();
+                            if (stoped)
+                            {
+                                IsRunning = false;
+                            }
+                        }
+                        finally
+                        {
+                            Dispatcher.Invoke(() =>
+                            {
+                                win.Close();
+                            });
+                        }
+                    }
+                    ).Info(LangUtil.Get("App.SequenceIsStopping"));
+        }
+
+        private bool StopSequence()
+        {
+            try
+            {
+                SequenceContext?.StationGlobals.SetValBoolean("StationState.StopTest", 1, true);
+                log.Info($"Stop Result: {SequenceContext?.StationGlobals.GetValBoolean("StationState.StopTest", 1)}");
+                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;
+            }
+        }
+
+        private void PluginControl_Loaded(object sender, RoutedEventArgs e)
+        {
+            new MaskWindow((WindowX)Window.GetWindow(this),
+                (win) =>
+                {
+                    try
+                    {
+                        InitScanner();
+                        isLoadOk = true;
+                        StartSequence();
+                    }
+                    catch (Exception ex)
+                    {
+                        log.Error("TsExecution Loaded Failed.", ex);
+                        Dispatcher.Invoke(() =>
+                        {
+                            MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
+                        });
+                    }
+                    Dispatcher.Invoke(() =>
+                    {
+                        if (isLoadOk) Loaded -= PluginControl_Loaded;
+                    });
+                }
+                ).Info(LangUtil.Get("App.SequenceIsStarting"));
+        }
+
+        #region teststand鍒濆鍖栫浉鍏�
+        /// <summary>
+        /// 鍚姩娴嬭瘯搴忓垪
+        /// </summary>
+        private void StartSequence()
+        {
+            try
+            {
+                if (!isLoadOk) return;
+                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.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+                IsRunning = true;
+            }
+            catch (Exception ex)
+            {
+                Dispatcher.Invoke(() =>
+                {
+                    log.Error("Start Sequence Failed.", ex);
+                    MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.StartSequenceFail")}: {ex.Message}");
+                });
+            }
+        }
+
+        /// <summary>
+        /// 鍒濆鍖朤estStand寮曟搸
+        /// </summary>
+        private void InitTsEngine()
+        {
+            try
+            {
+                AxApplicationMgr = new AxApplicationMgr();
+                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();
+
+                this.engine = this.AxApplicationMgr.GetEngine();
+                this.engine.PersistBreakpoints = false;
+                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");
+            }
+            catch (Exception ex)
+            {
+                log.Error("InitTsEngine Failed.", ex);
+                throw ex;
+            }
+        }
+
+        /// <summary>
+        /// 閫�鍑哄簲鐢�
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void AxApplicationMgr_ExitApplication(object sender, EventArgs e)
+        {
+            //Environment.ExitCode = this.AxApplicationMgr.ExitCode;
+            //this.Close();
+        }
+
+        /// <summary>
+        /// 杩涚▼缁撴潫浜嬩欢
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
+        {
+            try
+            {
+                if (this.testSeq == null)
+                    return;
+                this.engine.ReleaseSequenceFileEx(this.testSeq, 0);
+                this.engine.ReleaseSequenceFileEx(this.modeSeq, 0);
+                this.engine.UnloadAllModules();
+                this.testSeq = null;
+                this.modeSeq = null;
+            }
+            catch (Exception ex)
+            {
+                log.Error("ReleaseSequenceFileEx Failed.", ex);
+                MsgBoxHelper.Error(Window.GetWindow(this), $"{LangUtil.Get("Ts.ReleaseSequenceFileFail")}: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// TestStand鐢ㄦ埛浜や簰浜嬩欢
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+        {
+            try
+            {
+                int EventCase = Convert.ToInt32(e.uiMsg.Event);
+                int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
+                string strData = e.uiMsg.StringData;
+
+                try
+                {
+                    log.Info($"Event: {EventCase}, NumericData: {MethodCode}, StringData: {strData}");
+                }
+                catch
+                {
+
+                }
+
+                if (EventCase != 10015) return;
+                switch (MethodCode)
+                {
+                    case 0:
+                        /// 璁剧疆鍙ユ焺
+                        this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
+                        break;
+                    case 1:
+                        var arr1 = strData.Split(';');
+                        int index1 = int.Parse(arr1[0]);
+                        this.tsSockets[index1].SetStatus(arr1[1]);
+                        break;
+                    case 2:
+                        var arr2 = strData.Split(';');
+                        int index2 = int.Parse(arr2[0]);
+                        this.tsSockets[index2].SetInfo(arr2[1]);
+                        break;
+                    case 8:
+                        IsRunning = false;
+                        break;
+                    default:
+                        break;
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Warn("Ts Event Error.", ex);
+            }
+        }
+        #endregion
+
+
+    }
+}

--
Gitblit v1.9.1