using HMI.Core.Entity;
using HMI.Core.Manager;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.Util;
using NationalInstruments.TestStand.Interop.API;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using Plugin.TsExecution.Entity;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
namespace Plugin.TsExecution
{
///
/// SingleControl.xaml 的交互逻辑
///
public partial class SingleControl : UserControl, INotifyPropertyChanged
{
#region ...
public event PropertyChangedEventHandler PropertyChanged;
protected void Set([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
protected void Set(ref T old, T @new, [CallerMemberName] string propertyName = null)
{
old = @new;
if (propertyName != null)
{
Set(propertyName);
}
}
#endregion
private int index;
private string CountIniPath;
private string status = "Ready";
private ScreenTouch[] screens;
private ScreenGrid screenGrid;
public string Status
{
get { return status; }
set { Set(ref status, value); }
}
private double totalNum;
public double TotalNum
{
get => totalNum;
private set
{
Set(ref totalNum, value);
}
}
private int passNum;
public int PassNum
{
get => passNum;
private set { Set(ref passNum, value); }
}
private int failNum;
public int FailNum
{
get => failNum;
private set { Set(ref failNum, value); }
}
private double passRate;
public double PassRate
{
get => passRate;
private set
{
Set(ref passRate, value);
}
}
public string NumInfo
{
get => this.lang("Ts.NumInfo", TotalNum, PassNum, FailNum, string.Format("{0:0.00}", PassRate));
}
public string TestInfo
{
get => this.lang("Ts.TestInfo", Barcode, ElapseTime);
}
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";
public string ElapseTime
{
get { return elapseTime; }
set
{
if (value == "Start Timing")
{
this.refreshTimer.Enabled = true;
TestStartTime = DateTime.Now;
StepStartTime = DateTime.Now;
}
else
{
this.refreshTimer.Enabled = false;
if (value != "Stop Timing")
{
Set(ref elapseTime, value + "s");
Set("TestInfo");
}
}
}
}
private string socketName = string.Empty;
public string SocketName
{
get { return socketName; }
set
{
Set(ref socketName, value);
}
}
private ObservableCollection _datasource = new ObservableCollection();
public ObservableCollection Datasource
{
get => _datasource;
set
{
Set(ref _datasource, value);
}
}
private DateTime TestStartTime = new DateTime();
private DateTime StepStartTime = new DateTime();
private TimeSpan TimeCount = new TimeSpan();
private System.Timers.Timer refreshTimer;
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);
}
}
///
/// 进度值
///
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)
{
DataContext = this;
this.CountIniPath = CountIniPath;
this.index = Index;
ProbeWarn = probeWarn;
refreshTimer = new System.Timers.Timer()
{
Interval = 100
};
refreshTimer.Elapsed += RefreshTimer_Elapsed;
RefreshProbeCount(null);
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)
{
//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");
}
public SequenceContext SequenceFileContext
{
get;
set;
}
///
/// 获取TS的每步测试的数据添加到表格
/// 项目名称,测试参数,测试值,上限,下限,单位,结果
///
///
public void AddTestData(string name, string step_name, string value, string HightLimit, string LowLimit, string unit, string Status)
{
try
{
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 (Exception ex)
{
//屏蔽错误
}
}
public void UpdateStatus(string status)
{
if (status == "Passed")
{
UpdateTestCounter(true);
}
else if (status == "Error" || status == "Failed")
{
UpdateTestCounter(false);
}
else if (Status != "Testing" && status == "Testing")
{
UpdateProbeCount(ProbeCount + 1);
}
Status = status;
}
public void IniTestData()
{
Datasource.Clear();
}
///
/// 设置测试进度条
///
///
public void SetTestProcess(int ProcessVal)
{
ProcessValue = ProcessVal;
Set("ProcessValueLabel");
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
this.UpdateTestCounter(null);
}
private void UpdateTestCounter(bool? result)
{
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 = ((double)PassNum / TotalNum);
}
else
{
PassRate = 0.0;
}
Set("NumInfo");
this.WriteCounter();
}
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()
{
this.PassNum = 0;
this.FailNum = 0;
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 rows = new List();
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.Invoke(() =>
{
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()
{
}
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);
}
}
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);
}
///
/// 绘图之前清空已有的
///
///
///
public void DrawScreenPoints(int index, int[][] points)
{
screens[index].DrawPoints(points);
}
///
/// 绘图之前不清空已有的
///
///
///
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;
}
}
///
/// 更新探针使用次数
///
///
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;
}
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();
}
}
}
}