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