alielie
2025-10-13 e3868d4d61ded0e76fc8fe3fdacdd9e6d9113cf1
Plugin.TsExecution/SingleControl.xaml.cs
@@ -1,12 +1,17 @@
using HMI.Core.Util;
using HMI.Core.Manager;
using HMI.Core.Util;
using HMI.Util;
using NationalInstruments.TestStand.Interop.API;
using Plugin.TsExecution.Entity;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Runtime.CompilerServices;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Plugin.TsExecution
{
@@ -35,7 +40,7 @@
        #endregion
        private bool isLoadOK = false;
        private int index;
        private string counterFilePath;
        private string CountIniPath;
        private string status = "Ready";
@@ -45,8 +50,8 @@
            set { Set(ref status, value); }
        }
        private int totalNum;
        public int TotalNum
        private double totalNum;
        public double TotalNum
        {
            get => totalNum;
            private set
@@ -89,18 +94,18 @@
            get => this.lang("Ts.TestInfo", Barcode, ElapseTime);
        }
        private string currentStep;
        public string CurrentStep
        {
            get { return currentStep; }
            set { Set(ref currentStep, value); }
        }
        private string barcode = string.Empty;
        public string Barcode
        {
            get { return barcode; }
            set { Set(ref barcode, value); }
        }
        private string model = string.Empty;
        public string Model
        {
            get { return model; }
            set { Set(ref model, value); }
        }
        private string elapseTime = "00:00:00";
@@ -112,7 +117,8 @@
                if (value == "Start Timing")
                {
                    this.refreshTimer.Enabled = true;
                    TimeNow = DateTime.Now;
                    TestStartTime = DateTime.Now;
                    StepStartTime = DateTime.Now;
                }
                else
                {
@@ -126,39 +132,148 @@
            }
        }
        private DateTime TimeNow = new DateTime();
        private ObservableCollection<TestStep> _datasource = new ObservableCollection<TestStep>();
        public ObservableCollection<TestStep> Datasource
        {
            get => _datasource;
            set
            {
                Set(ref _datasource, value);
            }
        }
        private DateTime TestStartTime = new DateTime();
        private DateTime StepStartTime = new DateTime();
        private TimeSpan TimeCount = new TimeSpan();
        private Timer refreshTimer;
        private System.Timers.Timer refreshTimer;
        private DataTable dt;
        public SingleControl(int Index, int passNum, int failNum)
        private string currentStep = "等待扫码";
        public string CurrentStep
        {
            get => currentStep;
            set
            {
                Set(ref currentStep, value);
            }
        }
        private int _probeCount;
        public int ProbeCount
        {
            get => _probeCount;
            set
            {
                Set(ref _probeCount, value);
            }
        }
        /// <summary>
        /// 进度值
        /// </summary>
        private int _processValue;
        public int ProcessValue
        {
            get => _processValue;
            set
            {
                Set(ref _processValue, value);
            }
        }
        public string ProcessValueLabel
        {
            get
            {
                if (ProcessValue > 0) return $"{ProcessValue}%";
                return "";
            }
            set
            {
            }
        }
        public void SetSimpleUI(bool flag)
        {
            if (flag)
            {
                simplePanel.Visibility = Visibility.Visible;
                detailPanel.Visibility = Visibility.Collapsed;
            }
            else
            {
                simplePanel.Visibility = Visibility.Collapsed;
                detailPanel.Visibility = Visibility.Visible;
            }
        }
        public int ProbeWarn { get; private set; }
        private bool isAutoMode;
        public bool IsAutoMode
        {
            get => isAutoMode;
            set
            {
                Set(ref isAutoMode, value);
            }
        }
        public SingleControl(int Index, string CountIniPath, int probeWarn)
        {
            this.CountIniPath = CountIniPath;
            DataContext = this;
            this.index = Index;
            PassNum = passNum;
            FailNum = failNum;
            dt = new DataTable();
            dt.Columns.Add(new DataColumn("Name", typeof(string)));
            dt.Columns.Add(new DataColumn("Unit", typeof(string)));
            dt.Columns.Add(new DataColumn("Value", typeof(string)));
            dt.Columns.Add(new DataColumn("LimitDown", typeof(string)));
            dt.Columns.Add(new DataColumn("LimitUp", typeof(string)));
            dt.Columns.Add(new DataColumn("Result", typeof(string)));
            ProbeWarn = probeWarn;
            refreshTimer = new Timer()
            refreshTimer = new System.Timers.Timer()
            {
                Interval = 1000
                Interval = 100
            };
            refreshTimer.Elapsed += RefreshTimer_Elapsed;
            ReadProbeCount();
            ReadCounter();
            InitializeComponent();
            try
            {
                var value = ParameterManager.GetCommonParameterByName("AutoTestMode");
                IsAutoMode = bool.Parse(value.Value);
            }
            catch
            {
                IsAutoMode = true;
            }
            //if (ProbeWarn > 0)
            //{
            //    probeWarnPanel.Visibility = Visibility.Visible;
            //}
            //else
            //{
            //    probeWarnPanel.Visibility = Visibility.Collapsed;
            //}
        }
        private void RefreshTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            TimeCount = DateTime.Now - TimeNow;
            //Dispatcher.Invoke(() =>
            //{
            //    var data = PluginLoader.Instance.Plugins.FirstOrDefault(p => p.Name == "TS");
            //    if (data?.Content is TsExecution ts)
            //    {
            //        if (Status == "Testing")
            //        {
            //            ts.UpdatePositionStatus(index, "Passed");
            //        }
            //        else
            //        {
            //            ts.UpdatePositionStatus(index, "Testing");
            //        }
            //    }
            //});
            //AddTestData("1", "1", "1", "1", "1", "1", "1");
            TimeCount = DateTime.Now - TestStartTime;
            elapseTime = string.Format("{0:00}:{1:00}:{2:00}", TimeCount.Hours, TimeCount.Minutes, TimeCount.Seconds);
            Set("ElapseTime");
            Set("TestInfo");
@@ -172,23 +287,34 @@
        /// <summary>
        /// 获取TS的每步测试的数据添加到表格
        /// 项目名称,测试参数,测试值,上限,下限,单位,结果
        /// </summary>
        /// <param name="TS_Data"></param>
        public void AddTestData(string step_name, string unit, string TestValue, string LowLimit, string HightLimit, string Status)
        public void AddTestData(string name, string step_name, string value, string HightLimit, string LowLimit, string unit, string Status)
        {
            try
            {
                var dr = dt.NewRow();
                dr[0] = step_name;
                dr[1] = unit;
                dr[2] = TestValue;
                dr[3] = LowLimit;
                dr[4] = HightLimit;
                dr[5] = Status;
                dt.Rows.Add(dr);
                table.ItemsSource = dt.DefaultView;
                var data = new TestStep
                {
                    Name = name,
                    Step = step_name,
                    Value = value,
                    LimitUp = HightLimit,
                    LimitDown = LowLimit,
                    Unit = unit,
                    Result = Status
                };
                table.Dispatcher.Invoke(new Action(() =>
                {
                    var now = DateTime.Now;
                    var span = now - StepStartTime;
                    StepStartTime = now;
                    data.ConsumeTime = $"{(span.TotalMilliseconds / 1000d).ToString("F2")}s";
                    Datasource.Add(data);
                    table.ScrollIntoView(data);
                }));
            }
            catch
            catch (Exception ex)
            {
                //屏蔽错误
            }
@@ -196,7 +322,6 @@
        public void UpdateStatus(string status)
        {
            Status = status;
            if (status == "Passed")
            {
                UpdateTestCounter(true);
@@ -205,12 +330,16 @@
            {
                UpdateTestCounter(false);
            }
            else if (Status != "Testing" && status == "Testing")
            {
                UpdateProbeCount(ProbeCount + 1);
            }
            Status = status;
        }
        public void IniTestData()
        {
            dt.Clear();
            table.ItemsSource = dt.DefaultView;
            Datasource.Clear();
        }
        /// <summary>
@@ -219,9 +348,8 @@
        /// <param name="ProcessVal"></param>
        public void SetTestProcess(int ProcessVal)
        {
            //this.TestProcess.Value = ProcessVal;
            //this.TestProcessLabel.Text = ProcessVal.ToString() + "%";
            //this.TestProcessLabel.BackColor = Color.Transparent;
            ProcessValue = ProcessVal;
            Set("ProcessValueLabel");
        }
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
@@ -234,16 +362,20 @@
            if (result == true)
            {
                PassNum += 1;
                //Interlocked.Increment(ref passNum);
                //Set("PassNum");
            }
            else if (result == false)
            {
                FailNum += 1;
                //Interlocked.Increment(ref failNum);
                //Set("FailNum");
            }
            TotalNum = PassNum + FailNum;
            if (TotalNum != 0)
            {
                PassRate = (PassNum / TotalNum) * 100;
                PassRate = ((double)PassNum / TotalNum);
            }
            else
            {
@@ -253,16 +385,180 @@
            this.WriteCounter();
        }
        /// <summary>
        /// 从ini读取探针使用次数
        /// </summary>
        private void ReadProbeCount()
        {
            try
            {
                var num = IniFileHelper.ReadIniData("Socket" + this.index.ToString(), "ProbeCount", "0", this.CountIniPath);
                this.ProbeCount = int.Parse(num);
            }
            catch (Exception ex)
            {
                this.ProbeCount = 0;
            }
        }
        /// <summary>
        /// 更新探针使用次数
        /// </summary>
        /// <param name="count"></param>
        private void UpdateProbeCount(int count)
        {
            /// 写到配置文件
            IniFileHelper.WriteIniData("Socket" + this.index.ToString(), "ProbeCount", count.ToString(), this.CountIniPath);
            ProbeCount = count;
            //if (ProbeWarn <= 0) probeCountAlarm.Visibility = Visibility.Collapsed;
            //else if (count >= ProbeWarn) probeCountAlarm.Visibility = Visibility.Visible;
            //else probeCountAlarm.Visibility = Visibility.Collapsed;
        }
        private void WriteCounter()
        {
            IniFileHelper.WriteIniData("Socket" + this.index.ToString(), "Pass",
                this.passNum.ToString(), this.CountIniPath);
            IniFileHelper.WriteIniData("Socket" + this.index.ToString(), "Fail", this.failNum.ToString(),
                this.CountIniPath);
        }
        private void ReadCounter()
        {
            try
            {
                this.PassNum = Convert.ToInt32(IniFileHelper.ReadIniData("Socket" + this.index.ToString(), "Pass", "", CountIniPath));
                this.FailNum = Convert.ToInt32(IniFileHelper.ReadIniData("Socket" + this.index.ToString(), "Fail", "", CountIniPath));
            }
            catch (Exception ex)
            {
                //do nothing
            }
        }
        public void ResetCounter()
        {
            PassNum = 0;
            FailNum = 0;
            this.PassNum = 0;
            this.FailNum = 0;
            this.UpdateTestCounter(null);
        }
        public void WriteToCSV(string path)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                try
                {
                    FileInfo fi = new FileInfo(path);
                    if (!fi.Directory.Exists)
                    {
                        fi.Directory.Create();  //文件不存在,创建文件
                    }
                    using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
                    using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
                    {
                        string title = "项目名称,测试参数,测试值,上限,下限,单位,结果";
                        sw.WriteLine(title);
                        if (Datasource != null && Datasource.Count > 0)
                        {
                            foreach (var data in Datasource)
                            {
                                sw.WriteLine($"{data.Name},{data.Step},{data.Value},{data.LimitUp},{data.LimitDown},{data.Unit},{data.Result}");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    TsExecution.logger.Error("Write CSV File Failed.", ex);
                }
            }));
        }
        public void ShowPausePanel()
        {
            pausePanel.Visibility = Visibility.Visible;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;
            switch (btn.Name)
            {
                case "clear":
                    UpdateProbeCount(0);
                    break;
                case "cancelPauseBtn":
                    SequenceFileContext?.StationGlobals.SetValBoolean($"StationState.IsContinue_{index}", 1, false);
                    pausePanel.Visibility = Visibility.Collapsed;
                    break;
                case "continuePauseBtn":
                    SequenceFileContext?.StationGlobals.SetValBoolean($"StationState.IsContinue_{index}", 1, true);
                    pausePanel.Visibility = Visibility.Collapsed;
                    break;
                case "scannerSetting":
                    //ScannerSetting setting = new ScannerSetting()
                    //{
                    //    Owner = Window.GetWindow(this)
                    //};
                    //setting.Open(true, $"Socket{index}", CountIniPath);
                    ShowScannerPanel();
                    break;
                case "scannerOkBtn":
                    SendSnr2Ts();
                    break;
                default:
                    break;
            }
        }
        public void ShowScannerPanel()
        {
            //scannerPanel.Visibility = Visibility.Visible;
        }
        private void SendSnr2Ts()
        {
            //try
            //{
            //    string snr = TbManualSnr.Text;
            //    SequenceFileContext?.StationGlobals.SetValString($"StationState.SN[{index}]", 1, snr);
            //    scannerPanel.Visibility = Visibility.Collapsed;
            //    TbManualSnr.Text = string.Empty;
            //}
            //catch (Exception ex)
            //{
            //    ToastHelper.Error(ex.Message);
            //}
        }
        private void pausePanel_Loaded(object sender, RoutedEventArgs e)
        {
            if (sender == pausePanel)
            {
                var can = pausePanel;
                var modal = visualModal;
                Canvas.SetLeft(modal, (pausePanel.ActualWidth - visualModal.ActualWidth) / 2);
                Canvas.SetTop(modal, (pausePanel.ActualHeight - visualModal.ActualHeight) / 2);
            }
            else
            {
                //var can = scannerPanel;
                //var modal = scannerVisualModal;
                //Canvas.SetLeft(modal, (scannerPanel.ActualWidth - scannerVisualModal.ActualWidth) / 2);
                //Canvas.SetTop(modal, (scannerPanel.ActualHeight - scannerVisualModal.ActualHeight) / 2);
            }
        }
        private void TextBlock_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            DependencyObject parent = VisualTreeHelper.GetParent((DependencyObject)sender);
            while (parent != null) {
                parent = VisualTreeHelper.GetParent(parent);
            }
        }
    }
}