Util.ManualDebug/ManualDebug.xaml.cs
@@ -1,14 +1,22 @@
using HMI.Core.Util;
using HMI.UI.DpUtil;
using NationalInstruments.TestStand.Interop.API;
using Plugin.TsSupport;
using SuperSocket.SocketBase.Config;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using Util.ManualDebug.Model;
namespace Util.SB
namespace Util.ManualDebug
{
    public class BtnConfig
    {
@@ -45,9 +53,27 @@
        Warn = 2,
        Error = 3
    }
    public partial class ManualDebug : UserControl
    public partial class ManualDebug : UserControl, INotifyPropertyChanged
    {
        #region ...
        public event PropertyChangedEventHandler PropertyChanged;
        protected void Set([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
        protected void Set<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
        {
            old = @new;
            if (propertyName != null)
            {
                Set(propertyName);
            }
        }
        #endregion
        public static readonly DependencyProperty OvenNameProperty = DependencyProperty.Register(
                            "OvenName",
                            typeof(string),
@@ -68,6 +94,12 @@
        public static readonly DependencyProperty CellIndexProperty = DependencyProperty.Register(
                            "CellIndex",
                            typeof(int),
                            typeof(ManualDebug),
                            new PropertyMetadata(-1));
        public static readonly DependencyProperty CellCountProperty = DependencyProperty.Register(
                            "CellCount",
                            typeof(int),
                            typeof(ManualDebug),
                            new PropertyMetadata(0));
@@ -99,6 +131,12 @@
            set { SetValue(CellIndexProperty, value); }
        }
        public int CellCount
        {
            get { return (int)GetValue(CellCountProperty); }
            set { SetValue(CellCountProperty, value); }
        }
        public ObservableCollection<TestDataItem> TestData { get; private set; } = new ObservableCollection<TestDataItem>();
        private Dictionary<string, StatusBtn> btnCache = new Dictionary<string, StatusBtn>();
@@ -111,8 +149,30 @@
        private ITestExecutionWrapper executionWrapper;
        private TcpServer tcpServer;
        public string seqPath { get; set; }
        public string modelPath { get; set; } = "C:\\Program Files\\National Instruments\\TestStand 2020\\Components\\Models\\TestStandModels\\ParallelModel.seq";
        private string tcpServerStatus;
        public string TcpServerStatus
        {
            get => tcpServerStatus;
            set
            {
                Set(ref tcpServerStatus, value);
            }
        }
        private string tcpServerInfo;
        public string TcpServerInfo
        {
            get => tcpServerInfo;
            set
            {
                Set(ref tcpServerInfo, value);
            }
        }
        public ManualDebug()
        {
@@ -125,8 +185,61 @@
            RefreshButtons(null);
        }
        public void HideCells(bool flag)
        {
            CellSelectBorder.Visibility = flag ? Visibility.Collapsed : Visibility.Visible;
        }
        private List<ManualCell> Cells = new List<ManualCell>();
        private List<StatusCell> StatusCells = new List<StatusCell>();
        public void RefreshGrid(CellConfig[] cells)
        {
            if (cells != null)
            {
                int i = 0;
                foreach (var cell in cells)
                {
                    var mCell = new ManualCell
                    {
                        Title = cell.Name,
                        Index = cell.Index
                    };
                    mCell.SelectedChanged += MCell_SelectedChanged;
                    Cells.Add(mCell);
                    CellGrid.Children.Add(mCell);
                    var sCell = new StatusCell
                    {
                        Title = cell.Name,
                        Index = cell.Index
                    };
                    StatusCells.Add(sCell);
                    CellResultGrid.Children.Add(sCell);
                    BindingOperations.SetBinding(sCell, StatusCell.StatusProperty, new Binding(nameof(ManualCell.Selected))
                    {
                        Source = mCell,
                        Mode = BindingMode.OneWay,
                        //UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                        Converter = CellStatusConverter.Instance
                    });
                }
                UniformGridHelper.RefreshGridInnerBorder(CellGrid);
                UniformGridHelper.RefreshGridInnerBorder(CellResultGrid);
            }
        }
        private void MCell_SelectedChanged(object sender, EventArgs e)
        {
            object[] arr = Cells.Select(c => (object)c.Selected).ToArray();
            SetArray($"Running.CellIndex", PropertyValueTypes.PropValType_Boolean, arr);
        }
        private void ManualDebug_Loaded(object sender, RoutedEventArgs e)
        {
            StartTcpServer();
            Task.Run(() =>
            {
                System.Threading.Thread.Sleep(500);
@@ -139,11 +252,117 @@
            });
        }
        private int GetConfigPort()
        {
            try
            {
                var customConfig = (Hashtable)ConfigurationManager.GetSection("TestResultConfig");
                if (customConfig.ContainsKey("PortStart"))
                {
                    int port = int.Parse(customConfig["PortStart"].ToString()) - 1;
                    return port;
                }
                else
                {
                    return 6659;
                }
            }
            catch (Exception ex)
            {
                AppendLog(LogLevel.Error, $"读取起始端口错误: {ex.Message} {ex.StackTrace} 使用默认端口6659");
                return 6659;
            }
        }
        /// <summary>
        /// 启动Tcp服务器
        /// </summary>
        private void StartTcpServer()
        {
            int port = GetConfigPort();
            var serverConfig = new ServerConfig()
            {
                MaxRequestLength = 1024 * 1024,
                Port = port
            };
            try
            {
                if (tcpServer == null)
                {
                    tcpServer = new TcpServer();
                    tcpServer.NewRequestReceived += TcpServer_NewRequestReceived;
                    if (!tcpServer.Setup(serverConfig))
                    {
                        ChangeTcpServerStatus("ERROR", this.lang("Tr.TcpServer.SettingFailed"));
                        return;
                    }
                    if (!tcpServer.Start())
                    {
                        ChangeTcpServerStatus("ERROR", this.lang("Tr.TcpServer.StartFailed"));
                        return;
                    }
                    ChangeTcpServerStatus("RUNNING", this.lang("Tr.TcpServer.Running"));
                    AppendLog(LogLevel.Debug, $"数据接收服务器启动,端口:{port}");
                }
                else if (tcpServer.State != SuperSocket.SocketBase.ServerState.Running)
                {
                    if (!tcpServer.Setup(serverConfig))
                    {
                        ChangeTcpServerStatus("ERROR", this.lang("Tr.TcpServer.SettingFailed"));
                        return;
                    }
                    if (!tcpServer.Start())
                    {
                        ChangeTcpServerStatus("ERROR", this.lang("Tr.TcpServer.StartFailed"));
                        return;
                    }
                    ChangeTcpServerStatus("RUNNING", this.lang("Tr.TcpServer.Running"));
                    AppendLog(LogLevel.Debug, $"数据接收服务器启动,端口:{port}");
                }
            }
            catch (Exception ex)
            {
                ChangeTcpServerStatus("ERROR", $"{ex.Message}");
                AppendLog(LogLevel.Error, $"数据接收服务器启动错误: {ex.Message} {ex.StackTrace}");
                tcpServer?.Stop();
                tcpServer = null;
            }
        }
        /// <summary>
        /// 更新Tcp服务器状态
        /// </summary>
        /// <param name="status"></param>
        /// <param name="info"></param>
        private void ChangeTcpServerStatus(string status, string info)
        {
            Dispatcher.Invoke(() =>
            {
                TcpServerStatus = status;
                TcpServerInfo = info;
            });
        }
        private void TcpServer_NewRequestReceived(TcpSession session, SuperSocket.SocketBase.Protocol.StringRequestInfo requestInfo)
        {
            string msg = requestInfo.Body;
            string[] datas_10015 = msg.Split(';');
            //int cellIndex = int.Parse(datas_10015[1]);
            string strs = datas_10015[2];
            string[] arr = strs.Split(',');
            Dispatcher.Invoke(() =>
            {
                AddTestData(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7]);
            });
        }
        public void RefreshButtons(List<BtnConfig> settings)
        {
            if (settings == null) return;
            for (int i = 0; i < settings.Count; i++) {
            for (int i = 0; i < settings.Count; i++)
            {
                var setting = settings[i];
                var margin = new Thickness(0, 0, 20, 0);
@@ -196,6 +415,35 @@
            }
        }
        private void SetArray(string name, PropertyValueTypes type, object[] arr)
        {
            try
            {
                var context = ((TeststandWrapper)executionWrapper).context;
                context.FileGlobals.DeleteSubProperty(name, 2);
                context.FileGlobals.NewSubProperty(name, type, true, null, 1);
                context.FileGlobals.GetPropertyObject(name, 0).SetNumElements(arr.Length);
                for (int i = 0; i < arr.Length; i++)
                {
                    if (type == PropertyValueTypes.PropValType_Boolean)
                    {
                        context.FileGlobals.SetValBoolean($"{name}[{i}]", 0, arr[i] == null ? false : (bool)arr[i]);
                    }
                    else
                    {
                        context.FileGlobals.SetValString($"{name}[{i}]", 0, arr[i]?.ToString());
                    }
                    // (type == PropertyValueTypes.PropValType_String)
                }
            }
            catch (Exception ex)
            {
                AppendLog(LogLevel.Error, $"写数组 {name} 错误: {ex.Message} {ex.StackTrace}");
            }
        }
        private void Wrapper_UIMessageEvent(object sender, UIMessageEvent e)
        {
            try
@@ -203,6 +451,39 @@
                if (e.EventCode == 10000)
                {
                    executionWrapper?.SetContext(e.Data);
                    string key = $"Running.OvenName";
                    executionWrapper?.SetFileGlobalValue(key, 1, OvenName);
                    key = $"Running.OvenIndex";
                    executionWrapper?.SetFileGlobalValue(key, 1, OvenIndex);
                    //key = $"Running.CellIndex";
                    //executionWrapper?.SetFileGlobalValue(key, 1, CellIndex);
                    if (CellIndex >= 0)
                    {
                        key = $"Running.CellIndex";
                        object[] arr = new object[CellCount];
                        arr[CellIndex] = true;
                        SetArray(key, PropertyValueTypes.PropValType_Boolean, arr);
                        key = $"Running.CellName";
                        string[] names = new string[CellCount];
                        names[CellIndex] = CellName;
                        SetArray(key, PropertyValueTypes.PropValType_String, names);
                    }
                    else
                    {
                        string[] names = Cells.Select(c => c.Title).ToArray();
                        SetArray($"Running.CellName", PropertyValueTypes.PropValType_String, names);
                    }
                    Dispatcher.Invoke(() =>
                    {
                        CellGrid.IsEnabled = true;
                        AppendLog(LogLevel.Debug, "Context初始化完成");
                    });
                    return;
                }
                if (e.EventCode == 10001)
@@ -234,14 +515,26 @@
                    });
                    return;
                }
                if (e.EventCode == 10004)
                {
                    int index = Convert.ToInt32(e.NumberData);
                    //CellStatus status = (CellStatus)Enum.Parse(typeof(CellStatus), e.StrData);
                    CellStatus status = (CellStatus)int.Parse(e.StrData);
                    Dispatcher.BeginInvoke(() =>
                    {
                        if (index < StatusCells.Count)
                        {
                            StatusCells[index].SetCurrentValue(StatusCell.StatusProperty, status);
                        }
                    });
                    return;
                }
            }
            catch (Exception ex)
            {
                AppendLog(LogLevel.Error, $"处理UI信息失败 {ex.Message} {ex.StackTrace}");
            }
        }
        private void Btn_BtnClick(object sender, RoutedEventArgs e)
        {
@@ -254,19 +547,7 @@
        {
            try
            {
                string key = $"Running.OvenName";
                executionWrapper?.SetFileGlobalValue(key, 1, OvenName);
                key = $"Running.CellName";
                executionWrapper?.SetFileGlobalValue(key, 1, CellName);
                key = $"Running.OvenIndex";
                executionWrapper?.SetFileGlobalValue(key, 1, OvenIndex);
                key = $"Running.CellIndex";
                executionWrapper?.SetFileGlobalValue(key, 1, CellIndex);
                key = $"Running.ActionName";
                string key = $"Running.ActionName";
                executionWrapper?.SetFileGlobalValue(key, 1, name);
            }
            catch (Exception ex)
@@ -390,12 +671,19 @@
            {
                executionWrapper?.SetFileGlobalValue("Running.StopTest", 1, true);
                executionWrapper?.WaitForExit();
                executionWrapper?.Dispose();
                tcpServer?.Stop();
            }
            catch (Exception ex)
            {
            }
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            StartTcpServer();
        }
    }
    public class TestDataItem : INotifyPropertyChanged