From d1b72117058f1131046b6aa3add8e3ccfae033d8 Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 09 十一月 2026 10:36:07 +0800
Subject: [PATCH] docs: CAN 模拟器独立 TCP 服务进程设计规格(统一 CanDeviceDriver + 双工推送协议)
---
Plugin.TsExecution/SingleControl.xaml.cs | 341 ++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 291 insertions(+), 50 deletions(-)
diff --git a/Plugin.TsExecution/SingleControl.xaml.cs b/Plugin.TsExecution/SingleControl.xaml.cs
index e0bbebe..0c3ecb0 100644
--- a/Plugin.TsExecution/SingleControl.xaml.cs
+++ b/Plugin.TsExecution/SingleControl.xaml.cs
@@ -1,9 +1,13 @@
-锘縰sing HMI.Core.Manager;
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
using HMI.Core.Util;
+using HMI.UI.Util;
using HMI.Util;
using NationalInstruments.TestStand.Interop.API;
using Plugin.TsExecution.Entity;
using System;
+using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
@@ -11,6 +15,7 @@
using System.Timers;
using System.Windows;
using System.Windows.Controls;
+using Util.ManualDebug;
namespace Plugin.TsExecution
{
@@ -36,11 +41,13 @@
}
}
#endregion
- private bool isLoadOK = false;
private int index;
private string CountIniPath;
private string status = "Ready";
+
+ private ScreenTouch[] screens;
+ private ScreenGrid screenGrid;
public string Status
{
@@ -57,6 +64,8 @@
Set(ref totalNum, value);
}
}
+
+ public TsExecution parent { get; set; }
private int passNum;
public int PassNum
@@ -130,6 +139,16 @@
}
}
+ private string socketName = string.Empty;
+ public string SocketName
+ {
+ get { return socketName; }
+ set
+ {
+ Set(ref socketName, value);
+ }
+ }
+
private ObservableCollection<TestStep> _datasource = new ObservableCollection<TestStep>();
public ObservableCollection<TestStep> Datasource
{
@@ -163,6 +182,16 @@
set
{
Set(ref _probeCount, value);
+ try
+ {
+ if (ProbeWarn <= 0) probeCountAlarm.Visibility = Visibility.Collapsed;
+ else if (value >= ProbeWarn) probeCountAlarm.Visibility = Visibility.Visible;
+ else probeCountAlarm.Visibility = Visibility.Collapsed;
+ }
+ catch
+ {
+
+ }
}
}
@@ -205,7 +234,15 @@
}
}
- public int ProbeWarn { get; private set; }
+ private int _probeWarn;
+ public int ProbeWarn
+ {
+ get => _probeWarn;
+ private set
+ {
+ Set(ref _probeWarn, value);
+ }
+ }
private bool isAutoMode;
public bool IsAutoMode
@@ -229,13 +266,13 @@
Interval = 100
};
refreshTimer.Elapsed += RefreshTimer_Elapsed;
- ReadProbeCount();
ReadCounter();
InitializeComponent();
+ RefreshProbeCount(null);
try
{
var value = ParameterManager.GetCommonParameterByName("AutoTestMode");
- IsAutoMode = bool.Parse(value.Value);
+ IsAutoMode = value == null ? true : bool.Parse(value.Value);
}
catch
{
@@ -337,7 +374,10 @@
public void IniTestData()
{
- Datasource.Clear();
+ Dispatcher.Invoke(() =>
+ {
+ Datasource.Clear();
+ });
}
/// <summary>
@@ -383,37 +423,6 @@
this.WriteCounter();
}
- /// <summary>
- /// 浠巌ni璇诲彇鎺㈤拡浣跨敤娆℃暟
- /// </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",
@@ -442,9 +451,48 @@
this.UpdateTestCounter(null);
}
+ public void WriteToExcel(string path)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ try
+ {
+ string suffix = Path.GetExtension(path);
+ if (!string.Equals(".xlsx", suffix, StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(".xls", suffix, StringComparison.OrdinalIgnoreCase))
+ {
+ path = path.Replace(suffix, ".xls");
+ }
+
+ FileInfo fi = new FileInfo(path);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+ List<string[]> rows = new List<string[]>();
+ rows.Add(new string[] { "娴嬭瘯鏃堕棿", "娴嬭瘯浜�", "娴嬭瘯璁惧", "鏉″舰鐮�", "娴嬭瘯缁撴灉" });
+ rows.Add(new string[] { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), UserInfo.User.Name, ParamSetting.StationName, Barcode, Status });
+ rows.Add(new string[] { "椤圭洰鍚嶇О", "娴嬭瘯鍙傛暟", "娴嬭瘯鍊�", "涓婇檺", "涓嬮檺", "鍗曚綅", "缁撴灉" });
+ if (Datasource != null && Datasource.Count > 0)
+ {
+ foreach (var data in Datasource)
+ {
+ rows.Add(new string[] { data.Name, data.Step, data.Value, data.LimitUp, data.LimitDown, data.Unit, data.Result });
+ }
+ }
+ ExcelHelper.ExportExcel(path, rows);
+ }
+ catch (Exception ex)
+ {
+ TsExecution.logger.Error("Write CSV File Failed.", ex);
+ }
+ });
+ }
+
+
public void WriteToCSV(string path)
{
- Dispatcher.BeginInvoke(new Action(() =>
+ Dispatcher.Invoke(() =>
{
try
{
@@ -474,7 +522,7 @@
{
TsExecution.logger.Error("Write CSV File Failed.", ex);
}
- }));
+ });
}
public void ShowPausePanel()
@@ -520,17 +568,7 @@
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)
@@ -550,5 +588,208 @@
//Canvas.SetTop(modal, (scannerPanel.ActualHeight - scannerVisualModal.ActualHeight) / 2);
}
}
+
+ public void RefreshScreen(int[][] configs)
+ {
+ //foreach (UIElement item in canvas.Children)
+ //{
+ // if (item is ScreenTouch)
+ // {
+ // canvas.Children.Remove(item);
+ // }
+ //}
+ screenContainer.Child = null;
+
+
+ screenGrid = new ScreenGrid(1, configs.Length);
+
+ screens = new ScreenTouch[configs.Length];
+
+ int space = 2 * (screens.Length + 1);
+ for (int i = 0; i < configs.Length; i++)
+ {
+ var screen = new ScreenTouch(configs[i][0], configs[i][1])
+ {
+ Width = Math.Max((tableHeader.ActualHeight / 9 * 16 - space) / screens.Length, 0),
+ Height = Math.Max((tableHeader.ActualHeight / 9 * 16 - space) / screens.Length / 16 * 9, 0)
+ };
+ screens[i] = screen;
+ screenGrid.AddScreen(screen, 0, i);
+ }
+ screenContainer.Child = screenGrid;
+
+ //canvas.Children.Add(screens[0]);
+ //Canvas.SetBottom(screens[0], 0);
+ //Canvas.SetRight(screens[0], 0);
+ //Panel.SetZIndex(screens[0], 999);
+ }
+
+ public void DrawScreenPoint(int index, int x, int y)
+ {
+ screens[index].DrawPoint(x, y);
+ }
+
+ /// <summary>
+ /// 缁樺浘涔嬪墠娓呯┖宸叉湁鐨�
+ /// </summary>
+ /// <param name="index"></param>
+ /// <param name="points"></param>
+ public void DrawScreenPoints(int index, int[][] points)
+ {
+ screens[index].DrawPoints(points);
+ }
+
+ /// <summary>
+ /// 缁樺浘涔嬪墠涓嶆竻绌哄凡鏈夌殑
+ /// </summary>
+ /// <param name="index"></param>
+ /// <param name="points"></param>
+ public void DrawNewScreenPoints(int index, int[][] points)
+ {
+ screens[index].DrawNewPoints(points);
+ }
+
+ public void ClearScreenPoint(int index)
+ {
+ screens[index].Clear();
+ }
+
+ public void RefreshProbeCount(ProductData product)
+ {
+ 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;
+ }
+
+ public void RefreshProduct(ProductData product)
+ {
+ if (product == null)
+ {
+ screenContainer.Child = null;
+ return;
+ }
+ try
+ {
+ string screenSize = ProductManager.GetParameterByProductAndName(product.Name, "ScreenTouch")?.Value;
+ if (string.IsNullOrEmpty(screenSize))
+ {
+ screenContainer.Child = null;
+ return;
+ }
+ string[] arr = screenSize.Split(';');
+ int[][] configs = new int[arr.Length][];
+
+ for (int i = 0; i < arr.Length; i++)
+ {
+ string[] size = arr[i].Split(',');
+ configs[i] = new int[2] { int.Parse(size[0]), int.Parse(size[1]) };
+ }
+ RefreshScreen(configs);
+ }
+ catch (Exception ex)
+ {
+ TsExecution.logger.Error("RefreshProduct Failed.", ex);
+ screenContainer.Child = null;
+ }
+ }
+
+ private void control_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ if (screenGrid == null)
+ {
+ return;
+ }
+ //screenGrid.Height = tableHeader.ActualHeight - 2;
+ //screenGrid.Width = tableHeader.ActualHeight / 9 * 16 - 2;
+
+ int space = 2 * (screens.Length + 1);
+
+ for (int i = 0; i < screens.Length; i++)
+ {
+ var screen = screens[i];
+ screen.Width = Math.Max(Math.Floor((tableHeader.ActualHeight / 9 * 16 - space) / screens.Length), 0);
+ screen.Height = Math.Max(Math.Floor(screen.Width / 16 * 9), 0);
+ }
+ }
+
+ private void screenContainer_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (e.ClickCount == 2)
+ {
+ new ScreenTouchWin(screens)
+ {
+ Owner = Window.GetWindow(this)
+ }.ShowDialog();
+ }
+ }
+
+ private void control_PreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ if (parent.EnableManualDebug)
+ {
+ ContextMenu contextMenu = new ContextMenu();
+ contextMenu.Closed += ContextMenu_Closed;
+ var item = new MenuItem
+ {
+ IsCheckable = false,
+ Name = "manualDebugItem",
+ Header = this.lang("鎵嬪姩璋冭瘯"),
+ };
+ item.Click += Item_Click; ;
+ contextMenu.Items.Add(item);
+ this.ContextMenu = contextMenu;
+ }
+ else
+ {
+
+ this.ContextMenu = null;
+ }
+ }
+
+ private void Item_Click(object sender, RoutedEventArgs e)
+ {
+ string manualDebugSeq = ParameterManager.GetCommonParameterByName("ManualDebugSeqPath")?.Value;
+ if (string.IsNullOrEmpty(manualDebugSeq))
+ {
+ MsgBoxHelper2.Error("璇峰厛璁剧疆鎵嬪姩璋冭瘯搴忓垪璺緞[ManualDebugSeqPath]!");
+ return;
+ }
+ string modelPath = parent.tsModelPath;
+ var win = new ManualDebugWindow(manualDebugSeq, modelPath, false)
+ {
+ Title = $"宸ヤ綅{this.index}鎵嬪姩璋冭瘯",
+
+ Owner = Window.GetWindow(this),
+ OvenIndex = 0,
+ OvenName = "",
+ CellCount = parent.tsSockets.Count,
+
+ CellIndex = this.index,
+ CellName = "",
+ };
+ win.ShowDialog();
+ }
+
+ private void ContextMenu_Closed(object sender, RoutedEventArgs e)
+ {
+ this.ContextMenu = null;
+ }
}
}
--
Gitblit v1.9.1