From 771a0e7b6b1276087515bbe94de28358cb92963b Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期四, 04 六月 2026 10:32:27 +0800
Subject: [PATCH] 优化老化;
---
Plugin.BurnIn/Util/DpUtil.cs | 220 +
Plugin.DataBoard/Plugin.DataBoard.csproj | 64
Plugin.DataBoard/packages.config | 22
WPFProject/BuildCmd.bat | 30
Plugin.BurnIn/Util/FontSizeConverter.cs | 32
Plugin.TestResult/DataTable.xaml | 1
Plugin.QualityReport/AssemblyInfo.cs | 13
Plugin.TsSupport/TsExecutionWrapper.cs | 26
HMI.Core/Util/MSMQHelper.cs | 4
Plugin.BurnIn/ChartWindow.xaml.cs | 31
Plugin.TestResult/TestResultView.xaml.cs | 143
Plugin.TsExecution/Plugin.TsExecution.csproj | 8
Plugin.BurnIn/Resource/ok2.png | 0
Plugin.BurnIn/Resource/ng2.png | 0
Plugin.TestResult/ViewControl.xaml.cs | 127
WPFProject/App.config | 3
Plugin.TsExecution/TsExecution.xaml.cs | 574 +
Plugin.QualityReport/QualityReport.xaml | 249 +
Plugin.BurnIn/UI/LiveChart.xaml | 29
Plugin.BurnIn/Resource/checkIn.png | 0
Plugin.BurnIn/Resource/waiting2.png | 0
HMI.Core/Util/Sqlite3Helper.cs | 2
HMI.UI/DpUtil/UniformGridHelper.cs | 18
Plugin.BurnIn/Util/SNValidator.cs | 86
HMI.Core/Setting/ParamSetting.cs | 51
Plugin.BurnIn/InfoWindow.xaml | 117
Plugin.BurnIn/Model/ScannerConfig.cs | 34
Plugin.TsExecution/ScreenTouch.xaml.cs | 21
Plugin.BurnIn/Util/PNUtil.cs | 106
Plugin.BurnIn/BurnInUI.xaml | 159
Plugin.DataBoard/DataBoard.xaml.cs | 468 ++
S7Driver/PLCS7Driver.cs | 166
Plugin.BurnIn/TestResultView.xaml | 21
S7Driver/Properties/AssemblyInfo.cs | 4
Plugin.BurnIn/InfoTable.xaml.cs | 203 +
Plugin.TsSupport/ITestExecutionWrapper.cs | 3
SimpleUtil/HMI.TapApi/Properties/AssemblyInfo.cs | 33
Plugin.TsExecution/SingleControl.xaml | 3
WPFProject/WPFProject.sln | 99
HMI.Core/Entity/SortParam.cs | 18
Plugin.BurnIn/Scanner.xaml | 78
SimpleUtil/HMI.Simple.Util/AlarmUtil.cs | 27
HMI.Util/ExcelHelper.cs | 30
Plugin.BurnIn/Util/CommonCodeParser.cs | 28
Plugin.TestResult/Properties/AssemblyInfo.cs | 4
StationGlobalsReader/MainWindow.xaml | 29
HMI.Util/Alarm/AlarmUtil.cs | 34
Plugin.BurnIn/BurnInUI.xaml.cs | 494 ++
Plugin.DataBoard/app.config | 11
Plugin.QualityReport/Libs/Static/重复性模板.xls | 0
Plugin.TsExecution/Properties/AssemblyInfo.cs | 14
Plugin.BurnIn/Model/CellInfo.cs | 17
Plugin.BurnIn/Model/BaseModel.cs | 21
Plugin.BurnIn/Model/TcpServer.cs | 59
Plugin.BurnIn/AssemblyInfo.cs | 12
Plugin.TestResult/SingleCell.xaml.cs | 40
Plugin.TestResult/DataTable.xaml.cs | 86
WPFProject/ResourceListener.cs | 14
Plugin.BurnIn/SingleCell.xaml | 146
Plugin.BurnIn/ChartWindow.xaml | 23
Plugin.BurnIn/CoolerStatus.xaml.cs | 93
Plugin.BurnIn/SingleCell.xaml.cs | 1174 ++++++
HMI.ParameterManage/HMI.ParameterManage.csproj | 4
Plugin.BurnIn/Plugin.BurnIn.csproj | 70
Plugin.BurnIn/InfoWindow.xaml.cs | 176
Plugin.BurnIn/UI/LiveChart.xaml.cs | 516 ++
Plugin.BurnIn/DataTable.xaml.cs | 887 ++++
Plugin.BurnIn/Util/ScannerParser.cs | 30
Plugin.QualityReport/Libs/Static/MSA模板.xlsx | 0
StationGlobalsReader/StationGlobalsReader.csproj | 28
Plugin.BurnIn/Model/Info.cs | 69
Plugin.BurnIn/ScannerSetting.xaml.cs | 147
Plugin.BurnIn/ManualDebugWindow.xaml | 21
Plugin.TsSupport/Plugin.TsSupport.csproj | 6
SimpleUtil/HMI.TapApi/ProductUtil.cs | 164
Plugin.BurnIn/Model/DataTableModel.cs | 7
HMI.ParameterManage/Model/XmlModel.cs | 16
Plugin.DataBoard/DataBoard.xaml | 49
Plugin.TestResult/Scanner.xaml.cs | 57
Plugin.BurnIn/ScannerSetting.xaml | 66
Plugin.TsExecution/ScreenTouch.xaml | 4
StationGlobalsReader/AssemblyInfo.cs | 10
Plugin.BurnIn/DataTable.xaml | 164
Plugin.BurnIn/Constant/CommonConstant.cs | 70
Plugin.BurnIn/ManualDebugWindow.xaml.cs | 93
Plugin.BurnIn/TestResultView.xaml.cs | 683 +++
Plugin.BurnIn/Resource/checkInFailed2.png | 0
Plugin.BurnIn/CoolerStatus.xaml | 25
Plugin.QualityReport/Plugin.QualityReport.csproj | 46
Plugin.BurnIn/Util/ModelCodeParser.cs | 97
Plugin.BurnIn/Resource/barcode.png | 0
Plugin.BurnIn/Resource/ready.png | 0
HMI.ParameterManage/SettingModal.xaml.cs | 10
HMI.Core/HMI.Core.csproj | 1
Plugin.BurnIn/Util/JKCodeParser.cs | 30
Plugin.BurnIn/Resource/testing2.png | 0
WPFProject/WPFProject.csproj | 29
StationGlobalsReader/App.xaml.cs | 13
Plugin.BurnIn/Util/RunTimeVariablePool.cs | 11
Plugin.BurnIn/Cooler.xaml.cs | 206 +
Plugin.TsExecution/SingleControl.xaml.cs | 136
StationGlobalsReader/MainWindow.xaml.cs | 50
Plugin.BurnIn/Scanner.xaml.cs | 465 ++
Plugin.TsSupport/TeststandWrapper.cs | 16
SimpleUtil/HMI.Simple.Util/MSMQHelper.cs | 21
StationGlobalsReader/App.xaml | 9
SimpleUtil/HMI.TapApi/HMI.TapApi.csproj | 74
Plugin.BurnIn/Util/ICodeParser.cs | 10
Plugin.TsSupport/TapWrapper.cs | 238 +
HMI.Util/HMI.Util.csproj | 4
Plugin.BurnIn/Resource/abort.png | 0
/dev/null | 1
Plugin.BurnIn/Model/BaseConfig.cs | 198 +
Plugin.BurnIn/InfoTable.xaml | 92
Plugin.DataBoard/SimpleData.cs | 7
Plugin.QualityReport/Libs/Static/CMK模板.xls | 0
Plugin.BurnIn/Cooler.xaml | 77
Plugin.BurnIn/Resource/alert.png | 0
Plugin.QualityReport/QualityReport.xaml.cs | 705 +++
119 files changed, 10,909 insertions(+), 621 deletions(-)
diff --git a/HMI.Core/Entity/SortParam.cs b/HMI.Core/Entity/SortParam.cs
new file mode 100644
index 0000000..ddba1dc
--- /dev/null
+++ b/HMI.Core/Entity/SortParam.cs
@@ -0,0 +1,18 @@
+锘縰sing System.ComponentModel;
+
+namespace HMI.Core.Entity
+{
+ public class SortParam
+ {
+ public string field { get; set; }
+ public ListSortDirection direction { get; set; }
+ public string sort { get; set; }
+ }
+
+ public class PageParam
+ {
+ public int limit { get; set; }
+ public int offset { get; set; }
+
+ }
+}
diff --git a/HMI.Core/HMI.Core.csproj b/HMI.Core/HMI.Core.csproj
index 3a0a3b2..8fc307a 100644
--- a/HMI.Core/HMI.Core.csproj
+++ b/HMI.Core/HMI.Core.csproj
@@ -118,6 +118,7 @@
<Compile Include="Entity\PermissionData.cs" />
<Compile Include="Entity\ProductData.cs" />
<Compile Include="Entity\SelectBase.cs" />
+ <Compile Include="Entity\SortParam.cs" />
<Compile Include="Entity\TestItemData.cs" />
<Compile Include="Entity\UserInfo.cs" />
<Compile Include="Event\TabChange.cs" />
diff --git a/HMI.Core/Setting/ParamSetting.cs b/HMI.Core/Setting/ParamSetting.cs
index e01cc33..f14a912 100644
--- a/HMI.Core/Setting/ParamSetting.cs
+++ b/HMI.Core/Setting/ParamSetting.cs
@@ -1,17 +1,38 @@
锘縰sing HMI.Core.Manager;
using HMI.Core.Util;
+using System.Collections;
+using System.Configuration;
using System.IO;
+using System.Runtime.CompilerServices;
namespace HMI.Core.Setting
{
public class ParamSetting
{
+ private static Hashtable customConfig = (Hashtable)ConfigurationManager.GetSection("TestResultConfig");
+
+ private static string GetValue([CallerMemberName] string propertyName = null)
+ {
+ return (customConfig != null && customConfig.ContainsKey(propertyName)) ? customConfig[propertyName].ToString() : null;
+ }
+
/// <summary>
/// MesAddress
/// </summary>
public static string MesAddress { get; private set; } = "127.0.0.1:8080";
+ /// <summary>
+ /// 鑰佸寲瀵煎嚭琛岃浆鍒�
+ /// </summary>
public static bool ReverseCSV { get; private set; } = false;
+
+ /// <summary>
+ /// 瀹㈡埛缂栫爜
+ /// </summary>
public static string CustomerCode { get; private set; }
+
+ /// <summary>
+ /// 鐢熶骇鏁版嵁DB瀛樻斁鐩綍
+ /// </summary>
public static string DataLogFolder { get; private set; } = null;
@@ -28,15 +49,32 @@
public static bool ProbeByModel { get; private set; } = false;
public static int ReverseCSVSkipRow { get; private set; } = 3;
+ /// <summary>
+ /// 鎿嶄綔鏄惁闇�瑕佸瘑鐮�
+ /// </summary>
+
public static bool IsOptRequirePassword { get; private set; } = false;
-
+
/// <summary>
/// 鍚敤鎵爜鎹㈠瀷
/// </summary>
public static bool EnableAutoModel { get; private set; } = false;
+
+ public const string ShareConfigKey = "ShareConfig";
public static string ShareConfig { get; private set; } = null;
public static bool ShowBurnInAbort { get; private set; } = true;
public static string SocketNames { get; private set; } = string.Empty;
+ public static string StationName { get; private set; } = string.Empty;
+
+
+ public static string EngineType
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? "TestStand" : data.ToString();
+ }
+ }
static ParamSetting()
{
@@ -154,7 +192,7 @@
try
{
- ShareConfig = ParameterManager.GetCommonParameterByName<string>("ShareConfig", null);
+ ShareConfig = ParameterManager.GetCommonParameterByName<string>(ShareConfigKey, null);
}
catch
{
@@ -178,6 +216,15 @@
{
}
+
+ try
+ {
+ StationName = ParameterManager.GetCommonParameterByName<string>("StationName", string.Empty);
+ }
+ catch
+ {
+
+ }
}
}
}
diff --git a/HMI.Core/Util/MSMQHelper.cs b/HMI.Core/Util/MSMQHelper.cs
index 41dcf48..efa87d5 100644
--- a/HMI.Core/Util/MSMQHelper.cs
+++ b/HMI.Core/Util/MSMQHelper.cs
@@ -13,7 +13,7 @@
/// <summary>
/// 娑堟伅闃熷垪鎿嶄綔绫�
/// </summary>
- public class MSMQHelper
+ public class MSMQHelperCCC
{
/// <summary>
/// 娑堟伅闃熷垪鍚嶇О
@@ -34,7 +34,7 @@
/// 鏋勯�犲嚱鏁�
/// </summary>
/// <param name="Name">娑堟伅闃熷垪鍚嶇О</param>
- public MSMQHelper(string Name)
+ public MSMQHelperCCC(string Name)
{
try
{
diff --git a/HMI.Core/Util/Sqlite3Helper.cs b/HMI.Core/Util/Sqlite3Helper.cs
index 57fe091..e271025 100644
--- a/HMI.Core/Util/Sqlite3Helper.cs
+++ b/HMI.Core/Util/Sqlite3Helper.cs
@@ -11,6 +11,8 @@
private string ConnectString = string.Empty;
+ public const int MAX_ATTACHED = 30;
+
private SQLiteConnection conn = null;
public Sqlite3Helper(string DBFile)
diff --git a/HMI.ParameterManage/HMI.ParameterManage.csproj b/HMI.ParameterManage/HMI.ParameterManage.csproj
index c5043b6..dc481a8 100644
--- a/HMI.ParameterManage/HMI.ParameterManage.csproj
+++ b/HMI.ParameterManage/HMI.ParameterManage.csproj
@@ -172,6 +172,10 @@
<Project>{afea100a-9223-448d-ab10-3015d93dd98c}</Project>
<Name>HMI.Util</Name>
</ProjectReference>
+ <ProjectReference Include="..\SimpleUtil\HMI.LogUtil\HMI.LogUtil.csproj">
+ <Project>{6d0aab08-0f3e-48ce-b755-9d29bc8f1225}</Project>
+ <Name>HMI.LogUtil</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Entity\" />
diff --git a/HMI.ParameterManage/Model/XmlModel.cs b/HMI.ParameterManage/Model/XmlModel.cs
index 92210e2..c04e4ad 100644
--- a/HMI.ParameterManage/Model/XmlModel.cs
+++ b/HMI.ParameterManage/Model/XmlModel.cs
@@ -1,10 +1,12 @@
锘縰sing HMI.Core.Entity;
using HMI.Core.Manager;
using HMI.Core.Util;
+using HMI.LogUtil;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
+using System.Text.RegularExpressions;
namespace HMI.ParameterManage.Model
{
@@ -71,8 +73,16 @@
public bool ValidateParameterName(object value, out string msg)
{
+ string pattern = @"^[\p{L}_][\p{L}\p{N}_]*$";
msg = null;
string name = value.ToString();
+
+ if (!Regex.IsMatch(name, pattern))
+ {
+ msg = "鍙傛暟鍚嶄笉鑳戒互鏁板瓧寮�澶�";
+ return false;
+ }
+
if (Products == null) return true;
var temp = Parameters.FirstOrDefault(p => p.Name == name);
if (temp != null && temp != SelectedParameter)
@@ -125,6 +135,7 @@
else
{
InsertParameter(data);
+ LogHelper.Info("HMI", $"[{data.ProductName}] Add New Parameter {data.Name}. Value: {data.Value}", out _);
}
}
@@ -215,8 +226,13 @@
public void UpdateParameter(int index, ParameterData data)
{
var temp = XmlHelper.DeepClone(Parameters);
+ var old = temp[index];
temp[index] = data;
SaveParameter(temp);
+ if (old.Value != data.Value)
+ {
+ LogHelper.Info("HMI", $"Update Parameter {data.Name}. Value: {old.Value} => {data.Value}", out _);
+ }
}
/// <summary>
diff --git a/HMI.ParameterManage/SettingModal.xaml.cs b/HMI.ParameterManage/SettingModal.xaml.cs
index 22569d6..c485bf6 100644
--- a/HMI.ParameterManage/SettingModal.xaml.cs
+++ b/HMI.ParameterManage/SettingModal.xaml.cs
@@ -11,7 +11,9 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Windows.Controls;
+using System.Windows.Interop;
namespace HMI.ParameterManage
{
@@ -116,6 +118,14 @@
public bool ValidateName(object value, out string err)
{
err = null;
+
+ string pattern = @"^[\p{L}_][\p{L}\p{N}_]*$";
+ if (!Regex.IsMatch(value.ToString(), pattern))
+ {
+ err = "鍙傛暟鍚嶄笉鑳戒互鏁板瓧寮�澶�";
+ return false;
+ }
+
var data = Datasource?.FirstOrDefault(e => e.Name == value.ToString());
if (data != null && data != Data)
{
diff --git a/HMI.UI/DpUtil/UniformGridHelper.cs b/HMI.UI/DpUtil/UniformGridHelper.cs
index 6f98327..1b12a2b 100644
--- a/HMI.UI/DpUtil/UniformGridHelper.cs
+++ b/HMI.UI/DpUtil/UniformGridHelper.cs
@@ -108,6 +108,24 @@
control.BorderThickness = bt;
}
+ if (child is Border border)
+ {
+
+ int col = i % columnCount;
+ int row = i / columnCount;
+
+ double left = (col == 0 && ignoreLeft) ? 0 : width;
+ double top = (row == 0 && ignoreTop) ? 0 : width;
+
+ double right = ignoreRight ? 0 : ((col == columnCount - 1) ? width : 0);
+ double bottom = ignoreBottom ? 0 : ((row == rowCount - 1) ? width : 0);
+
+ var bt = new Thickness(left, top, right, bottom);
+
+ border.BorderBrush = brush;
+ border.BorderThickness = bt;
+ }
+
}
}
diff --git a/HMI.Util/Alarm/AlarmUtil.cs b/HMI.Util/Alarm/AlarmUtil.cs
index 1044e1e..ea9988f 100644
--- a/HMI.Util/Alarm/AlarmUtil.cs
+++ b/HMI.Util/Alarm/AlarmUtil.cs
@@ -2,6 +2,7 @@
using HMI.Core.Entity;
using HMI.Core.Setting;
using HMI.Core.Util;
+using HMI.Simple.Util;
using log4net;
using S7Driver;
using System;
@@ -192,7 +193,7 @@
private void RefershAlarm()
{
- alarmRefershToMain.Send("AlarmRefersh", string.Empty);
+ alarmRefershToMain.Send("AlarmRefersh", string.Empty, string.Empty, 0);
List<AlarmText> alarms = new List<AlarmText>();
foreach (AlarmText alarm in currentPLCAlarmCache)
@@ -223,8 +224,8 @@
try
{
mqTimer.Enabled = false;
- alarmQueue.Receive(100, out string MessageID, out string MsgStr);
- if (MessageID != string.Empty)
+ alarmQueue.Receive(100, out string MessageID, out MQAlarm alarm);
+ if (MessageID != string.Empty && alarm != null)
{
switch (MessageID)
{
@@ -251,28 +252,19 @@
//}
break;
default:
- string[] arr = MsgStr.Split(',');
- string source = "PC";
- string info = string.Empty;
- if (arr.Length > 1)
- {
- source = arr[0];
- info = arr[1];
- }
- else
- {
- info = MsgStr;
- }
+ string source = string.IsNullOrEmpty(alarm.Source) ? "PC" : alarm.Source;
+ string info = alarm.Content;
+
AlarmText newAlarm = new AlarmText
{
Source = source,
VirtualId = $"{source}:{info}",
AlarmInfo = info,
- Level = 3,
+ Level = alarm.Level,
Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
};
if (currentMQAlarmCache
- .Find(alarm => alarm.Source == newAlarm.Source && alarm.AlarmInfo == newAlarm.AlarmInfo) == null)
+ .Find(a => a.Source == newAlarm.Source && a.AlarmInfo == newAlarm.AlarmInfo) == null)
{
currentMQAlarmCache.Add(newAlarm);
RefershAlarm();
@@ -297,7 +289,7 @@
BlockReadCache.Clear();
try
{
- BlockSettings = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(blockFilePath);
+ BlockSettings = HMI.Core.Util.XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(blockFilePath);
}
catch (Exception ex)
{
@@ -321,7 +313,7 @@
{
try
{
- MarkSettings = XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(markFilePath);
+ MarkSettings = HMI.Core.Util.XmlHelper.DeserializeFromXml<ObservableCollection<AlarmSetting>>(markFilePath);
}
catch (Exception ex)
{
@@ -338,13 +330,13 @@
public void UpdateBlockSettings(IEnumerable<AlarmSetting> settings)
{
- XmlHelper.SerializeToXml(blockFilePath, settings);
+ HMI.Core.Util.XmlHelper.SerializeToXml(blockFilePath, settings);
RefreshBlockSettings();
}
public void UpdateMarkSettings(IEnumerable<AlarmSetting> settings)
{
- XmlHelper.SerializeToXml(markFilePath, settings);
+ HMI.Core.Util.XmlHelper.SerializeToXml(markFilePath, settings);
RefreshMarkSettings();
}
}
diff --git a/HMI.Util/ExcelHelper.cs b/HMI.Util/ExcelHelper.cs
index 0708a5c..801b657 100644
--- a/HMI.Util/ExcelHelper.cs
+++ b/HMI.Util/ExcelHelper.cs
@@ -104,6 +104,36 @@
}
}
+ public static void ExportExcel(string targetPath, List<string[]> rows)
+ {
+ IWorkbook workbook = null;
+ if (targetPath.EndsWith(".xlsx"))
+ {
+ workbook = new XSSFWorkbook();
+ }
+ else if (targetPath.EndsWith(".xls"))
+ {
+ workbook = new HSSFWorkbook();
+ }
+ workbook.CreateSheet("sheet1");////鏂板缓涓�涓伐浣滆〃
+ ISheet SheetOne = workbook.GetSheet("sheet1");
+
+
+ for (int i = 0; i < rows.Count; i++)
+ {
+ IRow rowTemp = SheetOne.CreateRow(i);
+ for (int j = 0; j < rows[i].Length; j++)
+ {
+ rowTemp.CreateCell(j).SetCellValue(rows[i][j]);
+ }
+ }
+
+ using (FileStream fs = new FileStream(targetPath, FileMode.OpenOrCreate))
+ {
+ workbook.Write(fs);
+ }
+ }
+
public static List<T> ReadFromExcel<T>(string sourcePath)
{
diff --git a/HMI.Util/HMI.Util.csproj b/HMI.Util/HMI.Util.csproj
index fc1f1c8..1404835 100644
--- a/HMI.Util/HMI.Util.csproj
+++ b/HMI.Util/HMI.Util.csproj
@@ -99,6 +99,10 @@
<Project>{628ef12b-9ed2-4b20-950f-dc3ecc3fd15f}</Project>
<Name>S7Driver</Name>
</ProjectReference>
+ <ProjectReference Include="..\SimpleUtil\HMI.Simple.Util\HMI.Simple.Util.csproj">
+ <Project>{CF5BEBE9-2803-49C3-B773-73D082E0984A}</Project>
+ <Name>HMI.Simple.Util</Name>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
diff --git a/Plugin.BurnIn/AssemblyInfo.cs b/Plugin.BurnIn/AssemblyInfo.cs
new file mode 100644
index 0000000..ba840b1
--- /dev/null
+++ b/Plugin.BurnIn/AssemblyInfo.cs
@@ -0,0 +1,12 @@
+using HMI.Core.Annotation;
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+[assembly: PluginClassName("Plugin.BurnIn.BurnInUI")]
diff --git a/Plugin.BurnIn/BurnInUI.xaml b/Plugin.BurnIn/BurnInUI.xaml
new file mode 100644
index 0000000..040a05e
--- /dev/null
+++ b/Plugin.BurnIn/BurnInUI.xaml
@@ -0,0 +1,159 @@
+锘�<hb:PluginMaskControl x:Class="Plugin.BurnIn.BurnInUI"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:std="clr-namespace:HMI.StdControl;assembly=HMI.StdControl"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ mc:Ignorable="d"
+ Style="{StaticResource pluginMaskControl}"
+ Loaded="UserControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ <Style TargetType="GroupBox">
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='20,1920'}" />
+ </Style>
+
+ <Style TargetType="Button">
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ </Style>
+
+ <Style TargetType="Label">
+ <Setter Property="BorderThickness" Value="1"/>
+ <Setter Property="BorderBrush" Value="LightGray"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Setter Property="Padding" Value="5"/>
+ </Style>
+ </UserControl.Resources>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <!--<Grid.ColumnDefinitions>
+ <ColumnDefinition Width="7.5*"/>
+ <ColumnDefinition Width="*"/>
+ </Grid.ColumnDefinitions>-->
+ <local:TestResultView x:Name="testResultView" Grid.Row="1" Grid.Column="0" Loaded="testResultView_Loaded" />
+ <DockPanel Margin="10,0" Grid.Row="0" Grid.Column="1" LastChildFill="False" Background="#FFF" VerticalAlignment="Center">
+ <pu:FormGroup DockPanel.Dock="Right">
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="20">
+ <Button x:Name="btnStart" Click="Start_Click"
+ Width="100" FontSize="14" Padding="0" Height="30" Content="{DynamicResource App.Start}">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource SuccessButton}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding EnableManualDebug}" Value="True">
+ <Setter Property="IsEnabled" Value="False"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding IsRunning}" Value="True">
+ <Setter Property="IsEnabled" Value="False"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+
+ <Button x:Name="btnStop" Click="Stop_Click" Style="{StaticResource DangerButton}"
+ Width="100" FontSize="14" Padding="0" Height="30"
+ Content="{DynamicResource App.Stop}"/>
+
+ <Button x:Name="btnClear" Click="BtnClear_Click" Style="{StaticResource PrimaryButton}"
+ Width="100" FontSize="14" Padding="0" Height="30"
+ Content="{DynamicResource Ts.BtnClearNum}"/>
+
+ <Button x:Name="scannerSetting" Click="ScannerSetting_Click" Style="{StaticResource PrimaryButton}"
+ Width="100" FontSize="14" Padding="0" Height="30" Content="{DynamicResource App.ScannerSetting}" Cursor="Hand"/>
+
+ <!--<Button x:Name="btnScan1" Click="Scan_Click_1" Style="{StaticResource PrimaryButton}"
+ Content="{DynamicResource Tr.Zone1Scan}"/>
+
+ <Button x:Name="btnScan2" Click="Scan_Click_2" Style="{StaticResource PrimaryButton}"
+ Content="{DynamicResource Tr.Zone2Scan}"/>-->
+ </StackPanel>
+ </pu:FormGroup>
+ <pu:FormGroup Header="{DynamicResource Tr.ProductInfo}" FontSize="16" Visibility="Collapsed">
+ <ComboBox x:Name="modelSelect" Style="{StaticResource FormComboxStyle}" Width="200"
+ Height="28"
+ pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+ SelectionChanged="modelSelect_SelectionChanged"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="{DynamicResource Tr.TestProgram}" FontSize="16">
+ <TextBox IsReadOnly="True" x:Name="tbFileName" Style="{StaticResource EditorTextBoxStyle}" Width="200"
+Height="28" Text="{Binding FileName}"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup>
+ <std:StdEnableMes DockPanel.Dock="Left" FontSize="20"
+ x:Name="stdEnableMes"
+ ValueChanged="StdEnableMes_ValueChanged"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup x:Name="FgEnableManualDebug" Visibility="Collapsed">
+ <CheckBox FontSize="20"
+ IsChecked="{Binding EnableManualDebug,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
+ VerticalContentAlignment="Center"
+ Content="鎵嬪姩璋冭瘯" />
+ </pu:FormGroup>
+
+
+ <!--<pu:FormGroup Header="{DynamicResource Tr.Status}" FontSize="16">
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="10">
+ <Label HorizontalContentAlignment="Center" VerticalAlignment="Center">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="HorizontalAlignment" Value="Stretch"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding mesStatus}" Value="true">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Content" Value="{DynamicResource Tr.MES_OPEN}"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding mesStatus}" Value="false">
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="Content" Value="{DynamicResource Tr.MES_CLOSE}"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ <Label>
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="HorizontalAlignment" Value="Stretch"/>
+ <Setter Property="VerticalAlignment" Value="Center"/>
+ <Setter Property="Content" Value="{Binding produceStatus}"/>
+ <Setter Property="Margin" Value="0,10"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding produceStatus}" Value="INIT">
+ <Setter Property="Background" Value="Gray"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding produceStatus}" Value="STOP">
+ <Setter Property="Background" Value="Red"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding produceStatus}" Value="RUNNING">
+ <Setter Property="Background" Value="Green"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ </StackPanel>
+ </pu:FormGroup>-->
+ </DockPanel>
+ </Grid>
+</hb:PluginMaskControl>
diff --git a/Plugin.BurnIn/BurnInUI.xaml.cs b/Plugin.BurnIn/BurnInUI.xaml.cs
new file mode 100644
index 0000000..7c372f1
--- /dev/null
+++ b/Plugin.BurnIn/BurnInUI.xaml.cs
@@ -0,0 +1,494 @@
+锘縰sing HMI.Base;
+using HMI.Core.Api;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.LogUtil;
+using HMI.StdControl;
+using HMI.UI.Util;
+using log4net;
+using NationalInstruments.TestStand.Interop.API;
+using PLCHelper;
+using Plugin.BurnIn.Util;
+using Plugin.TsSupport;
+using System.ComponentModel;
+using System.IO;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// ViewControl.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class BurnInUI : PluginMaskControl, IAlarmHandler
+ {
+
+ private System.Timers.Timer timer;
+
+ public static ILog Logger { get; private set; }
+
+
+ private bool _mesStatus;
+
+ public bool mesStatus
+ {
+ get => _mesStatus;
+ set => Set(ref _mesStatus, value);
+ }
+
+ private string _produceStatus = "INIT";
+
+ public string produceStatus
+ {
+ get => _produceStatus;
+ set => Set(ref _produceStatus, value);
+ }
+
+ private string _fileName;
+
+ public string FileName
+ {
+ get => _fileName;
+ set => Set(ref _fileName, value);
+ }
+
+ private bool enableManualDebug;
+ public bool EnableManualDebug
+ {
+ get => enableManualDebug;
+ set
+ {
+ if (IsRunning)
+ {
+ MsgBoxHelper2.Warn("璇峰厛缁撴潫鑷姩娴嬭瘯");
+ return;
+ }
+ testResultView.inManualDebugMode = value;
+ Set(ref enableManualDebug, value);
+ }
+ }
+
+ public override void SetLogger(ILog logger)
+ {
+ base.SetLogger(logger);
+ Logger = logger;
+ }
+
+ private bool isRunning = false;
+ public bool IsRunning
+ {
+ get => isRunning;
+ set
+ {
+ Set(ref isRunning, value);
+ testResultView.IsRunning = value;
+ this.modelSelect.IsEnabled = !value;
+ this.btnStop.IsEnabled = value;
+ stdEnableMes.CbEnabled = !value;
+ }
+ }
+
+ private bool AutoExecuteSeq = true;
+
+ #region TS鐩稿叧
+
+ /// <summary>
+ /// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
+ /// </summary>
+ private SequenceContext SequenceContext = null;
+ #endregion
+
+ public BurnInUI()
+ {
+ S7Context.Init(SystemSetting.Instance.PlcIp, SystemSetting.Instance.PlcPort);
+ DataContext = this;
+ timer = new System.Timers.Timer();
+ timer.Interval = 1000;
+ timer.Elapsed += Timer_Elapsed;
+ InitializeComponent();
+
+
+ //testResultView.testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
+ //testResultView.testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
+ //testResultView.testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
+ }
+
+ private void HandleUIMessage(int EventCase, int MethodCode, string strData, object xData)
+ {
+ try
+ {
+ try
+ {
+ log.Debug($"EventCase: {EventCase}, MethodCode: {MethodCode}, StrData: {strData}");
+ }
+ catch
+ {
+
+ }
+
+ if (EventCase == 8)
+ {
+ IsRunning = false;
+ return;
+ }
+
+ if (EventCase != 10014) return;
+
+ if (MethodCode == 0)
+ {
+ /// 璁剧疆鍙ユ焺
+ this.SequenceContext = (SequenceContext)xData;
+ return;
+ }
+
+
+ if (MethodCode == 8)
+ {
+ /// 鏇存柊MES鐘舵��
+ mesStatus = strData == "1";
+ return;
+ }
+
+ if (MethodCode == 9)
+ {
+ /// 鏇存柊鐢熶骇鐘舵��
+ produceStatus = strData;
+ return;
+ }
+ }
+ catch
+ { }
+ }
+
+ private void ExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+ {
+ HandleUIMessage(e.EventCode, Convert.ToInt16(e.NumberData), e.StrData, e.Data);
+ }
+
+ private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ testResultView.RefreshCooler();
+ }
+
+ public TestResultView View
+ {
+ get => testResultView;
+ }
+ public static string SannerIniFile { get; private set; }
+
+ public override void InitFinish()
+ {
+ base.InitFinish();
+ string path = Path.Combine(BaseFolder, "Count.ini");
+ testResultView.SetCountIniPath(path);
+ testResultView.InitMainGrid();
+
+ path = Path.Combine(BaseFolder, "Scanner.ini");
+ if (!File.Exists(path))
+ {
+ File.Create(path).Close();
+ }
+ SannerIniFile = path;
+ LoadProduct();
+ var api = S7Context.Get(RunTimeVariablePool.DEFAULT_PLC_NAME);
+ log.Debug($"PLC {api.IpAddress}:{api.Port}");
+ try
+ {
+ var value = ParameterManager.GetCommonParameterByName("AutoExecuteSeq");
+ AutoExecuteSeq = bool.Parse(value.Value);
+ }
+ catch
+ {
+ AutoExecuteSeq = true;
+ }
+
+ try
+ {
+ var value = ParameterManager.GetCommonParameterByName("BurnInMainSeq");
+ testResultView.testSeqFile = value.Value;
+ FileName = Path.GetFileName(value.Value);
+ }
+ catch
+ {
+ testResultView.testSeqFile = string.Empty;
+ FileName = string.Empty;
+ }
+ string type = Path.GetExtension(FileName);
+ bool isTap = string.Equals(".tapplan", type, StringComparison.OrdinalIgnoreCase);
+
+ testResultView.InitTestStandEngine(isTap);
+ testResultView.executionWrapper.UIMessageEvent += ExecutionWrapper_UIMessageEvent;
+
+ testResultView.SetOvenName();
+
+ RefreshUIConfig();
+ }
+
+ /// <summary>
+ /// 鍒锋柊UI閰嶇疆
+ /// </summary>
+ private void RefreshUIConfig()
+ {
+ try
+ {
+ /// 杩愯涓氨涓嶇
+ if (IsRunning)
+ {
+ return;
+ }
+ bool enableManualDebug = ParameterManager.GetCommonParameterByName("EnableManualDebug", false);
+ if (enableManualDebug)
+ {
+ FgEnableManualDebug.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ FgEnableManualDebug.Visibility = Visibility.Collapsed;
+ EnableManualDebug = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("RefreshUIConfig Error.", ex);
+ }
+ }
+
+ private bool isLoaded;
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ AlarmShowHelper.AddHandler(this);
+ if (AutoExecuteSeq)
+ {
+ ShowMask(() =>
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ Start_Click(null, null);
+ }), System.Windows.Threading.DispatcherPriority.Background);
+ }, (ex) =>
+ {
+ ToastHelper.Error("Loaded Failed.");
+ log.Error("Loaded Failed.", ex);
+ }, "璇风◢鍚�", LangUtil.Get("Ts.SequenceIsStarting"));
+ }
+ else
+ {
+ IsRunning = false;
+ }
+ Loaded -= UserControl_Loaded;
+ }
+
+ public void LoadProduct()
+ {
+ List<ProductData> products = ProductManager.GetProducts<List<ProductData>>()
+ ?? new List<ProductData>();
+ this.modelSelect.Items.Clear();
+ List<string> productSource = new List<string>();
+ foreach (var prd in products)
+ {
+ this.modelSelect.Items.Add(prd.Name);
+ productSource.Add(prd.Name);
+ }
+ testResultView.SetProductSource(productSource);
+ testResultView.SetCurrentProduct(null);
+
+ //string model = testResultView.executionWrapper.GetStationGlobalValue<string>("ProductModel", 1);
+ ////testResultView.engine.Globals.GetValString("ProductModel", 1);
+ //if (!string.IsNullOrEmpty(model))
+ //{
+ // this.modelSelect.SelectedItem = model;
+ // testResultView.SetCurrentProduct(model);
+ //}
+ //else if (products.Count > 0)
+ //{
+ // this.modelSelect.SelectedIndex = 0;
+ // testResultView.SetCurrentProduct(products[0].Name);
+ //}
+ }
+
+ private void modelSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ try
+ {
+ string currentModel = this.modelSelect.SelectedItem.ToString();
+ List<ParameterData> parameters = ProductManager.GetParametersByProductName(currentModel);
+
+ testResultView.executionWrapper.SetStationGlobalValue<string>("ProductModel", 0, currentModel);
+ testResultView.executionWrapper.CommitToDisk(false);
+
+ //testResultView.engine.Globals.SetValString("ProductModel", 0, currentModel);
+ //testResultView.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("鍒囨崲浜у搧鍨嬪彿澶辫触!" + ex.Message + ex.StackTrace);
+ }
+ }
+
+ private void Start_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(testResultView.testSeqFile))
+ {
+ MsgBoxHelper2.Warn("璇峰厛璁剧疆BurnInMainSeq灞炴��!");
+ IsRunning = false;
+ return;
+ }
+ LogHelper.Info("UI", "鎬诲惎鍔ㄦ寜閽寜涓�", out _);
+ log.Info("鎬诲惎鍔ㄦ寜閽寜涓�");
+ ShowMask(() =>
+ {
+ testResultView.StartTestSequence();
+ Dispatcher.Invoke(() =>
+ {
+ IsRunning = true;
+ });
+ }, (ex) =>
+ {
+ log.Error("StartTestSequence Error.", ex);
+ Dispatcher.Invoke(() =>
+ {
+ MsgBoxHelper.Error(Window.GetWindow(this), $"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}");
+ });
+ }, null, "璇风◢鍚�...");
+ }
+ catch (Exception ex)
+ {
+ log.Error("Start_Click Failed.", ex);
+ MsgBoxHelper.Error(Window.GetWindow(this),
+ $"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}");
+ }
+ }
+
+ private void Stop_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ bool breakStop = false;
+ foreach (var oven in TestResultView.tables)
+ {
+ if (oven.IsTesting)
+ {
+ breakStop = true;
+ break;
+ }
+ }
+ if (breakStop)
+ {
+ MsgBoxHelper2.Warn(this.lang("Tr.OvenIsTesting"));
+ return;
+ }
+
+ if (MsgBoxHelper2.WarnChoose(this.lang("Tr.MakeSureStopAllTest")) != MessageBoxResult.OK)
+ {
+ return;
+ }
+
+ LogHelper.Info("UI", "鎬诲仠姝㈡寜閽寜涓�", out _);
+ log.Info("鎬诲仠姝㈡寜閽寜涓�");
+ testResultView.StopTest();
+ /// 宸茬粡鍔犱簡WaitForExit,杩欓噷鍙互鏀逛负false
+ IsRunning = false;
+ }
+ catch (Exception ex)
+ {
+ log.Error("Stop_Click Failed.", ex);
+ MsgBoxHelper.Error(Window.GetWindow(this),
+ $"{this.lang("Ts.StopTestSequenceFailed")}: {ex.Message}");
+ }
+ }
+
+ private void testResultView_Loaded(object sender, RoutedEventArgs e)
+ {
+ }
+
+ /// <summary>
+ /// 璁℃暟娓呴浂鎸夐挳浜嬩欢
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ private void BtnClear_Click(object sender, RoutedEventArgs e)
+ {
+ testResultView.ClearNumber();
+ }
+
+ private void ScannerSetting_Click(object sender, RoutedEventArgs e)
+ {
+ ScannerSetting setting = new ScannerSetting()
+ {
+ Owner = Window.GetWindow(this)
+ };
+ setting.Open(false, "Config");
+ }
+
+ private void StdEnableMes_ValueChanged(object sender, StdUIEventArg e)
+ {
+ testResultView.executionWrapper.SetStationGlobalValue<bool>($"SystemSetting.{e.StringValue}", 1, e.BoolValue);
+ //testResultView.SequenceContext?.StationGlobals.SetValBoolean($"SystemSetting.{e.StringValue}", 1, e.BoolValue);
+ }
+
+ public void HandleAlarm(AlarmText alarm)
+ {
+ if (alarm.Level >= 4 && TestResultView.tables != null)
+ {
+ log.Info($"4绾ф姤璀﹁Е鍙�: [{alarm.AlarmInfo}],灏嗗仠姝㈡墍鏈夌倝浣撴祴璇�");
+ foreach (var oven in TestResultView.tables)
+ {
+ testResultView.SetStartFlag(oven.index, false);
+ }
+ return;
+ }
+
+ DataTable targetOven = null;
+ foreach (var oven in TestResultView.tables)
+ {
+ if (alarm.AlarmInfo?.StartsWith(oven.title) == true)
+ {
+ targetOven = oven;
+ break;
+ }
+ }
+ if (targetOven == null)
+ {
+ return;
+ }
+ if (alarm.Level >= 3)
+ {
+ /// 3绾т互涓婄殑鎶ヨ浼氬仠姝㈡祴璇�
+ log.Info($"3绾ф姤璀﹁Е鍙�: [{alarm.AlarmInfo}],灏嗗仠姝㈣�佸寲鐐塠{targetOven.title}]娴嬭瘯");
+ testResultView.SetStartFlag(targetOven.index, false);
+ }
+ }
+
+ public override void Active()
+ {
+ base.Active();
+ LoadProduct();
+ RefreshUIConfig();
+ }
+
+ public override void OnClose(object sender, CancelEventArgs e)
+ {
+ if (IsRunning)
+ {
+ MsgBoxHelper2.Warn("璇峰厛鍋滄鑰佸寲娴嬭瘯锛�");
+ e.Cancel = true;
+ }
+ }
+
+ public override void DoClose(object sender, EventArgs e)
+ {
+ try
+ {
+ timer?.Stop();
+ testResultView.ReleaseResource();
+ }
+ catch
+ {
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/ChartWindow.xaml b/Plugin.BurnIn/ChartWindow.xaml
new file mode 100644
index 0000000..3e8c283
--- /dev/null
+++ b/Plugin.BurnIn/ChartWindow.xaml
@@ -0,0 +1,23 @@
+锘�<pu:WindowX x:Class="Plugin.BurnIn.ChartWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
+ InteropOwnersMask="False"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ Unloaded="Window_Unloaded"
+ Title="{Binding title}" Height="450" Width="800">
+ <UniformGrid x:Name="mainGrid" Columns="1">
+
+ </UniformGrid>
+</pu:WindowX>
diff --git a/Plugin.BurnIn/ChartWindow.xaml.cs b/Plugin.BurnIn/ChartWindow.xaml.cs
new file mode 100644
index 0000000..ebab99b
--- /dev/null
+++ b/Plugin.BurnIn/ChartWindow.xaml.cs
@@ -0,0 +1,31 @@
+锘縰sing HMI.Core.Util;
+using Panuon.WPF.UI;
+using System.Windows;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// ChartWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ChartWindow : WindowX
+ {
+ private string _title;
+ public string title
+ {
+ get => _title;
+ set => Set(ref _title, value);
+ }
+
+ public ChartWindow(string title)
+ {
+ this.title = $"{title}{this.lang("Tr.DetailChart")}";
+ this.DataContext = this;
+ InitializeComponent();
+ }
+
+ private void Window_Unloaded(object sender, RoutedEventArgs e)
+ {
+ this.mainGrid.Children.Clear();
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Constant/CommonConstant.cs b/Plugin.BurnIn/Constant/CommonConstant.cs
new file mode 100644
index 0000000..56b844b
--- /dev/null
+++ b/Plugin.BurnIn/Constant/CommonConstant.cs
@@ -0,0 +1,70 @@
+锘縰sing System.Drawing;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Plugin.BurnIn.Constant
+{
+ public class CommonStatus
+ {
+ public static readonly string OK = "ok";
+ public static readonly string NG = "ng";
+ public static readonly string WAITING = "waiting";
+ public static readonly string CHECKINFAILED = "checkInFailed";
+ public static readonly string CHECK_IN = "checkIn";
+ public static readonly string TESTING = "testing";
+ public static readonly string ALERT = "alert";
+ public static readonly string READY = "ready";
+
+ private static string[] cache = new string[] { "ok", "ng", "waiting", "checkInFailed", "checkIn", "testing", "alert", "ready" };
+
+ public static readonly Dictionary<string, string> STATUS_MAP = new Dictionary<string, string>() {
+ { "ok","姝e父"},
+ { "ng","寮傚父"},
+ { "waiting","绛夊緟涓�"},
+ { "checkInFailed","CheckIn澶辫触"},
+ { "checkIn","CheckIn"},
+ { "testing","娴嬭瘯涓�"},
+ { "alert","鎶ヨ"},
+ { "ready","鍑嗗灏辩华"},
+ { "abort","鎵嬪姩鍋滄"},
+ };
+
+ public static readonly Dictionary<string, SolidBrush> COLOR_MAP = new Dictionary<string, SolidBrush>() {
+ { "ok",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "ng",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "waiting",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "testing",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "checkInFailed",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "checkIn",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ { "abort",new SolidBrush(Color.FromArgb(0,0,0,0))},
+ };
+
+ public static string GetRandomStatus()
+ {
+ return cache[new Random().Next(cache.Length)];
+ }
+
+ public static string GetStatusDescription(string status)
+ {
+ if (STATUS_MAP.ContainsKey(status)) return STATUS_MAP[status];
+ return "";
+ }
+ }
+
+ public class StatusColorConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is string status)
+ {
+
+ }
+ return null;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Cooler.xaml b/Plugin.BurnIn/Cooler.xaml
new file mode 100644
index 0000000..1f75d21
--- /dev/null
+++ b/Plugin.BurnIn/Cooler.xaml
@@ -0,0 +1,77 @@
+锘�<UserControl x:Class="Plugin.BurnIn.Cooler"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ mc:Ignorable="d"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <GroupBox Header="{Binding Title}">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Label x:Name="label">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalContentAlignment" Value="Center"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="0">
+ <Setter Property="Background" Value="Gray"/>
+ <Setter Property="Content" Value="鍋滄"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="1">
+ <Setter Property="Content" Value="杩愭按涓�"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="2">
+ <Setter Property="Background" Value="Gray"/>
+ <Setter Property="Content" Value="{Binding LabelContent}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="3">
+ <Setter Property="Background" Value="Gray"/>
+ <Setter Property="Content" Value="娴嬪帇涓�"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ <StackPanel Grid.Row="1">
+ <!--<Button Click="Button_Click" Style="{StaticResource PrimaryButton}" Tag="1" IsEnabled="False" Content="杩愭按"/>-->
+ <Button Click="Start_Click" Tag="2" x:Name="startBtn" Content="鍚规按">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="2">
+ <Setter Property="IsEnabled" Value="False"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ <!--<Button Click="Button_Click" Style="{StaticResource PrimaryButton}" Tag="3" IsEnabled="False" Content="娴嬪帇"/>-->
+ <Button Click="Stop_Click" Style="{StaticResource DangerButton}" Tag="0" Content="鍋滄" Cursor="Hand"/>
+ <!--<Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+ <Setter Property="Content" Value="鎵嬪姩鍚规按"/>
+ <Setter Property="IsEnabled" Value="False"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding Status}" Value="0">
+ <Setter Property="Content" Value="鎵嬪姩鍚规按"/>
+ <Setter Property="IsEnabled" Value="True"/>
+ <Setter Property="Background" Value="{DynamicResource SuccessColor}"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding Status}" Value="2">
+ <Setter Property="Content" Value="鍋滄鍚规按"/>
+ <Setter Property="IsEnabled" Value="True"/>
+ <Setter Property="Background" Value="{DynamicResource DangerColor}"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>-->
+ </StackPanel>
+ </Grid>
+ </GroupBox>
+</UserControl>
diff --git a/Plugin.BurnIn/Cooler.xaml.cs b/Plugin.BurnIn/Cooler.xaml.cs
new file mode 100644
index 0000000..35ca5a8
--- /dev/null
+++ b/Plugin.BurnIn/Cooler.xaml.cs
@@ -0,0 +1,206 @@
+锘縰sing HMI.Core.Manager;
+using HMI.UI.Util;
+using PLCHelper;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Timers;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// Cooler.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class Cooler : UserControl, INotifyPropertyChanged
+ {
+ #region ...
+ public virtual event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual 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 int index { get; private set; }
+
+ public string Title { get; set; }
+
+ private System.Timers.Timer timer;
+
+ public Cooler(int index)
+ {
+ DataContext = this;
+ this.index = index;
+ this.Title = $"绗瑊index + 1}璺按鍐锋満";
+ InitializeComponent();
+ }
+
+ private ushort status;
+ public ushort Status
+ {
+ get => status;
+ set
+ {
+ Set(ref status, value);
+ }
+ }
+
+ private int totalTime;
+
+ private string labelContent = "鍚规按涓�";
+ public string LabelContent
+ {
+ get => labelContent;
+ set
+ {
+ Set(ref labelContent, value);
+ }
+ }
+
+ private void InitTimer(int time)
+ {
+ if (time <= 0)
+ {
+ time = 240;
+ }
+ totalTime = time;
+ LabelContent = $"鍚规按涓璡r\n鍓﹞totalTime}s...";
+ timer = new System.Timers.Timer();
+ timer.Interval = 1000;
+ timer.Elapsed += Timer_Elapsed;
+ timer.Enabled = true;
+ }
+
+ private void Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ try
+ {
+ timer.AutoReset = false;
+ if (totalTime > 0)
+ {
+ totalTime -= 1;
+ LabelContent = $"鍚规按涓璡r\n鍓﹞totalTime}s...";
+ }
+ else
+ {
+ if (S7Context.WriteData("", $"Cooler{index + 1}_Status", 0, out string errMsg))
+ {
+ Status = 0;
+ Dispatcher.Invoke(() =>
+ {
+ startBtn.IsEnabled = true;
+ });
+ }
+ else
+ {
+ Dispatcher.Invoke(() =>
+ {
+ ToastHelper.Error(errMsg);
+ });
+ }
+ Release();
+ }
+ }
+ catch (Exception ex)
+ {
+ }
+ finally
+ {
+ if (timer?.Enabled == true) timer.AutoReset = true;
+ }
+ }
+
+ private void Start_Click(object sender, RoutedEventArgs e)
+ {
+ if (timer != null) return;
+ var btn = sender as Button;
+
+ int totalTime = 240;
+
+ try
+ {
+ var p = ParameterManager.GetCommonParameterByName("鍚规按鏃堕棿")?.Value;
+ if (!string.IsNullOrEmpty(p)) totalTime = int.Parse(p);
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ if (MsgBoxHelper2.WarnChoose($"绗� [{index + 1}] 璺按鍐锋満纭畾瑕亄btn.Content}鍚�?") == MessageBoxResult.OK)
+ {
+ try
+ {
+ if (S7Context.WriteData("", $"Cooler{index + 1}_Status", 2, out string errMsg))
+ {
+ Status = 2;
+ InitTimer(totalTime);
+ btn.IsEnabled = false;
+ }
+ else
+ {
+ ToastHelper.Error(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(ex.Message);
+ }
+ }
+ }
+
+ private void Stop_Click(object sender, RoutedEventArgs e)
+ {
+ var btn = sender as Button;
+
+ if (MsgBoxHelper2.WarnChoose($"绗� [{index + 1}] 璺按鍐锋満纭畾瑕亄btn.Content}鍚�?") == MessageBoxResult.OK)
+ {
+ try
+ {
+ if (timer != null)
+ {
+ timer.Enabled = false;
+ timer.Dispose();
+ timer = null;
+ }
+
+ if (S7Context.WriteData("", $"Cooler{index + 1}_Status", 0, out string errMsg))
+ {
+ Status = 0;
+ startBtn.IsEnabled = true;
+ }
+ else
+ {
+ ToastHelper.Error(errMsg);
+ }
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(ex.Message);
+ }
+ }
+ }
+
+ public void Release()
+ {
+ if (timer != null)
+ {
+ timer.Enabled = false;
+ timer.Dispose();
+ timer = null;
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/CoolerStatus.xaml b/Plugin.BurnIn/CoolerStatus.xaml
new file mode 100644
index 0000000..34b2311
--- /dev/null
+++ b/Plugin.BurnIn/CoolerStatus.xaml
@@ -0,0 +1,25 @@
+锘�<pu:WindowX x:Class="Plugin.BurnIn.CoolerStatus"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ WindowStartupLocation="CenterScreen"
+ FontSize="20"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
+ InteropOwnersMask="False"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ Closed="WindowX_Closed"
+ Loaded="WindowX_Loaded"
+ Width="600" Height="400">
+ <Window.Resources>
+ </Window.Resources>
+ <Grid Margin="10" x:Name="mainGrid"></Grid>
+</pu:WindowX>
diff --git a/Plugin.BurnIn/CoolerStatus.xaml.cs b/Plugin.BurnIn/CoolerStatus.xaml.cs
new file mode 100644
index 0000000..d446edf
--- /dev/null
+++ b/Plugin.BurnIn/CoolerStatus.xaml.cs
@@ -0,0 +1,93 @@
+锘縰sing Panuon.WPF.UI;
+using PLCHelper;
+using System.Timers;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// CoolerStatus.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class CoolerStatus : WindowX
+ {
+ private int ovenIndex;
+ private int columns;
+ private System.Timers.Timer timer;
+ private List<Cooler> coolers = new List<Cooler>();
+
+ public CoolerStatus(int ovenIndex, int columns, string title)
+ {
+ DataContext = this;
+ this.ovenIndex = ovenIndex;
+ this.columns = columns;
+ Title = title;
+ timer = new System.Timers.Timer();
+ timer.Interval = 1000;
+ timer.Elapsed += Timer_Elapsed;
+ InitializeComponent();
+ RefreshUI();
+ RefreshStatus();
+ }
+
+ private void Timer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ RefreshStatus();
+ }
+
+ private void RefreshStatus()
+ {
+ foreach (var cooler in coolers)
+ {
+ try
+ {
+ if (S7Context.GetData("", $"Cooler{cooler.index + 1}_Status", out object val))
+ {
+ cooler.Dispatcher.Invoke(() =>
+ {
+ cooler.Status = (ushort)val;
+ });
+ }
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+ }
+
+ private void RefreshUI()
+ {
+ mainGrid.Children.Clear();
+ mainGrid.ColumnDefinitions.Clear();
+
+ for (int i = 0; i < this.columns; i++)
+ {
+ ColumnDefinition newCol = new ColumnDefinition();
+ newCol.Width = new GridLength(1, GridUnitType.Star);
+ mainGrid.ColumnDefinitions.Add(newCol);
+ var cooler = new Cooler(ovenIndex * columns + i);
+ Grid.SetColumn(cooler, i);
+ mainGrid.Children.Add(cooler);
+ coolers.Add(cooler);
+ }
+ }
+
+ private void WindowX_Closed(object sender, EventArgs e)
+ {
+ timer.Enabled = false;
+ timer.Dispose();
+
+ foreach (var cooler in coolers)
+ {
+ cooler.Release();
+ }
+ }
+
+ private void WindowX_Loaded(object sender, RoutedEventArgs e)
+ {
+ timer.Enabled = true;
+ this.Loaded -= WindowX_Loaded;
+ }
+ }
+}
diff --git a/Plugin.BurnIn/DataTable.xaml b/Plugin.BurnIn/DataTable.xaml
new file mode 100644
index 0000000..4d57492
--- /dev/null
+++ b/Plugin.BurnIn/DataTable.xaml
@@ -0,0 +1,164 @@
+锘�<UserControl x:Class="Plugin.BurnIn.DataTable"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+xmlns:pw="https://opensource.panuon.com/wpf"
+xmlns:pu="https://opensource.panuon.com/wpf-ui"
+xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+xmlns:dc="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ mc:Ignorable="d"
+ Background="#FFF"
+ BorderBrush="Black"
+ BorderThickness="1"
+ x:Name="control"
+ Loaded="UserControl_Loaded"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ <dc:ReverseBoolConverter x:Key="reverseConverter"/>
+ </UserControl.Resources>
+ <Grid x:Name="grid">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="8.5*"/>
+ <RowDefinition Height="1.5*"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+ <Grid x:Name="infoGrid" Grid.Row="0" Background="#a1eafb">
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+
+ <TextBlock FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='20,940'}"
+ FontWeight="Bold"
+ Margin="0"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center" Text="{Binding title}"/>
+
+ <ComboBox Grid.Row="1" FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='15,940'}"
+ Style="{StaticResource FormComboxStyle}"
+ IsEnabled="{Binding IsTesting,Converter={StaticResource reverseConverter}}"
+ pu:ComboBoxHelper.ClearButtonVisibility="Collapsed"
+ BorderBrush="Black"
+ Height="26"
+ BorderThickness="0,1,0,0"
+ pu:ComboBoxHelper.Watermark="{DynamicResource Tr.ProductInfo}"
+ Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='150,940'}"
+ SelectedValuePath="Content"
+ x:Name="CbProduct" SelectionChanged="CbProduct_SelectionChanged"/>
+
+ <local:InfoTable x:Name="infoTable" Grid.Row="0" Grid.Column="1"
+ Grid.RowSpan="2"
+ FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+ Converter={StaticResource FontSizeConverter}, ConverterParameter='12,940'}"></local:InfoTable>
+ </Grid>
+
+ <UniformGrid x:Name="mainGrid" Grid.Row="1" dp:UniformGridHelper.InnerBorder="1"
+ dp:UniformGridHelper.InnerBorderIgnore="Left,Right,Bottom">
+ </UniformGrid>
+
+ <!--<local:Chart Grid.Row="2" x:Name="chart" BorderThickness="0,1,0,1" BorderBrush="Black"
+ MouseDoubleClick="chart_MouseDoubleClick"/>-->
+
+ <StatusBar FontSize="14" Grid.Row="3">
+ <StatusBar.ItemsPanel>
+ <ItemsPanelTemplate>
+ <DockPanel/>
+ </ItemsPanelTemplate>
+ </StatusBar.ItemsPanel>
+ <StatusBarItem DockPanel.Dock="Left">
+ <Button Style="{StaticResource LinkButton}" Click="Button_Click_1" Content="{DynamicResource App.ScannerSetting}"/>
+ </StatusBarItem>
+
+ <StatusBarItem DockPanel.Dock="Right">
+ <StackPanel Orientation="Horizontal" dp:StackPanelHelper.ChildSpace="8">
+ <!--<Button Style="{StaticResource DeleteLink}" Click="Button_Click_2" Content="鍋滄娴嬭瘯"/>-->
+
+ <StackPanel Orientation="Horizontal">
+ <Ellipse Width="10" Height="10">
+ <Ellipse.Style>
+ <Style TargetType="Ellipse">
+ <Setter Property="Fill" Value="LightGray"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="ERROR">
+ <Setter Property="Fill" Value="Red"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding TcpServerStatus,ElementName=control}" Value="RUNNING">
+ <Setter Property="Fill" Value="Green"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Ellipse.Style>
+ </Ellipse>
+ <TextBlock Text="{Binding TcpServerInfo}"/>
+ <Button Padding="0" Margin="0" BorderThickness="0" Click="Button_Click">馃攧</Button>
+ </StackPanel>
+ </StackPanel>
+ </StatusBarItem>
+
+ <StatusBarItem DockPanel.Dock="Right">
+ <Button Click="Manual_Cooler_Opt" x:Name="coolerSetting">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource LinkButton}">
+ <Setter Property="Content" Value="{DynamicResource Tr.CoolerSetting}"/>
+ <Setter Property="Foreground" Value="{DynamicResource PrimaryColor}"/>
+ </Style>
+ </Button.Style>
+ </Button>
+ </StatusBarItem>
+
+ <StatusBarItem >
+ <TextBox IsReadOnly="True" FontSize="16" Background="Transparent" BorderThickness="0" Text="{Binding statusText}"/>
+ </StatusBarItem>
+ </StatusBar>
+
+ <UniformGrid Grid.Row="4" Rows="1">
+ <!--<UniformGrid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition/>
+ </UniformGrid.ColumnDefinitions>-->
+ <Button Click="ScanWindow_Click" Style="{StaticResource PrimaryButton}"
+ IsEnabled="{Binding IsTesting,Converter={StaticResource reverseBool}}"
+ Content="{DynamicResource Tr.Scan}"/>
+ <Button Grid.Column="1" Click="ClearAllSnr_Click" Style="{StaticResource DangerButton}"
+ IsEnabled="{Binding IsTesting,Converter={StaticResource reverseBool}}"
+Content="{DynamicResource Tr.ClearAllSNR}"/>
+ <!--<Button Grid.Column="2" Click="SetStationGlobal_Click" Style="{StaticResource SuccessButton}"
+ Content="{DynamicResource App.Start}"/> Background="#1296db"-->
+
+ <Button Grid.Column="2" Click="Abort_Click" x:Name="abortBtn"
+ Style="{DynamicResource DangerButton}" Background="#1296db" Content="Abort"/>
+
+ <Button Grid.Column="3" Click="StartSingleClick">
+ <Button.Style>
+ <Style TargetType="Button" BasedOn="{StaticResource SuccessButton}">
+ <Setter Property="Content" Value="{DynamicResource App.Start}"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding IsTesting}" Value="True">
+ <Setter Property="Background" Value="{DynamicResource DangerVerBar}"/>
+ <Setter Property="Content" Value="鍋滄娴嬭瘯"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Button.Style>
+ </Button>
+ </UniformGrid>
+ </Grid>
+</UserControl>
\ No newline at end of file
diff --git a/Plugin.BurnIn/DataTable.xaml.cs b/Plugin.BurnIn/DataTable.xaml.cs
new file mode 100644
index 0000000..f9ad8ac
--- /dev/null
+++ b/Plugin.BurnIn/DataTable.xaml.cs
@@ -0,0 +1,887 @@
+锘縰sing HMI.Base;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.LogUtil;
+using HMI.UI.Util;
+using HMI.Util;
+using Plugin.BurnIn.Model;
+using Plugin.BurnIn.Util;
+using Plugin.TsSupport;
+using SuperSocket.SocketBase.Config;
+using SuperSocket.SocketBase.Protocol;
+using System.ComponentModel;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Timers;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// DataTable.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class DataTable : UserControl, INotifyPropertyChanged
+ {
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private string _title;
+
+ public string title
+ {
+ get { return _title; }
+ set => RaiseAndSetIfchanged(ref _title, value);
+ }
+
+ private string _statusText;
+
+ public string statusText
+ {
+ get { return _statusText; }
+ set => RaiseAndSetIfchanged(ref _statusText, value);
+ }
+
+ private bool _isTesting;
+
+ public bool IsTesting
+ {
+ get { return _isTesting; }
+ set => RaiseAndSetIfchanged(ref _isTesting, value);
+ }
+
+ private ushort coolerStatus;
+ public ushort CoolerStatus
+ {
+ get => coolerStatus;
+ set
+ {
+ RaiseAndSetIfchanged(ref coolerStatus, value);
+ }
+ }
+
+ private string tcpServerStatus;
+
+ public string TcpServerStatus
+ {
+ get { return tcpServerStatus; }
+ set { RaiseAndSetIfchanged(ref tcpServerStatus, value); }
+ }
+
+ private string tcpServerInfo = LangUtil.Get("App.NotStarted");
+
+ public string TcpServerInfo
+ {
+ get { return tcpServerInfo; }
+ set { RaiseAndSetIfchanged(ref tcpServerInfo, value); }
+ }
+ public int index { get; private set; }
+ public readonly int cellCount;
+ private readonly string chartTitle;
+ public readonly TestResultView parent;
+
+ private BaseConfig config;
+ private LiveChart chart;
+ private LiveChart multiChart;
+ public SingleCell[] cells { get; private set; }
+
+ private TcpServer tcpServer;
+ private string CountIniPath;
+
+ private DateTime? testStartTime;
+
+ private System.Timers.Timer testTimeTimer;
+
+ // 骞冲潎娓╁害
+ public List<double> tempratures = new List<double>();
+ public Dictionary<string, List<double>> detailTempratures
+ = new Dictionary<string, List<double>>();
+
+ public DataTable(TestResultView parent, int index, string title,
+ string countIniPath,
+ BaseConfig config)
+ {
+ this.CountIniPath = countIniPath;
+ this.config = config;
+ this.index = index;
+ this.parent = parent;
+ this.title = title;
+ this.cellCount = config.PositionCount;
+ this.cells = new SingleCell[cellCount];
+ this.chartTitle = this.lang("Tr.AvgTemp");
+ DataContext = this;
+ InitializeComponent();
+ mainGrid.Columns = config.PositionColumn;
+ this.chart = new LiveChart("骞冲潎娓╁害,骞冲潎娓╁害(鈩�)", false, true);
+ this.multiChart = new LiveChart(",璇︾粏娓╁害(鈩�)", true)
+ {
+ BorderThickness = new Thickness(0)
+ };
+ this.grid.Children.Add(this.chart);
+ Grid.SetRow(this.chart, 2);
+ this.chart.MouseDoubleClick += chart_MouseDoubleClick;
+
+ for (int i = 0; i < this.cellCount; i++)
+ {
+ var cellRow = (i / config.PositionColumn) + 1;
+ var cellCol = (i % config.PositionColumn) + 1;
+ var cellTitle = $"{title}-{cellRow}-{cellCol}";
+
+ var cell = new SingleCell(this, cellTitle, i, config.CellListMaxSize, countIniPath);
+ mainGrid.Children.Add(cell);
+ cells[i] = cell;
+ }
+
+ ScannerParser.Init(config.CodeParserType);
+
+ ReadCount();
+ testTimeTimer = new System.Timers.Timer();
+ testTimeTimer.Interval = 10000;
+ testTimeTimer.AutoReset = true;
+ testTimeTimer.Elapsed += TestTimeTimer_Elapsed;
+ if (!ParamSetting.ShowCoolerSetting) coolerSetting.Visibility = Visibility.Collapsed;
+ if (!ParamSetting.ShowBurnInAbort) abortBtn.Visibility = Visibility.Collapsed;
+ }
+
+ private void TestTimeTimer_Elapsed(object sender, ElapsedEventArgs e)
+ {
+ if (testStartTime == null) return;
+ var now = DateTime.Now;
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ //SetConsumeTime((now - testStartTime).Value.TotalSeconds);
+ }));
+ }
+
+ public int GetSize()
+ {
+ return this.cellCount;
+ }
+
+ public SingleCell GetSingleCell(int index)
+ {
+ return cells[index];
+ }
+
+ public void SetStatusText(string statusText)
+ {
+ this.statusText = statusText;
+ }
+
+ public void SetTemperature(double t)
+ {
+ infoTable.temperature = t;
+ tempratures.Add(t);
+ chart.AddDynamicData("骞冲潎娓╁害", "骞冲潎娓╁害(鈩�)", DateTime.Now, t);
+ }
+
+ public void SetTemperature(string name, double t)
+ {
+ //List<double> list;
+ //if (detailTempratures.ContainsKey(name))
+ //{
+ // list = detailTempratures[name];
+ //}
+ //else
+ //{
+ // list = new List<double>();
+ // detailTempratures.Add(name, list);
+ //}
+ //list.Add(t);
+
+ multiChart.AddDynamicData(name, "璇︾粏娓╁害(鈩�)", DateTime.Now, t);
+ //multiChart.AddData(name, t);
+ }
+
+ public void SetStatus(string status)
+ {
+ BurnInUI.Logger.Debug($"In Status: {status}");
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ var lastStatus = infoTable.status;
+ if (status == "preCheck")
+ {
+ BurnInUI.Logger.Debug($"In preCheck");
+ IsTesting = true;
+ return;
+ }
+ if (status == "stop")
+ {
+ IsTesting = false;
+ return;
+ }
+ if (status == "abort")
+ {
+ IsTesting = false;
+ }
+ infoTable.status = status;
+
+ //if (lastStatus != "testing" && status == "testing")
+ //{
+ // testStartTime = DateTime.Now;
+ // SetStartTime(testStartTime?.ToString("yyyy-MM-dd HH:mm:ss"));
+ // testTimeTimer.Start();
+ //}
+ //if (lastStatus == "testing" && status != "testing")
+ //{
+ // testTimeTimer.Stop();
+ // var now = DateTime.Now;
+ // infoTable.UpdateConsumeTime((now - testStartTime).Value.TotalSeconds, null);
+ // SetEndTime(now.ToString("yyyy-MM-dd HH:mm:ss"));
+ // testStartTime = null;
+ //}
+ }));
+ }
+
+ public void SetOkCount(int count)
+ {
+ infoTable.okCount = count;
+ }
+
+ public void SetNgCount(int count)
+ {
+ infoTable.ngCount = count;
+ }
+
+ public void SetStartTime(string startTime)
+ {
+ infoTable.startTimeStr = startTime;
+ }
+
+ public void SetEndTime(string endTime)
+ {
+ infoTable.endTimeStr = endTime;
+ }
+
+ public void UpdateConsumeTime(double consumeTime, double? leftTime)
+ {
+ infoTable.UpdateConsumeTime(consumeTime, leftTime);
+ }
+
+ private ChartWindow window;
+
+ private void chart_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+ /// 鎵撳紑澶氫釜娓╁害鏇茬嚎
+ if (window == null)
+ {
+ window = new ChartWindow(title);
+ window.Owner = Window.GetWindow(this);
+ window.Closed += Window_Closed;
+ window.mainGrid.Children.Add(multiChart);
+ window.Show();
+ }
+ else
+ {
+ window.Activate();
+ }
+ }
+
+ private Scanner scanner;
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ window = null;
+ }
+
+ private void SetStationGlobal_Click(object sender, RoutedEventArgs e)
+ {
+
+ }
+
+ private void StartSingleClick(object sender, RoutedEventArgs e)
+ {
+ if (IsTesting)
+ {
+ if (MsgBoxHelper2.WarnChoose(this.lang("Tr.MakeSureStopOvenTest", title)) == MessageBoxResult.OK)
+ {
+ LogHelper.Info("UI", $"鑰佸寲鐐塠{title}]鍋滄鎸夐挳鎸変笅", out _);
+ BurnInUI.Logger.Info($"鑰佸寲鐐塠{title}]鍋滄鎸夐挳鎸変笅");
+ parent.SetStartFlag(this.index, false);
+ }
+ }
+ else
+ {
+ /// 妫�鏌ユ槸鍚﹀叧闂�
+ //if (!GetDoorClose(parent.executionWrapper))
+ //{
+ // /// 娌″叧闂ㄤ笉鍏佽鍚姩
+ // MsgBoxHelper2.Warn("璇峰厛鍏抽棴鑸遍棬锛�");
+ // return;
+ //}
+
+ /// 妫�鏌ユ槸鍚︽湁鏉$爜
+ bool flag = false;
+ foreach (var cell in cells)
+ {
+ if (!string.IsNullOrEmpty(cell.sn))
+ {
+ flag = true;
+ break;
+ }
+ }
+ if (flag)
+ {
+ LogHelper.Info("UI", $"鑰佸寲鐐塠{title}]鍚姩鎸夐挳鎸変笅", out _);
+ BurnInUI.Logger.Info($"鑰佸寲鐐塠{title}]鍚姩鎸夐挳鎸変笅");
+ ClearChartData();
+ parent.SetStartFlag(this.index, true);
+ }
+ else
+ {
+ MsgBoxHelper2.Warn("璇峰厛瀹屾垚鎵爜锛�");
+ }
+ }
+ }
+
+ private void ScanWindow_Click(object sender, RoutedEventArgs e)
+ {
+ if (!parent.IsRunning)
+ {
+ MsgBoxHelper.WarnMessage(this, this.lang("Tr.StartSeqFirst"), null, MessageBoxButton.OK);
+ return;
+ }
+
+ if (scanner != null)
+ {
+ scanner.ShowDialog();
+ }
+ else
+ {
+ int rows = config.CellCount / config.PositionColumn + 1;
+ scanner = new Scanner(this.index, this.lang("Tr.ScanTitle", title), CbProduct.SelectedItem?.ToString(), mainGrid.Columns, rows)
+ {
+ Owner = Window.GetWindow(this),
+ Tag = title
+ };
+ scanner.FinishBarcode += Scanner_FinishBarcode;
+ scanner.ComplateClick += Scanner_ComplateClick; ;
+ scanner.Closed += Scanner_Closed;
+ scanner.ShowDialog();
+ }
+ }
+
+ private void Scanner_ComplateClick(object sender, RoutedEventArgs e)
+ {
+ string paramName = $"StationHMI.UUTHMI[{index}].Scanner";
+
+ parent.executionWrapper.SetStationGlobalValue<bool>(paramName, 1, true);
+ //parent.engine.Globals.SetValBoolean(paramName, 1, true);
+ }
+
+ private void Scanner_Closed(object sender, EventArgs e)
+ {
+ scanner = null;
+ }
+
+ public bool GetDoorClose(ITestExecutionWrapper wrapper)
+ {
+ return wrapper?.GetStationGlobalValue<bool>($"StationHMI.UUTHMI[{this.index}].DoorClose", 0) == true;
+ }
+
+ private void Scanner_FinishBarcode(object sender, BarcodeEventArg e)
+ {
+ if (parent.executionWrapper == null) return;
+ //if (parent.SequenceContext == null) return;
+
+ int rows = (config.CellCount / config.PositionColumn) + 1;
+ CellInfo cellInfo = ScannerParser.GetCellInfoByCode(CbProduct.SelectedItem?.ToString(), mainGrid.Columns, rows, e.positionCode);
+ string positionCode = e.positionCode, snrCode = e.snrCode;
+
+ //if (cellInfo.OvenName != this.title)
+ //{
+ // MsgBoxHelper2.Warn($"璇峰垏鎹㈣嚦 [{cellInfo.OvenName}] 鍖烘壂鐮侊紝褰撳墠涓� [{this.title}] 鍖猴紒");
+ // return;
+ //}
+
+
+ var targetTable = TestResultView.nameTables[cellInfo.OvenName];
+
+ //灏嗚鍒扮殑鏉$爜鍐欏叆鍒癝N涓�
+ string LookupStr = $"StationHMI.UUTHMI[{targetTable.index}].SN[{cellInfo.Index}]";
+ cellInfo.LookUpStr = LookupStr;
+
+ BurnInUI.Logger.Info($"PositionCode: [{e.positionCode}], SNR: [{e.snrCode}], LookUpStr: [{LookupStr}]");
+ BurnInUI.Logger.Info($"OvenName: [{cellInfo.OvenName}], CellIndex: [{cellInfo.Index}]");
+ var cell = targetTable.GetSingleCell(cellInfo.Index);
+
+ if (targetTable.GetDoorClose(parent.executionWrapper))
+ {
+ /// 鍏抽棬浜嗗氨涓嶅厑璁告竻鏉$爜
+ MsgBoxHelper2.Warn($"{targetTable.title}鐐夌敓浜т腑锛屼笉鍏佽鎿嶄綔鏉$爜");
+ //MsgBoxHelper2.Warn(this.lang("Tr.CantClearSNR"));
+ return;
+ }
+
+ if (snrCode == null)
+ {
+ var oldCellInfo = e.lastInfo;
+ var oldTable = TestResultView.nameTables[oldCellInfo.OvenName];
+ var oldCell = oldTable.GetSingleCell(oldCellInfo.Index);
+ if (oldCell.status != "hadCode")
+ {
+ throw new Exception(this.lang("Tr.PositionCantClearSNR", oldCellInfo.OriginCode));
+ }
+ // 绉婚櫎鏉$爜
+ parent.executionWrapper.SetStationGlobalValue<string>(oldCellInfo.LookUpStr, 1, "");
+ //parent.executionWrapper.CommitToDisk(false);
+
+ //parent.engine.Globals.SetValString(oldCellInfo.LookUpStr, 1, "");
+ //parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ oldCell.SetStatus("waiting");
+ oldCell.ClearSN();
+ return;
+ }
+
+ /// 娓呮帀涓婁釜鏉$爜鐨勮褰�
+ var lastSn = cell.sn;
+ if (!string.IsNullOrEmpty(lastSn))
+ {
+ Scanner.RemoveSNR(lastSn);
+ }
+
+ // 鍐欏叆鏉$爜
+ parent.executionWrapper.SetStationGlobalValue<string>(LookupStr, 1, snrCode);
+ //parent.executionWrapper.CommitToDisk(false);
+
+ cell.SetStatus("hadCode");
+ cell.sn = snrCode;
+ Scanner.InsertNewCode(snrCode, cellInfo);
+ cell.LightGreen(true, out string msg);
+ }
+
+
+ /// <summary>
+ /// 娓呯┖涓や釜鍥捐〃鏁版嵁
+ /// </summary>
+ public void ClearChartData()
+ {
+ chart.Clear();
+ multiChart.Clear();
+
+ tempratures.Clear();
+ detailTempratures.Clear();
+ }
+
+ /// <summary>
+ /// 鍚姩Tcp鏈嶅姟鍣�
+ /// </summary>
+ private void StartTcpServer()
+ {
+ var serverConfig = new ServerConfig()
+ {
+ MaxRequestLength = 1024 * 1024,
+ Port = config.PortStart + index
+ };
+ 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"));
+ }
+ 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"));
+ }
+ }
+ catch (Exception ex)
+ {
+ ChangeTcpServerStatus("ERROR", $"{ex.Message}");
+ 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;
+ });
+ }
+
+ /// <summary>
+ /// 鍋滄Tcp鏈嶅姟鍣�
+ /// </summary>
+ private void StopTcpServer()
+ {
+ try
+ {
+ tcpServer?.Stop();
+ tcpServer = null;
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ /// <summary>
+ /// 閲婃斁璧勬簮
+ /// </summary>
+ public void RelaseResource()
+ {
+ testTimeTimer?.Stop();
+ StopTcpServer();
+ }
+
+ /// <summary>
+ /// Tcp娑堟伅澶勭悊
+ /// </summary>
+ /// <param name="session"></param>
+ /// <param name="requestInfo"></param>
+ private void TcpServer_NewRequestReceived(TcpSession session, StringRequestInfo requestInfo)
+ {
+ string msg = requestInfo.Body;
+ BurnInUI.Logger.Debug($"TCP Data From {session.RemoteEndPoint}: {msg}.");
+ string[] datas_10015 = msg.Split(';');
+ int cellIndex = int.Parse(datas_10015[1]);
+
+ string strs = datas_10015[2];
+ string[] values = strs.Split(',');
+ Dispatcher.Invoke(() =>
+ {
+ GetSingleCell(cellIndex).SetInfos(new Info
+ {
+ step = values[0],
+ value = values[1],
+ limitUp = values[2],
+ limitDown = values[3],
+ unit = values[4],
+ result = values[5],
+ updateTime = values[6]
+ });
+ });
+ //session.Send("1");
+ }
+
+ public void RefreshCount(int ok, int ng)
+ {
+ infoTable.UpdateNumber(infoTable.okCount + ok, infoTable.ngCount + ng);
+
+ if (ParamSetting.ProbeByModel)
+ {
+
+ }
+ else
+ {
+ IniFileHelper.WriteIniData($"Oven_{index}", "Pass", infoTable.okCount.ToString(),
+ this.CountIniPath);
+ IniFileHelper.WriteIniData($"Oven_{index}", "Fail", infoTable.ngCount.ToString(),
+ this.CountIniPath);
+ }
+ }
+
+ /// <summary>
+ /// 璇诲彇淇濆瓨鐨勬暟鎹�
+ /// </summary>
+ public void ReadCount()
+ {
+ try
+ {
+ int ok = Convert.ToInt32(IniFileHelper.ReadIniData($"Oven_{index}", "Pass", "", CountIniPath));
+ int ng = Convert.ToInt32(IniFileHelper.ReadIniData($"Oven_{index}", "Fail", "", CountIniPath));
+ infoTable.UpdateNumber(ok, ng);
+ }
+ catch (Exception ex)
+ {
+ //do nothing
+ }
+ }
+
+ /// <summary>
+ /// 璁℃暟娓呴浂
+ /// </summary>
+ public void ClearNumber()
+ {
+ infoTable.UpdateNumber(0, 0);
+ IniFileHelper.WriteIniData($"Oven_{index}", "Pass", infoTable.okCount.ToString(),
+ this.CountIniPath);
+ IniFileHelper.WriteIniData($"Oven_{index}", "Fail", infoTable.ngCount.ToString(),
+ this.CountIniPath);
+ }
+
+ private void UserControl_Loaded(object sender, RoutedEventArgs e)
+ {
+ StartTcpServer();
+ Loaded -= UserControl_Loaded;
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ StartTcpServer();
+ }
+
+ public void SaveTempFile(string filePath)
+ {
+ try
+ {
+ FileInfo fi = new FileInfo(filePath);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = string.Join(",", detailTempratures.Keys) + "," + this.lang("Tr.AvgTemp");
+ sw.WriteLine(title);
+
+ for (int i = 0; i < tempratures.Count; i++)
+ {
+ string line = "";
+ foreach (string key in detailTempratures.Keys)
+ {
+ if (detailTempratures[key] == null || detailTempratures[key].Count <= i)
+ {
+ line += ",";
+ }
+ else
+ {
+ line += $"{detailTempratures[key][i]},";
+ }
+ }
+ line += tempratures[i];
+ sw.WriteLine(line);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ }
+ }
+
+ public void SetProductSource(List<string> productSource)
+ {
+ CbProduct.ItemsSource = productSource;
+ }
+
+ public void SetCurrentProduct(string currentProduct)
+ {
+ CbProduct.SelectedItem = currentProduct;
+ }
+
+ private void CbProduct_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (e.AddedItems.Count > 0)
+ {
+ var str = e.AddedItems[0];
+ parent.SetOvenProduct(index, str.ToString());
+ }
+ else
+ {
+ parent.SetOvenProduct(index, "");
+ }
+
+ foreach (var cell in cells)
+ {
+ cell.RefreshProbe();
+ cell.RefreshCharts();
+ }
+ }
+
+ public void ClearCellData()
+ {
+ foreach (var cell in cells)
+ {
+ cell.ClearChart();
+ }
+ }
+
+ //public void ClearElectricData()
+ //{
+ // foreach (var cell in cells)
+ // {
+ // cell.ClearElectricData();
+ // }
+ //}
+
+ //public void ClearVData()
+ //{
+ // foreach (var cell in cells)
+ // {
+ // cell.ClearVData();
+ // }
+ //}
+
+ //public void ClearWaterData()
+ //{
+ // foreach (var cell in cells)
+ // {
+ // cell.ClearWaterData();
+ // }
+ //}
+
+ private void Button_Click_1(object sender, RoutedEventArgs e)
+ {
+ ScannerSetting setting = new ScannerSetting()
+ {
+ Owner = Window.GetWindow(this)
+ };
+ setting.Open(true, this.title);
+ }
+
+ private void Manual_Cooler_Opt(object sender, RoutedEventArgs e)
+ {
+ //var btn = (Button)sender;
+ //var target = CoolerStatus == 2 ? 0 : 2;
+ //if (MsgBoxHelper2.WarnChoose($"纭畾瑕佽繘琛寋btn.Content}鍚楋紵") == MessageBoxResult.OK)
+ //{
+ // if (S7Context.WriteData("1", $"Oven{index + 1}_CoolerStatus", (ushort)target, out string msg))
+ // {
+ // CoolerStatus = (ushort)target;
+ // ToastHelper.Success("Success");
+ // }
+ // else
+ // {
+ // ToastHelper.Error($"{msg}");
+ // }
+ //}
+ if (parent.IsRunning)
+ {
+ MsgBoxHelper2.Warn(this.lang("Tr.CantOptCooler"));
+ return;
+ }
+ var columns = mainGrid.Columns;
+ var window = new CoolerStatus(this.index, columns, title + this.lang("Tr.CoolerSetting"))
+ {
+
+ Owner = Window.GetWindow(this)
+ };
+ window.ShowDialog();
+ }
+
+ private void ClearAllSnr_Click(object sender, RoutedEventArgs e)
+ {
+ if (GetDoorClose(parent.executionWrapper))
+ {
+ /// 鍏抽棬浜嗗氨涓嶅厑璁告竻鏉$爜
+ MsgBoxHelper2.Warn(this.lang("Tr.CantClearSNR"));
+ return;
+ }
+
+ if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), LangUtil.Get("Tr.MakeSureClearAllSNR")) == MessageBoxResult.OK)
+ {
+ try
+ {
+ ClearAllSN();
+ ToastHelper.Success(LangUtil.Get("App.DeleteSuccess"));
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("ClearAllSnr_Click Error.", ex);
+ MsgBoxHelper.Error(Window.GetWindow(this), ex.Message);
+ }
+ }
+ }
+
+ public void ClearAllSN()
+ {
+ for (int i = 0; i < this.cellCount; i++)
+ {
+ ClearCellSN(i);
+ }
+ }
+
+ public void TryClearCellSN(int cellIndex)
+ {
+ if (GetDoorClose(parent.executionWrapper))
+ {
+ MsgBoxHelper.Error(Window.GetWindow(this), this.lang("Tr.CantClearSNR"));
+ return;
+ }
+ ClearCellSN(cellIndex);
+ }
+
+ private void ClearCellSN(int index)
+ {
+ var cell = GetSingleCell(index);
+ string LookupStr = $"StationHMI.UUTHMI[{this.index}].SN[{index}]";
+ var lastSN = cell.sn;
+ cell.SetStatus("waiting");
+
+ parent.executionWrapper.SetStationGlobalValue<string>(LookupStr, 1, "");
+ //parent.executionWrapper.CommitToDisk(false);
+
+ //parent.engine.Globals.SetValString(LookupStr, 1, "");
+ //parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ if (!string.IsNullOrEmpty(lastSN)) Scanner.RemoveSNR(lastSN);
+ cell.ClearSN();
+ }
+
+ private void Abort_Click(object sender, RoutedEventArgs e)
+ {
+ if (!parent.IsRunning)
+ {
+ MsgBoxHelper.WarnMessage(this, this.lang("Tr.StartSeqFirst"), null, MessageBoxButton.OK);
+ return;
+ }
+
+ //string key = $"StationState.Start[{this.index}]";
+ //if (parent.executionWrapper?.GetStationGlobalValue<bool>(key, 0) == true)
+ //{
+ // MsgBoxHelper2.Warn("娴嬭瘯鍚姩涓紝涓嶅厑璁窤bort");
+ // return;
+ //}
+ var win = new RequirePasswordByUser("admin")
+ {
+ Owner = Window.GetWindow(this)
+ };
+ if (win.ShowDialog() != true)
+ {
+ return;
+ }
+
+ if (MsgBoxHelper2.WarnChoose("璇风‘璁よ�佸寲浠撳湪瀹夊叏娓╁害锛屾按鍐锋満鍚规按瀹屾垚锛屽崟鍑籓K鎸夐挳浠撲綅鍥炲埌鍒濆鍖栫姸鎬�") != MessageBoxResult.OK)
+ {
+ return;
+ }
+ LogHelper.Info("UI", $"{title} Abort鎸夐挳鎸変笅", out _);
+ BurnInUI.Logger.Info($"{title} Abort鎸夐挳鎸変笅");
+ string key = $"StationHMI.UUTHMI[{this.index}].Abort";
+ parent.executionWrapper?.SetStationGlobalValue(key, 0, true);
+ }
+ }
+}
diff --git a/Plugin.BurnIn/InfoTable.xaml b/Plugin.BurnIn/InfoTable.xaml
new file mode 100644
index 0000000..8d6ae8a
--- /dev/null
+++ b/Plugin.BurnIn/InfoTable.xaml
@@ -0,0 +1,92 @@
+锘�<UserControl x:Class="Plugin.BurnIn.InfoTable"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+xmlns:pw="https://opensource.panuon.com/wpf"
+xmlns:pu="https://opensource.panuon.com/wpf-ui"
+xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <Style TargetType="Label">
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="FontWeight" Value="Bold"/>
+ </Style>
+ <Style TargetType="TextBox">
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Setter Property="FontWeight" Value="Bold"/>
+ <Setter Property="IsReadOnly" Value="True"/>
+ <Setter Property="BorderThickness" Value="0"/>
+ </Style>
+ </UserControl.Resources>
+ <Grid x:Name="infoGrid" Grid.Row="0" dp:GridHelper.InnerBorder="1"
+ dp:GridHelper.InnerBorderIgnore="Top,Right,Bottom">
+ <Grid.RowDefinitions>
+ <RowDefinition/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="1.5*"/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="1.5*"/>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition Width="2*"/>
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource Tr.Temperature}"/>
+ <Label Grid.Row="0" Grid.Column="1" Background="{DynamicResource CellValue}" Content="{Binding temperatureStr}"/>
+ <Label Grid.Row="0" Grid.Column="2" Content="{DynamicResource Tr.Status}"/>
+ <Label Grid.Row="0" Grid.Column="3" Content="{Binding statusStr}">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Setter Property="FontWeight" Value="Bold"/>
+ <Setter Property="VerticalContentAlignment" Value="Center"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="ok">
+ <Setter Property="Background" Value="#FF0F8853"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ng">
+ <Setter Property="Background" Value="#fd6b6d"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkInFailed">
+ <Setter Property="Background" Value="#ffac00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkIn">
+ <Setter Property="Background" Value="#FF00E2FF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="testing">
+ <Setter Property="Background" Value="#1296db"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="waiting">
+ <Setter Property="Background" Value="#A5A5A5"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="alert">
+ <Setter Property="Background" Value="#e04733"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ready">
+ <Setter Property="Background" Value="#FF08FF00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="abort">
+ <Setter Property="Background" Value="Black"/>
+ <Setter Property="Foreground" Value="White"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+ <Label Grid.Row="0" Grid.Column="4" Content="{DynamicResource Tr.Count}"/>
+ <Label Grid.Row="0" Grid.Column="5" Background="{DynamicResource CellValue}" Content="{Binding countStr}"/>
+
+ <Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource Tr.StartTime}"/>
+ <Label Grid.Row="1" Grid.Column="1" Background="{DynamicResource CellValue}" Content="{Binding startTimeStr}"/>
+ <Label Grid.Row="1" Grid.Column="2" Content="{DynamicResource Tr.ElapsedTime}"/>
+ <Label Grid.Row="1" Grid.Column="3" Background="{DynamicResource CellValue}" Content="{Binding consumeTimeStr}"/>
+ <Label Grid.Row="1" Grid.Column="4" Content="{DynamicResource Tr.EstimatedEndTime}"/>
+ <Label Grid.Row="1" Grid.Column="5" Background="{DynamicResource CellValue}" Content="{Binding endTimeStr}"/>
+ </Grid>
+</UserControl>
diff --git a/Plugin.BurnIn/InfoTable.xaml.cs b/Plugin.BurnIn/InfoTable.xaml.cs
new file mode 100644
index 0000000..83f3472
--- /dev/null
+++ b/Plugin.BurnIn/InfoTable.xaml.cs
@@ -0,0 +1,203 @@
+锘縰sing Plugin.BurnIn.Constant;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// InfoTable.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class InfoTable : UserControl, INotifyPropertyChanged
+ {
+
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private double _temperature;
+ public double temperature
+ {
+ get => _temperature;
+ set
+ {
+ RaiseAndSetIfchanged(ref _temperature, value);
+ RaisePropertyChanged("temperatureStr");
+ }
+ }
+
+ public string temperatureStr
+ {
+ get => $"{_temperature.ToString("f2")}鈩�";
+ }
+
+ private string _status;
+ public string status
+ {
+ get => _status;
+ set
+ {
+ RaiseAndSetIfchanged(ref _status, value);
+ RaisePropertyChanged("statusStr");
+ }
+ }
+
+ public string statusStr
+ {
+ get => status != null && CommonStatus.STATUS_MAP.ContainsKey(status) ? CommonStatus.STATUS_MAP[status] : "";
+ }
+
+ private int _okCount;
+ public int okCount
+ {
+ get => _okCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref _okCount, value);
+ }
+ }
+
+ private int _ngCount;
+
+ public int ngCount
+ {
+ get => _ngCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref _ngCount, value);
+ }
+ }
+
+ private int _allCount;
+
+ public int allCount
+ {
+ get => _allCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref _allCount, value);
+ }
+ }
+
+ public string countStr
+ {
+ get => $"OK:{okCount},NG:{ngCount},ALL:{allCount}";
+ }
+
+ private string _startTimeStr;
+ public string startTimeStr
+ {
+ get => _startTimeStr;
+ set
+ {
+ RaiseAndSetIfchanged(ref _startTimeStr, value);
+ }
+ }
+
+ private double _consumeTime;
+ public double consumeTime
+ {
+ get => _consumeTime;
+ set
+ {
+ RaiseAndSetIfchanged(ref _consumeTime, value);
+ }
+ }
+
+ private double? _leftTime;
+ public double? leftTime
+ {
+ get => _leftTime;
+ set
+ {
+ RaiseAndSetIfchanged(ref _leftTime, value);
+ }
+ }
+
+ public string consumeTimeStr
+ {
+ get
+ {
+ var str1 = ConvertDurtion(consumeTime);
+ if (leftTime != null)
+ {
+ str1 += $"/{ConvertDurtion(leftTime.Value)}";
+ }
+ return str1;
+ }
+ }
+
+ private string ConvertDurtion(double seconds)
+ {
+ if (seconds <= 0)
+ {
+ return "0s";
+ }
+ if (seconds <= 60)
+ {
+ return $"{seconds.ToString("f2")}s";
+ }
+ else if (seconds <= 3600)
+ {
+ var min = Math.Floor(seconds / 60);
+ seconds = seconds % 60;
+ if (seconds > 0)
+ {
+ return $"{min}m{seconds.ToString("f2")}s";
+ }
+ return $"{min}m";
+ }
+ else
+ {
+ var hour = Math.Floor(seconds / 3600);
+ var min = Math.Floor((seconds % 3600) / 60);
+ seconds = seconds % 60;
+ if (seconds > 0)
+ {
+ return $"{hour}h{min}m{seconds.ToString("f2")}s";
+ }
+ return $"{hour}h{min}m";
+ }
+ }
+
+ private string _endTimeStr;
+
+ public string endTimeStr
+ {
+ get => _endTimeStr;
+ set => RaiseAndSetIfchanged(ref _endTimeStr, value);
+ }
+
+ public void UpdateNumber(int ok, int ng)
+ {
+ this._okCount = ok;
+ this._ngCount = ng;
+ this._allCount = this._okCount + this._ngCount;
+ RaisePropertyChanged("countStr");
+ }
+
+ public void UpdateConsumeTime(double consumeTime, double? leftTime)
+ {
+ this.consumeTime = consumeTime;
+ this.leftTime = leftTime;
+ RaisePropertyChanged("consumeTimeStr");
+ }
+
+ public InfoTable()
+ {
+ this.DataContext = this;
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Plugin.BurnIn/InfoWindow.xaml b/Plugin.BurnIn/InfoWindow.xaml
new file mode 100644
index 0000000..949678a
--- /dev/null
+++ b/Plugin.BurnIn/InfoWindow.xaml
@@ -0,0 +1,117 @@
+锘�<pu:WindowX x:Class="Plugin.BurnIn.InfoWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
+ InteropOwnersMask="False"
+ Topmost="False"
+ Loaded="Window_Loaded"
+ SizeToContent="Height"
+ Unloaded="Window_Unloaded"
+ SizeChanged="Window_SizeChanged"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ Title="{Binding title}" Width="800" Height="825">
+ <Grid x:Name="mainGrid">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="500"/>
+ <RowDefinition Height="*"/>
+ <RowDefinition Height="*"/>
+ <RowDefinition Height="*"/>
+ <RowDefinition Height="25"/>
+ </Grid.RowDefinitions>
+ <DataGrid ItemsSource="{Binding dataSource}" AutoGenerateColumns="False"
+ CanUserAddRows="False"
+ CanUserDeleteRows="False"
+ IsReadOnly="True"
+ ColumnWidth="*"
+ VirtualizingPanel.IsContainerVirtualizable="True"
+ VirtualizingPanel.IsVirtualizing="True"
+ VirtualizingStackPanel.VirtualizationMode="Recycling"
+ FontSize="16">
+ <DataGrid.Resources>
+ <Style TargetType="ScrollBar" BasedOn="{StaticResource ScrollStyle_Mobile}"/>
+ </DataGrid.Resources>
+ <DataGrid.Columns>
+ <!--<DataGridTemplateColumn Header="#" CanUserResize="False" Width="Auto">
+ <DataGridTemplateColumn.CellTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource rowNumber},
+RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridRow},AncestorLevel=1}}"/>
+ </DataTemplate>
+ </DataGridTemplateColumn.CellTemplate>
+ </DataGridTemplateColumn>-->
+ <DataGridTextColumn Binding="{Binding step}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Name}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Binding="{Binding value}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Value}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Binding="{Binding limitUp}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.LimitUp}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Binding="{Binding limitDown}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.LimitDown}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Binding="{Binding unit}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Unit}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Binding="{Binding result}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.Result}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ <DataGridTextColumn Binding="{Binding updateTime}">
+ <DataGridTextColumn.Header>
+ <TextBlock Text="{DynamicResource Test.TestTime}"/>
+ </DataGridTextColumn.Header>
+ </DataGridTextColumn>
+ </DataGrid.Columns>
+ </DataGrid>
+
+ <Grid Background="#f1eded" Grid.Row="4">
+ <DockPanel>
+ <StackPanel DockPanel.Dock="Right" Orientation="Horizontal" Margin="0,0,30,0">
+ <Label Padding="0" FontSize="12"
+VerticalAlignment="Center"
+VerticalContentAlignment="Center" Content="{DynamicResource Ts.ProbeCount}"/>
+ <Label Padding="0" FontSize="12" Margin="0,0,15,0"
+VerticalAlignment="Center"
+VerticalContentAlignment="Center" Content="{Binding ProbeCount}"/>
+
+
+ <Label x:Name="alarmLabel" Padding="0" FontSize="12"
+VerticalAlignment="Center"
+VerticalContentAlignment="Center" Content="{DynamicResource Ts.ProbeAlarmCount}"/>
+ <Label x:Name="alarmValue" Padding="0" FontSize="12"
+VerticalAlignment="Center"
+VerticalContentAlignment="Center" Content="{Binding ProbeWarn}"/>
+
+ <Button Style="{StaticResource LinkButton}" Margin="10,0,0,0" Click="Button_Click" >娓呯┖</Button>
+ </StackPanel>
+
+ <Label x:Name="probeCountAlarm" Visibility="Collapsed" DockPanel.Dock="Left" Padding="30,0" FontSize="12" Foreground="Red"
+VerticalAlignment="Center"
+VerticalContentAlignment="Center" Content="{DynamicResource Ts.ProbeAlarm}"/>
+ </DockPanel>
+ </Grid>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.BurnIn/InfoWindow.xaml.cs b/Plugin.BurnIn/InfoWindow.xaml.cs
new file mode 100644
index 0000000..afc7eb1
--- /dev/null
+++ b/Plugin.BurnIn/InfoWindow.xaml.cs
@@ -0,0 +1,176 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.Util;
+using Panuon.WPF.UI;
+using Plugin.BurnIn.Model;
+using System.Collections.ObjectModel;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// InfoWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class InfoWindow : WindowX
+ {
+
+ private string _title;
+ public string title
+ {
+ get => _title;
+ set => Set(ref _title, value);
+ }
+
+ private ObservableCollection<Info> _dataSource;
+
+ public ObservableCollection<Info> dataSource
+ {
+ get => _dataSource == null ? new ObservableCollection<Info>() : _dataSource;
+ set => Set(ref _dataSource, value);
+ }
+ private LiveChart waterChart;
+ private LiveChart electricChart;
+ private LiveChart vChart;
+
+ //public InfoWindow(string title, ObservableCollection<Info> infos, Chart waterChart, Chart electricChart, Chart vChart, int probeCount, int probeWarn)
+ //{
+ // this.title = title;
+ // this.dataSource = infos;
+ // DataContext = this;
+ // Topmost = false;
+ // this.ProbeWarn = probeWarn;
+ // InitializeComponent();
+
+
+ // UpdateProbeCount(probeCount,probeWarn);
+
+ // if (waterChart != null)
+ // {
+ // this.waterChart = waterChart;
+ // mainGrid.Children.Add(waterChart);
+ // Grid.SetRow(waterChart, 1);
+ // }
+
+ // this.electricChart = electricChart;
+ // mainGrid.Children.Add(electricChart);
+ // Grid.SetRow(electricChart, 2);
+
+
+ // this.vChart = vChart;
+ // mainGrid.Children.Add(vChart);
+ // Grid.SetRow(vChart, 3);
+ //}
+
+ public InfoWindow(string title, ObservableCollection<Info> infos, LiveChart[] charts, int probeCount, int probeWarn)
+ {
+ this.title = title;
+ this.dataSource = infos;
+ DataContext = this;
+ Topmost = false;
+ this.ProbeWarn = probeWarn;
+ InitializeComponent();
+
+
+ UpdateProbeCount(probeCount, probeWarn);
+ int row = 1;
+ foreach (var chart in charts)
+ {
+ if (chart == null) return;
+ mainGrid.Children.Add(chart);
+ Grid.SetRow(chart, row++);
+ }
+
+ //if (waterChart != null)
+ //{
+ // this.waterChart = waterChart;
+ // mainGrid.Children.Add(waterChart);
+ // Grid.SetRow(waterChart, 1);
+ //}
+
+ //this.electricChart = electricChart;
+ //mainGrid.Children.Add(electricChart);
+ //Grid.SetRow(electricChart, 2);
+
+ //this.vChart = vChart;
+ //mainGrid.Children.Add(vChart);
+ //Grid.SetRow(vChart, 3);
+ }
+
+ public event EventHandler ClearProbeCountEvent;
+
+ private int probeCount;
+ public int ProbeCount
+ {
+ get => probeCount;
+ set
+ {
+ Set(ref probeCount, value);
+ }
+ }
+
+ public int ProbeWarn
+ {
+ get;
+ set;
+ }
+
+ public void UpdateProbeCount(int count, int warn)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ ProbeCount = count;
+ ProbeWarn = warn;
+
+ if (ProbeWarn < 0)
+ {
+ alarmLabel.Visibility = Visibility.Collapsed;
+ alarmValue.Visibility = Visibility.Collapsed;
+ }
+ else
+ {
+ probeCountAlarm.Visibility = (ProbeCount >= ProbeWarn) ? Visibility.Visible : Visibility.Collapsed;
+ }
+ });
+ }
+
+ public void UpdateSource(ObservableCollection<Info> infos)
+ {
+ this.dataSource = infos;
+ }
+
+ private void Window_Loaded(object sender, RoutedEventArgs e)
+ {
+ DataContext = this;
+ }
+
+ private void Window_Unloaded(object sender, RoutedEventArgs e)
+ {
+ DataContext = null;
+ }
+
+ protected override void OnClosed(EventArgs e)
+ {
+ waterChart = null;
+ electricChart = null;
+ vChart = null;
+ mainGrid.Children.Clear();
+ base.OnClosed(e);
+ }
+
+ private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
+ {
+ //if (electricChart != null)
+ //{
+ // electricChart.Height = this.ActualHeight * 0.3;
+ //}
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ if (MsgBoxHelper.WarnMessage(this, this.lang("Ts.MakeSureToClearProbeCount")) == MessageBoxResult.OK)
+ {
+ ClearProbeCountEvent?.Invoke(this, null);
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/ManualDebugWindow.xaml b/Plugin.BurnIn/ManualDebugWindow.xaml
new file mode 100644
index 0000000..ba5a019
--- /dev/null
+++ b/Plugin.BurnIn/ManualDebugWindow.xaml
@@ -0,0 +1,21 @@
+锘�<pu:WindowX x:Class="Plugin.BurnIn.ManualDebugWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ xmlns:sb="clr-namespace:Util.SB;assembly=Util.ManualDebug"
+ Title="ManualDebugWindow"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ Style="{StaticResource ModalWindow}"
+ Closing="Window_Closing"
+ WindowStartupLocation="CenterScreen"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ Height="1000" Width="900">
+ <Grid x:Name="sb">
+ <sb:ManualDebug OvenName="{Binding OvenName,Mode=OneWay}"
+ CellName="{Binding CellName,Mode=OneWay}"
+ OvenIndex="{Binding OvenIndex,Mode=OneWay}"
+ CellIndex="{Binding CellIndex,Mode=OneWay}"/>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.BurnIn/ManualDebugWindow.xaml.cs b/Plugin.BurnIn/ManualDebugWindow.xaml.cs
new file mode 100644
index 0000000..3118483
--- /dev/null
+++ b/Plugin.BurnIn/ManualDebugWindow.xaml.cs
@@ -0,0 +1,93 @@
+锘縰sing HMI.Util;
+using Panuon.WPF.UI;
+using System.ComponentModel;
+using System.IO;
+using System.Windows;
+using Util.SB;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// ManualDebugWindow.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ManualDebugWindow : WindowX
+ {
+
+ private ManualDebug debug;
+
+ public ManualDebugWindow(string seqPath, string modelPath)
+ {
+ DataContext = this;
+ InitializeComponent();
+ debug = (ManualDebug)sb.Children[0];
+ ReadBtns();
+ //List<BtnConfig> settings = new List<BtnConfig> { new BtnConfig { Title = "涓婄數婵�娲�", Name = "Active" } };
+ debug.seqPath = seqPath;
+ debug.modelPath = modelPath;
+ }
+
+ private string ovenName;
+ public string OvenName
+ {
+ get => ovenName;
+ set
+ {
+ Set(ref ovenName, value);
+ }
+ }
+
+ private string cellName;
+ public string CellName
+ {
+ get => cellName;
+ set
+ {
+ Set(ref cellName, value);
+ }
+ }
+
+ private int ovenIndex;
+ public int OvenIndex
+ {
+ get => ovenIndex;
+ set
+ {
+ Set(ref ovenIndex, value);
+ }
+ }
+
+ private int cellIndex;
+ public int CellIndex
+ {
+ get => cellIndex;
+ set
+ {
+ Set(ref cellIndex, value);
+ }
+ }
+
+ private void ReadBtns()
+ {
+ string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Settings.ini");
+ var map = IniFileHelper.GetKeyValuesBySection(path, "Btns");
+ List<BtnConfig> settings = new List<BtnConfig>();
+ foreach (var kv in map)
+ {
+ settings.Add(new BtnConfig { Title = kv.Key, Name = kv.Value });
+ }
+ debug.RefreshButtons(settings);
+ }
+
+ private void Window_Closing(object sender, CancelEventArgs e)
+ {
+ if (MessageBox.Show("纭畾瑕佸叧闂悧锛�", "鎻愮ず", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
+ {
+ debug.Stop();
+ }
+ else
+ {
+ e.Cancel = true;
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Model/BaseConfig.cs b/Plugin.BurnIn/Model/BaseConfig.cs
new file mode 100644
index 0000000..631a81c
--- /dev/null
+++ b/Plugin.BurnIn/Model/BaseConfig.cs
@@ -0,0 +1,198 @@
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Manager;
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Runtime.CompilerServices;
+
+namespace Plugin.BurnIn.Model
+{
+ public class BaseConfig
+ {
+ private static Hashtable customConfig = (Hashtable)ConfigurationManager.GetSection("TestResultConfig");
+
+ private string GetValue([CallerMemberName] string propertyName = null)
+ {
+ return (customConfig != null && customConfig.ContainsKey(propertyName)) ? customConfig[propertyName].ToString() : null;
+ }
+
+ /// <summary>
+ /// 棣栭〉甯冨眬琛屾暟
+ /// </summary>
+ private int row = 1;
+ public int Row
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? row : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(Row)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 棣栭〉甯冨眬鍒楁暟
+ /// </summary>
+ private int column = 2;
+ public int Column
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? column : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(Column)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鐐夋暟 -1 灏辨槸row*column
+ /// </summary>
+ private int cellCount = -1;
+ public int CellCount
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? cellCount : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(CellCount)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鐐逛綅鍒楁暟
+ /// </summary>
+ private int positionColumn = 6;
+ public int PositionColumn
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? positionColumn : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(PositionColumn)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 姣忎釜鐐夊瓙鐨勭偣浣嶆暟
+ /// </summary>
+ private int positionCount = 54;
+ public int PositionCount
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? positionCount : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(PositionCount)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鏇茬嚎鏈�澶氫繚瀛樺灏戞暟鎹�
+ /// </summary>
+ private int maxSize = 10000;
+ public int MaxSize
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? maxSize : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(MaxSize)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鍥捐〃鍒锋柊棰戠巼 ms
+ /// </summary>
+ private int refreshInterval = 500;
+ public int RefreshInterval
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? refreshInterval : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(RefreshInterval)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鐐夊瓙鍚嶇О
+ /// </summary>
+ private string nameStr = "A,B,C,D,E,F,G";
+ public string NameStr
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? nameStr : data;
+ }
+ set
+ {
+ customConfig[nameof(NameStr)] = value;
+ }
+ }
+
+ /// <summary>
+ /// 绌翠綅Step鍒楄〃鏈�澶у閲�
+ /// </summary>
+ private int cellListMaxSize = 10000;
+ public int CellListMaxSize
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? cellListMaxSize : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(CellListMaxSize)] = value;
+ }
+ }
+
+ private int portStart = 6660;
+ public int PortStart
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? portStart : int.Parse(data);
+ }
+ set
+ {
+ customConfig[nameof(PortStart)] = value;
+ }
+ }
+
+ private string codeParserType;
+ public string CodeParserType
+ {
+ get
+ {
+ var data = GetValue();
+ return data == null ? codeParserType : data.ToString();
+ }
+ }
+
+ public bool testing = false;
+ }
+}
diff --git a/Plugin.BurnIn/Model/BaseModel.cs b/Plugin.BurnIn/Model/BaseModel.cs
new file mode 100644
index 0000000..e7cba9c
--- /dev/null
+++ b/Plugin.BurnIn/Model/BaseModel.cs
@@ -0,0 +1,21 @@
+锘縰sing System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace Plugin.BurnIn.Model
+{
+ public class BaseModel : INotifyPropertyChanged
+ {
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Model/CellInfo.cs b/Plugin.BurnIn/Model/CellInfo.cs
new file mode 100644
index 0000000..53b502d
--- /dev/null
+++ b/Plugin.BurnIn/Model/CellInfo.cs
@@ -0,0 +1,17 @@
+锘縩amespace Plugin.BurnIn.Model
+{
+ public class CellInfo
+ {
+ public string OriginCode { get; set; }
+ public string MachineName { get; set; }
+ /// <summary>
+ /// 鐐夊悕
+ /// </summary>
+ public string OvenName { get; set; }
+ /// <summary>
+ /// 绌翠綅涓嬫爣
+ /// </summary>
+ public int Index { get; set; }
+ public string LookUpStr { get; set; }
+ }
+}
diff --git a/Plugin.BurnIn/Model/DataTableModel.cs b/Plugin.BurnIn/Model/DataTableModel.cs
new file mode 100644
index 0000000..caf55ff
--- /dev/null
+++ b/Plugin.BurnIn/Model/DataTableModel.cs
@@ -0,0 +1,7 @@
+锘縩amespace Plugin.BurnIn.Model
+{
+ public class DataTableModel : BaseModel
+ {
+
+ }
+}
diff --git a/Plugin.BurnIn/Model/Info.cs b/Plugin.BurnIn/Model/Info.cs
new file mode 100644
index 0000000..f4259ec
--- /dev/null
+++ b/Plugin.BurnIn/Model/Info.cs
@@ -0,0 +1,69 @@
+锘縩amespace Plugin.BurnIn.Model
+{
+ public class Info : BaseModel
+ {
+ private string _step;
+
+ public string step
+ {
+ get => _step;
+
+ set => RaiseAndSetIfchanged(ref _step, value);
+ }
+
+ private string _value;
+
+ public string value
+ {
+ get => _value;
+
+ set => RaiseAndSetIfchanged(ref _value, value);
+ }
+
+ private string _unit;
+
+ public string unit
+ {
+ get => _unit;
+
+ set => RaiseAndSetIfchanged(ref _unit, value);
+ }
+
+ private string _result;
+
+ public string result
+ {
+ get => _result;
+
+ set => RaiseAndSetIfchanged(ref _result, value);
+ }
+
+ private string _limitDown;
+
+ public string limitDown
+ {
+ get => _limitDown;
+
+ set => RaiseAndSetIfchanged(ref _limitDown, value);
+ }
+
+ private string _limitUp;
+
+ public string limitUp
+ {
+ get => _limitUp;
+
+ set => RaiseAndSetIfchanged(ref _limitUp, value);
+ }
+
+ private string _updateTime;
+
+ public string updateTime
+ {
+ get => _updateTime;
+
+ set => RaiseAndSetIfchanged(ref _updateTime, value);
+ }
+
+ }
+}
diff --git a/Plugin.BurnIn/Model/ScannerConfig.cs b/Plugin.BurnIn/Model/ScannerConfig.cs
new file mode 100644
index 0000000..986e041
--- /dev/null
+++ b/Plugin.BurnIn/Model/ScannerConfig.cs
@@ -0,0 +1,34 @@
+锘縰sing HMI.Util;
+using System;
+using System.IO.Ports;
+
+namespace Plugin.BurnIn.Model
+{
+ public class ScannerConfig
+ {
+ public string PortName { get; set; }
+
+ public int BaudRate { get; set; }
+ public Parity Parity { get; set; } = Parity.None;
+ public int DataBits { get; set; }
+ public StopBits StopBits { get; set; } = StopBits.One;
+ public Handshake Handshake { get; set; } = Handshake.None;
+ public bool DtrEnable { get; set; } = true;
+ public bool RtsEnable { get; set; } = true;
+
+
+ public static ScannerConfig ReadFromIni(string iniFile, string section)
+ {
+ var res = new ScannerConfig();
+ res.PortName = IniFileHelper.ReadIniData(section, "PortName", "", iniFile);
+ res.BaudRate = int.Parse(IniFileHelper.ReadIniData(section, "BaudRate", "0", iniFile));
+ res.Parity = (Parity)Enum.Parse(typeof(Parity), IniFileHelper.ReadIniData(section, "Parity", "None", iniFile));
+ res.DataBits = int.Parse(IniFileHelper.ReadIniData(section, "DataBits", "0", iniFile));
+ res.StopBits = (StopBits)Enum.Parse(typeof(StopBits), IniFileHelper.ReadIniData(section, "StopBits", "One", iniFile));
+ res.Handshake = (Handshake)Enum.Parse(typeof(Handshake), IniFileHelper.ReadIniData(section, "Handshake", "None", iniFile));
+ res.DtrEnable = bool.Parse(IniFileHelper.ReadIniData(section, "DtrEnable", "true", iniFile));
+ res.RtsEnable = bool.Parse(IniFileHelper.ReadIniData(section, "RtsEnable", "true", iniFile));
+ return res;
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Model/TcpServer.cs b/Plugin.BurnIn/Model/TcpServer.cs
new file mode 100644
index 0000000..0c11084
--- /dev/null
+++ b/Plugin.BurnIn/Model/TcpServer.cs
@@ -0,0 +1,59 @@
+锘縰sing SuperSocket.SocketBase;
+using SuperSocket.SocketBase.Protocol;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Plugin.BurnIn.Model
+{
+ public class DTReceiveFilter : ReceiveFilterBase<StringRequestInfo>
+ {
+ public override StringRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
+ {
+ rest = 0;
+ int i = offset;
+ List<byte> bytes = new List<byte>();
+ while (i < readBuffer.Length)
+ {
+ byte b = readBuffer[i++];
+ if (b == '\n')
+ {
+ break;
+ }
+ bytes.Add(b);
+ }
+ byte[] arr = bytes.ToArray();
+ return new StringRequestInfo(DateTime.Now.ToString("yyyyMMddHHmmssfff"), Encoding.UTF8.GetString(arr), null);//sb.ToString()
+ }
+ }
+
+ public class StringParser : IRequestInfoParser<StringRequestInfo>
+ {
+
+ public StringRequestInfo ParseRequestInfo(string source)
+ {
+ return new StringRequestInfo(DateTime.Now.ToString("yyyyMMddHHmmssfff"), source, null);
+ }
+ }
+
+ //public class TcpServer : AppServer<TcpSession>
+ //{
+ // public TcpServer() : base(new DefaultReceiveFilterFactory<DTReceiveFilter, StringRequestInfo>())
+ // {
+
+ // }
+ //}
+
+ public class TcpServer : AppServer<TcpSession>
+ {
+ public TcpServer() : base(new TerminatorReceiveFilterFactory("\n", Encoding.UTF8, new StringParser()))
+ {
+
+ }
+ }
+
+ public class TcpSession : AppSession<TcpSession, StringRequestInfo>
+ {
+
+ }
+}
diff --git a/Plugin.BurnIn/Plugin.BurnIn.csproj b/Plugin.BurnIn/Plugin.BurnIn.csproj
new file mode 100644
index 0000000..3be23dc
--- /dev/null
+++ b/Plugin.BurnIn/Plugin.BurnIn.csproj
@@ -0,0 +1,70 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <Platforms>AnyCPU;x64</Platforms>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="LiveChartsCore" Version="2.0.0-rc5.4" />
+ <PackageReference Include="LiveChartsCore.SkiaSharpView" Version="2.0.0-rc5.4" />
+ <PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc5.4" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ <PackageReference Include="SuperSocket" Version="1.6.6.1" />
+ <PackageReference Include="SuperSocket.Engine" Version="1.6.6.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.StdControl\HMI.StdControl.csproj" />
+ <ProjectReference Include="..\PLCHelper\PLCHelper.csproj" />
+ <ProjectReference Include="..\Plugin.TsSupport\Plugin.TsSupport.csproj" />
+ <ProjectReference Include="..\SimpleUtil\HMI.LogUtil\HMI.LogUtil.csproj" />
+ <ProjectReference Include="..\Util.ManualDebug\Util.ManualDebug.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Reference Include="HslCommunication">
+ <HintPath>..\Libs\HslCommunication.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.API">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="WindowsFormsIntegration" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Resource Include="Resource\abort.png" />
+ <Resource Include="Resource\alert.png" />
+ <Resource Include="Resource\barcode.png" />
+ <Resource Include="Resource\checkIn.png" />
+ <Resource Include="Resource\checkInFailed2.png" />
+ <Resource Include="Resource\ng2.png" />
+ <Resource Include="Resource\ok2.png" />
+ <Resource Include="Resource\ready.png" />
+ <Resource Include="Resource\testing2.png" />
+ <Resource Include="Resource\waiting2.png" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Update="TestResultView.xaml.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.BurnIn/Resource/abort.png b/Plugin.BurnIn/Resource/abort.png
new file mode 100644
index 0000000..1b6b094
--- /dev/null
+++ b/Plugin.BurnIn/Resource/abort.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/alert.png b/Plugin.BurnIn/Resource/alert.png
new file mode 100644
index 0000000..6a9e531
--- /dev/null
+++ b/Plugin.BurnIn/Resource/alert.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/barcode.png b/Plugin.BurnIn/Resource/barcode.png
new file mode 100644
index 0000000..b68a9d6
--- /dev/null
+++ b/Plugin.BurnIn/Resource/barcode.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/checkIn.png b/Plugin.BurnIn/Resource/checkIn.png
new file mode 100644
index 0000000..eb4f984
--- /dev/null
+++ b/Plugin.BurnIn/Resource/checkIn.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/checkInFailed2.png b/Plugin.BurnIn/Resource/checkInFailed2.png
new file mode 100644
index 0000000..b4e6cfd
--- /dev/null
+++ b/Plugin.BurnIn/Resource/checkInFailed2.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/ng2.png b/Plugin.BurnIn/Resource/ng2.png
new file mode 100644
index 0000000..b1da88a
--- /dev/null
+++ b/Plugin.BurnIn/Resource/ng2.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/ok2.png b/Plugin.BurnIn/Resource/ok2.png
new file mode 100644
index 0000000..637da7a
--- /dev/null
+++ b/Plugin.BurnIn/Resource/ok2.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/ready.png b/Plugin.BurnIn/Resource/ready.png
new file mode 100644
index 0000000..df8dfd3
--- /dev/null
+++ b/Plugin.BurnIn/Resource/ready.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/testing2.png b/Plugin.BurnIn/Resource/testing2.png
new file mode 100644
index 0000000..531bff9
--- /dev/null
+++ b/Plugin.BurnIn/Resource/testing2.png
Binary files differ
diff --git a/Plugin.BurnIn/Resource/waiting2.png b/Plugin.BurnIn/Resource/waiting2.png
new file mode 100644
index 0000000..2fd9c21
--- /dev/null
+++ b/Plugin.BurnIn/Resource/waiting2.png
Binary files differ
diff --git a/Plugin.BurnIn/Scanner.xaml b/Plugin.BurnIn/Scanner.xaml
new file mode 100644
index 0000000..315cca4
--- /dev/null
+++ b/Plugin.BurnIn/Scanner.xaml
@@ -0,0 +1,78 @@
+锘�<pu:WindowX x:Class="Plugin.BurnIn.Scanner"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ WindowStartupLocation="CenterScreen"
+ Closing="Window_Closing"
+ FontSize="20"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
+ InteropOwnersMask="False"
+ SizeToContent="Height"
+ pu:WindowXModalDialog.Buttons="{x:Null}"
+ Title="{Binding title}" Width="600">
+ <Window.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ <Style TargetType="Label">
+ <Setter Property="HorizontalAlignment" Value="Right"/>
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='80,1920'}" />
+ </Style>
+ <Style TargetType="TextBox">
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='100,1920'}" />
+ </Style>
+ <Style TargetType="Button" BasedOn="{StaticResource PrimaryButton}">
+ <Setter Property="FontSize" Value="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=Window},
+Converter={StaticResource FontSizeConverter}, ConverterParameter='20,1920'}" />
+ </Style>
+ </Window.Resources>
+
+ <Grid Margin="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ </Grid.RowDefinitions>
+
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition/>
+ </Grid.ColumnDefinitions>
+
+ <!--<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" Padding="0"
+ Content="{DynamicResource Tr.PleaseScanSnr}"
+ Margin="0,0,0,20"
+ />-->
+ <GroupBox Grid.Row="1" Header="{DynamicResource Tr.PleaseScanSnr}" Padding="0,0,0,10" Grid.ColumnSpan="2" >
+ <StackPanel>
+ <pu:FormGroup
+ Header="{DynamicResource Tr.PositionSnr}"
+ dp:FormGroupHelper.IsRequired="True"
+ Style="{StaticResource InputFormGroupStyle}">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="positionText" TextWrapping="NoWrap" KeyDown="TextBox_KeyDown"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup
+ Header="{DynamicResource Tr.ProductSnr}"
+ dp:FormGroupHelper.IsRequired="True" Style="{StaticResource InputFormGroupStyle}">
+ <TextBox Style="{StaticResource EditorTextBoxStyle}" x:Name="snrText" TextWrapping="NoWrap" KeyDown="TextBox_KeyDown"/>
+ </pu:FormGroup>
+ </StackPanel>
+
+ </GroupBox>
+
+ <!--<Button Grid.Row="2" Click="Con_Click" Style="{StaticResource PrimaryButton}"
+ Content="{DynamicResource Tr.ContinueScan}"/>-->
+ <Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Click="Ok_Click" Style="{StaticResource SuccessButton}"
+ Content="{DynamicResource Tr.FinishScan}"/>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.BurnIn/Scanner.xaml.cs b/Plugin.BurnIn/Scanner.xaml.cs
new file mode 100644
index 0000000..ae98c61
--- /dev/null
+++ b/Plugin.BurnIn/Scanner.xaml.cs
@@ -0,0 +1,465 @@
+锘縰sing HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using HMI.Util;
+using Panuon.WPF.UI;
+using Plugin.BurnIn.Model;
+using Plugin.BurnIn.Util;
+using System.ComponentModel;
+using System.IO.Ports;
+using System.Windows;
+using System.Windows.Input;
+
+namespace Plugin.BurnIn
+{
+ public class BarcodeEventArg
+ {
+ public string name { get; private set; }
+ public string positionCode { get; private set; }
+ public string snrCode { get; private set; }
+ public CellInfo lastInfo { get; private set; }
+
+ public BarcodeEventArg(string name, string positionCode, string snrCode, CellInfo lastInfo)
+ {
+ this.name = name;
+ this.positionCode = positionCode;
+ this.snrCode = snrCode;
+ this.lastInfo = lastInfo;
+ }
+ }
+
+ /// <summary>
+ /// Scanner.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class Scanner : WindowX
+ {
+ private string _title;
+
+ public string title
+ {
+ get { return _title; }
+ set => Set(ref _title, value);
+ }
+
+ public event EventHandler<BarcodeEventArg> FinishBarcode;
+ public event EventHandler<RoutedEventArgs> ComplateClick;
+
+ private static Dictionary<string, CellInfo> snrCache = new Dictionary<string, CellInfo>();
+ SerialPort serialPort;
+
+ private string model;
+ private int columns;
+ private int rows;
+ private int ovenIndex;
+ private CellInfo targetCellInfo;
+ public Scanner(int index, string title, string model, int columns, int rows)
+ {
+ this.ovenIndex = index;
+ this.title = title;
+ this.model = model;
+ this.columns = columns;
+ this.rows = rows;
+ this.DataContext = this;
+ InitializeComponent();
+ Loaded += Scanner_Loaded;
+ }
+
+ private void Scanner_Loaded(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ InitScanner();
+ Loaded -= Scanner_Loaded;
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("Open Scanner Window Error.", ex);
+ MsgBoxHelper.Error(this, $"{ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 璁剧疆鎵爜鏋�
+ /// </summary>
+ private void InitScanner()
+ {
+ string comStr = "";
+ if (serialPort != null) return;
+
+ string section = this.Tag.ToString();
+ ScannerConfig common = ScannerConfig.ReadFromIni(BurnInUI.SannerIniFile, "Config");
+
+ string portName = IniFileHelper.ReadIniData(section, "PortName", "", BurnInUI.SannerIniFile);
+ if (string.IsNullOrEmpty(portName))
+ {
+ if (section.StartsWith("A"))
+ {
+ portName = "COM1";
+ }
+ else
+ {
+ portName = "COM2";
+ }
+ }
+ common.PortName = portName;
+
+
+ // 閰嶇疆涓插彛
+ 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)
+ {
+ BurnInUI.Logger.Error("Init Scan Gun Failed.", ex);
+ MsgBoxHelper.Error(this, $"{this.lang("Tr.InitGunFailed")}: {ex.StackTrace}");
+ }
+ }
+
+ private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
+ {
+ try
+ {
+ SerialPort sp = (SerialPort)sender;
+ string barcode = ReadDataFrom(sp).Trim();
+
+ //string barcode =
+ Dispatcher.Invoke(() =>
+ {
+ if (snrText.IsFocused)
+ {
+ snrText.Text = barcode;
+ Con_Click(null, null);
+ }
+ else
+ {
+ try
+ {
+ var targetCellInfo = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, barcode);
+ if (!TestResultView.nameTables.ContainsKey(targetCellInfo.OvenName))
+ {
+ MsgBoxHelper2.Error($"鑰佸寲鐐� [{targetCellInfo.OvenName}] 涓嶅瓨鍦紝璇锋鏌ラ厤缃�");
+ return;
+ }
+ var sourceTable = TestResultView.tables[this.ovenIndex];
+ if (sourceTable.title != targetCellInfo.OvenName)
+ {
+ MsgBoxHelper2.Error($"璇峰垏鎹㈣嚦 [{targetCellInfo.OvenName}] 鍖烘壂鐮侊紝褰撳墠涓� [{sourceTable.title}] 鍖猴紒");
+ return;
+ }
+
+ var oven = TestResultView.nameTables[targetCellInfo.OvenName];
+ if (oven.cells.Length < targetCellInfo.Index + 1)
+ {
+ MsgBoxHelper2.Error($"绌翠綅鍙� [{barcode}] 瓒呭嚭绱㈠紩 {targetCellInfo.Index}");
+ return;
+ }
+
+ this.targetCellInfo = targetCellInfo;
+ positionText.Text = barcode;
+ //positionText.Focus();
+ //snrText.Text = "";
+ snrText.Focus();
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("Parse Position Code Error.", ex);
+ MsgBoxHelper2.Error($"绌翠綅鍙� [{barcode}] 瑙f瀽澶辫触: {ex.Message}");
+ }
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("Get Scan Gun Data Failed.", ex);
+ MessageBox.Show($"{this.lang("Tr.GetGunData")}: {ex.StackTrace}");
+ }
+ }
+
+ public static void InsertNewCode(string snr, CellInfo info)
+ {
+ snrCache[snr] = info;
+ }
+
+ public static void RemoveSNR(string snr)
+ {
+ snrCache.Remove(snr);
+ }
+
+ private void SendCode(string tag, string position, string snr)
+ {
+ if (snrCache.ContainsKey(snr))
+ {
+ string oldPosition = snrCache[snr].OriginCode;
+ if (MsgBoxHelper2.WarnChoose($"鏉$爜[{snr}]宸叉斁缃簬[{oldPosition}]涓紝鏄惁娓呴櫎锛�") == MessageBoxResult.OK)
+ {
+ try
+ {
+ FinishBarcode.Invoke(this, new BarcodeEventArg(tag, position, null, snrCache[snr]));
+ snrCache.Remove(snr);
+ FinishBarcode.Invoke(this, new BarcodeEventArg(tag, position, snr, null));
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(ex.Message);
+ }
+ }
+ }
+ else
+ {
+ FinishBarcode.Invoke(this, new BarcodeEventArg(tag, position, snr, null));
+ }
+ }
+
+ private void Con_Click(object sender, RoutedEventArgs e)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ string position = positionText.Text, snr = snrText.Text;
+ try
+ {
+ var EnableMes = ParameterManager.GetCommonParameterByName<bool>("EnableMes", false);
+ if (ParamSetting.CustomerCode == "LIXUN" && EnableMes)
+ {
+ var table = TestResultView.nameTables[targetCellInfo.OvenName];
+ // TestResultView.tables[this.ovenIndex]
+ string currentPn = table.CbProduct.Text;
+
+ /// 妫�鏌ユ牸寮�
+ if (!SNValidator.ValidateSN(currentPn, snr, out string msg))
+ {
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革細{msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+
+ /// 鑾峰彇绔欏悕
+ string stationName = ProductManager.GetParameterByProductAndName(currentPn, "MES绔欎綅")?.Value;
+ if (string.IsNullOrEmpty(stationName))
+ {
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革紝褰撳墠浜у搧[{currentPn}]鏈缃弬鏁癕ES绔欎綅");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+
+ /// 妫�鏌N
+ if (PNUtil.GetPN(ParamSetting.MesAddress, stationName, snr, out string pn, out msg))
+ {
+
+ if (pn != currentPn)
+ {
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"褰撳墠娴嬭瘯鏂欏彿涓� [{currentPn}]锛屾壂鐮佷骇鍝佹枡鍙蜂负 [{pn}] 涓嶅厑璁告祴璇�");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+ }
+ else
+ {
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革細{msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+
+ /// 妫�鏌ュ伐搴�
+ if (PNUtil.CheckIn(BurnInUI.Logger, ParamSetting.MesAddress, stationName, snr, out bool needCheckIn, out msg))
+ {
+ if (needCheckIn != true)
+ {
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"鏉$爜[{snr}]宸ュ簭涓嶅湪鏈珯锛歿msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+ }
+ else
+ {
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ MsgBoxHelper2.Error($"鏉$爜[{snr}]CheckIn澶辫触锛歿msg}");
+ snrText.Text = string.Empty;
+ snrText.Focus();
+ return;
+ }
+ }
+ //var _ = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, snr);
+ //ToastHelper.Warning(this, "浜у搧鐮佹牸寮忓紓甯�");
+ //snrText.Text = string.Empty;
+ //snrText.Focus();
+ //return;
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("Scanner Check Error.", ex);
+ MsgBoxHelper2.Error($"鎵爜妫�鏌ュ紓甯革細{ex.Message}");
+ return;
+ }
+
+ if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
+ {
+ ToastHelper.Warning(this, this.lang("Tr.PleaseInputSnrs"));
+ return;
+ }
+ try
+ {
+ SendCode(Tag.ToString(), position, snr);
+ positionText.Text = "";
+ snrText.Text = "";
+ positionText.Focus();
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("Con_Click Failed.", ex);
+ ToastHelper.Warning(this, ex.Message);
+ }
+ });
+ }
+
+ /// <summary>
+ /// 鍘熸潵鐨勫畬鎴愭壂鎻忛�昏緫
+ /// </summary>
+ /// <param name="sender"></param>
+ /// <param name="e"></param>
+ //private void Ok_Click(object sender, RoutedEventArgs e)
+ //{
+ // string position = positionText.Text, snr = snrText.Text;
+ // if (string.IsNullOrEmpty(position) || string.IsNullOrEmpty(snr))
+ // {
+ // ToastHelper.Warning(this, this.lang("Tr.PleaseInputSnrs"));
+ // return;
+ // }
+ // try
+ // {
+ // SendCode(Tag.ToString(), position, snr);
+ // this.Close();
+ // }
+ // catch (Exception ex)
+ // {
+ // ViewControl.Logger.Error("Con_Click Failed.", ex);
+ // ToastHelper.Warning(this, ex.Message);
+ // }
+ //}
+
+ private void Ok_Click(object sender, RoutedEventArgs e)
+ {
+ ComplateClick?.Invoke(this, e);
+ this.Close();
+ }
+
+ 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.ASCII.GetString(buffer);
+ System.Threading.Thread.Sleep(50);
+ }
+ return barcode;
+ }
+
+ private void Window_Closing(object sender, CancelEventArgs e)
+ {
+ try
+ {
+ targetCellInfo = null;
+ serialPort.Dispose();
+ serialPort = null;
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+
+ private void TextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter)
+ {
+ //string barcode =
+ Dispatcher.Invoke(() =>
+ {
+ if (snrText.IsFocused)
+ {
+ Con_Click(null, null);
+ }
+ else
+ {
+ //if (ParamSetting.CustomerCode != "LIXUN")
+ //{
+ // snrText.Focus();
+ // return;
+ //}
+ string barcode = positionText.Text;
+ try
+ {
+ targetCellInfo = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, barcode);
+ if (!TestResultView.nameTables.ContainsKey(targetCellInfo.OvenName))
+ {
+ MsgBoxHelper2.Error($"鑰佸寲鐐� [{targetCellInfo.OvenName}] 涓嶅瓨鍦紝璇锋鏌ラ厤缃�");
+ positionText.Text = string.Empty;
+ positionText.Focus();
+ targetCellInfo = null;
+ return;
+ }
+
+ var sourceTable = TestResultView.tables[this.ovenIndex];
+ if (sourceTable.title != targetCellInfo.OvenName)
+ {
+ MsgBoxHelper2.Error($"璇峰垏鎹㈣嚦 [{targetCellInfo.OvenName}] 鍖烘壂鐮侊紝褰撳墠涓� [{sourceTable.title}] 鍖猴紒");
+ positionText.Text = string.Empty;
+ positionText.Focus();
+ targetCellInfo = null;
+ return;
+ }
+
+ var oven = TestResultView.nameTables[targetCellInfo.OvenName];
+ if (oven.cells.Length < targetCellInfo.Index + 1)
+ {
+ MsgBoxHelper2.Error($"绌翠綅鍙� [{barcode}] 瓒呭嚭绱㈠紩 {targetCellInfo.Index}");
+ positionText.Text = string.Empty;
+ positionText.Focus();
+ targetCellInfo = null;
+ return;
+ }
+ snrText.Focus();
+ }
+ catch (Exception ex)
+ {
+ positionText.Text = string.Empty;
+ positionText.Focus();
+ BurnInUI.Logger.Error("Parse Position Code Error.", ex);
+ MsgBoxHelper2.Error($"绌翠綅鍙� [{barcode}] 瑙f瀽澶辫触: {ex.Message}");
+ }
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/ScannerSetting.xaml b/Plugin.BurnIn/ScannerSetting.xaml
new file mode 100644
index 0000000..063b303
--- /dev/null
+++ b/Plugin.BurnIn/ScannerSetting.xaml
@@ -0,0 +1,66 @@
+锘�<pu:WindowX x:Class="Plugin.BurnIn.ScannerSetting"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ mc:Ignorable="d"
+ Style="{StaticResource ModalWindow}"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ xmlns:cc="clr-namespace:HMI.Core;assembly=HMI.Core"
+ xmlns:sys="clr-namespace:System;assembly=mscorlib"
+ xmlns:ports="clr-namespace:System.IO.Ports;assembly=System"
+ SizeToContent="Height"
+ WindowStartupLocation="CenterOwner"
+ Title="{Binding title}" Width="600">
+ <Window.Resources>
+ <ObjectDataProvider x:Key="stopBitsItems"
+ MethodName="GetValues"
+ ObjectType="{x:Type sys:Enum}">
+ <ObjectDataProvider.MethodParameters>
+ <x:Type TypeName="ports:StopBits"/>
+ </ObjectDataProvider.MethodParameters>
+ </ObjectDataProvider>
+ </Window.Resources>
+
+
+ <Grid Margin="10">
+ <StackPanel x:Name="formPanel">
+ <pu:FormGroup x:Name="FgPortName" Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource Tr.PortName}"
+ GroupName="MyFormGroup">
+ <ComboBox x:Name="CbPortName" Style="{StaticResource FormComboxStyle}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource Tr.BaudRate}"
+ dp:FormGroupHelper.IsRequired="True"
+ GroupName="MyFormGroup">
+ <pu:NumberInput x:Name="NiBaudRate" IsEnabled="{Binding SbIsEnabled}" Style="{StaticResource FormNumberInput}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource Tr.DataBits}"
+ dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+ <pu:NumberInput x:Name="NiDataBits" IsEnabled="{Binding SbIsEnabled}" Style="{StaticResource FormNumberInput}" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource Tr.StopBits}"
+ dp:FormGroupHelper.IsRequired="True" GroupName="MyFormGroup">
+ <ComboBox x:Name="CbStopBits" IsEnabled="{Binding SbIsEnabled}" Style="{StaticResource FormComboxStyle}"
+ ItemsSource="{Binding Source={StaticResource stopBitsItems}}"
+ SelectedValuePath="Content">
+ </ComboBox>
+ </pu:FormGroup>
+
+ <pu:FormGroup Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource Tr.DtrEnable}" GroupName="MyFormGroup">
+ <CheckBox x:Name="CxDtrEnable" IsEnabled="{Binding SbIsEnabled}"/>
+ </pu:FormGroup>
+
+ <pu:FormGroup Style="{StaticResource InputFormGroupStyle}" Header="{DynamicResource Tr.RtsEnable}" GroupName="MyFormGroup">
+ <CheckBox x:Name="CxRtsEnable" IsEnabled="{Binding SbIsEnabled}"/>
+ </pu:FormGroup>
+ </StackPanel>
+ </Grid>
+</pu:WindowX>
diff --git a/Plugin.BurnIn/ScannerSetting.xaml.cs b/Plugin.BurnIn/ScannerSetting.xaml.cs
new file mode 100644
index 0000000..e2bc377
--- /dev/null
+++ b/Plugin.BurnIn/ScannerSetting.xaml.cs
@@ -0,0 +1,147 @@
+锘縰sing HMI.Core.Util;
+using HMI.UI.DpUtil;
+using HMI.UI.Util;
+using HMI.Util;
+using Panuon.WPF.UI;
+using Plugin.BurnIn.Model;
+using System.ComponentModel;
+using System.IO.Ports;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// ScannerSetting.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class ScannerSetting : WindowX
+ {
+ public ScannerSetting()
+ {
+ DataContext = this;
+ InitializeComponent();
+ }
+
+ public ScannerConfig Data { get; set; }
+
+ private bool _isProcessing;
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ //Press Continue Button
+ if (DialogResult == true)
+ {
+ if (_isProcessing)
+ {
+ e.Cancel = true;
+ return;
+ }
+ var okButton = WindowXModalDialog.GetOKButton(this);
+ try
+ {
+ _isProcessing = true;
+ ButtonHelper.SetIsPending(okButton, true);
+ if (!ValidateForm())
+ {
+ e.Cancel = true;
+ return;
+ }
+
+ SaveOrUpdateData();
+ }
+ catch (Exception ex)
+ {
+ ToastHelper.Error(this, $"Error锛亄ex.Message}");
+ e.Cancel = true;
+ return;
+ }
+ finally
+ {
+ _isProcessing = false;
+ ButtonHelper.SetIsPending(okButton, false);
+ }
+ }
+ base.OnClosing(e);
+ }
+
+
+ private bool ValidateForm()
+ {
+ bool flag = FormGroupHelper.ValidateForm(formPanel);
+ if (flag)
+ {
+ Data.PortName = CbPortName.SelectedItem?.ToString();
+ Data.BaudRate = (int)(NiBaudRate.Value??0);
+ Data.DataBits = (int)(NiDataBits.Value??0);
+ Data.StopBits = (StopBits)CbStopBits.SelectedItem;
+ Data.DtrEnable = CxDtrEnable.IsChecked ?? false;
+ Data.RtsEnable = CxRtsEnable.IsChecked ?? false;
+ }
+ return flag;
+ }
+
+ private bool _isEnabled;
+ public bool SbIsEnabled {
+ get => _isEnabled;
+ set {
+ Set(ref _isEnabled, value);
+ }
+ }
+
+ private string section;
+ public bool? Open(bool showPortName, string section)
+ {
+ string[] ports = SerialPort.GetPortNames();
+ CbPortName.ItemsSource = ports;
+
+ this.section = section;
+ this.Title = section == "Config" ? this.lang("Tr.CommonSetting") : (section + this.lang("Tr.ScannerSetting"));
+ if (showPortName)
+ {
+ FgPortName.Visibility = System.Windows.Visibility.Visible;
+ FormGroupHelper.SetIsRequired(FgPortName, true);
+ SbIsEnabled = false;
+ }
+ else
+ {
+ FgPortName.Visibility = System.Windows.Visibility.Collapsed;
+ FormGroupHelper.SetIsRequired(FgPortName, false);
+ SbIsEnabled = true;
+ }
+
+ var data = ScannerConfig.ReadFromIni(BurnInUI.SannerIniFile, "Config");
+ string portName = IniFileHelper.ReadIniData(section, "PortName", "", BurnInUI.SannerIniFile);
+ if (string.IsNullOrEmpty(portName)) {
+ if (section.StartsWith("A"))
+ {
+ portName = "COM1";
+ }
+ else {
+ portName = "COM2";
+ }
+ }
+ data.PortName = portName;
+
+ Data = data;
+ CbPortName.SelectedItem = Data.PortName;
+ NiBaudRate.Value = Data.BaudRate;
+ NiDataBits.Value = Data.DataBits;
+ CbStopBits.SelectedItem = Data.StopBits;
+ CxDtrEnable.IsChecked = Data.DtrEnable;
+ CxRtsEnable.IsChecked = Data.RtsEnable;
+ return this.ShowDialog();
+ }
+
+ private void SaveOrUpdateData()
+ {
+ string iniFile = BurnInUI.SannerIniFile;
+ IniFileHelper.WriteIniData(section, "PortName", Data.PortName, iniFile);
+ if (section == "Config")
+ {
+ IniFileHelper.WriteIniData(section, "BaudRate", Data.BaudRate.ToString(), iniFile);
+ IniFileHelper.WriteIniData(section, "DataBits", Data.DataBits.ToString(), iniFile);
+ IniFileHelper.WriteIniData(section, "StopBits", Data.StopBits.ToString(), iniFile);
+ IniFileHelper.WriteIniData(section, "DtrEnable", Data.DtrEnable.ToString(), iniFile);
+ IniFileHelper.WriteIniData(section, "RtsEnable", Data.RtsEnable.ToString(), iniFile);
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/SingleCell.xaml b/Plugin.BurnIn/SingleCell.xaml
new file mode 100644
index 0000000..5f5236c
--- /dev/null
+++ b/Plugin.BurnIn/SingleCell.xaml
@@ -0,0 +1,146 @@
+锘�<UserControl x:Class="Plugin.BurnIn.SingleCell"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ mc:Ignorable="d"
+ xmlns:pw="https://opensource.panuon.com/wpf"
+xmlns:pu="https://opensource.panuon.com/wpf-ui"
+xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+ x:Name="uc"
+ PreviewMouseRightButtonDown="OnPreviewMouseRightButtonDown"
+ MouseDoubleClick="UserControl_MouseDoubleClick"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+ <local:FontSizeConverter x:Key="FontSizeConverter"/>
+ </UserControl.Resources>
+
+ <UserControl.Style>
+ <Style TargetType="UserControl">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="ok">
+ <Setter Property="Background" Value="#FF0F8853"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ng">
+ <Setter Property="Background" Value="#fd6b6d"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkInFailed">
+ <Setter Property="Background" Value="#ffac00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkIn">
+ <Setter Property="Background" Value="#FF00E2FF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="testing">
+ <Setter Property="Background" Value="#1296db"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="waiting">
+ <Setter Property="Background" Value="#A5A5A5"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="alert">
+ <Setter Property="Background" Value="#e04733"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ready">
+ <Setter Property="Background" Value="#FF08FF00"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="hadCode">
+ <Setter Property="Background" Value="#FFF"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="abort">
+ <Setter Property="Background" Value="Black"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </UserControl.Style>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition />
+ <RowDefinition Height="14"/>
+ <RowDefinition Height="14"/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition/>
+ <ColumnDefinition Width="Auto"/>
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0" Grid.Column="0" HorizontalContentAlignment="Left" VerticalContentAlignment="Top" Padding="0" Margin="5,5,0,0"
+ FontSize="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+ Converter={StaticResource FontSizeConverter}, ConverterParameter='8,103'}"
+ FontWeight="Bold"
+Background="Transparent" BorderThickness="0" Content="{Binding title}">
+ <Label.Style>
+ <Style TargetType="Label">
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="abort">
+ <Setter Property="Foreground" Value="#FFF"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Label.Style>
+ </Label>
+
+ <Image Grid.Row="0" Grid.Column="1" Width="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType=UserControl},
+ Converter={StaticResource FontSizeConverter}, ConverterParameter='10,20'}" HorizontalAlignment="Right"
+ Margin="0,5,5,0">
+ <Image.Style>
+ <Style TargetType="Image">
+ <Setter Property="HorizontalAlignment" Value="Center"/>
+ <Setter Property="VerticalAlignment" Value="Top"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding status}" Value="ok">
+ <Setter Property="Source" Value="Resource/ok2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ng">
+ <Setter Property="Source" Value="Resource/ng2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkInFailed">
+ <Setter Property="Source" Value="Resource/checkInFailed2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="checkIn">
+ <Setter Property="Source" Value="Resource/checkIn.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="testing">
+ <Setter Property="Source" Value="Resource/testing2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="waiting">
+ <Setter Property="Source" Value="Resource/waiting2.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="alert">
+ <Setter Property="Source" Value="Resource/alert.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="ready">
+ <Setter Property="Source" Value="Resource/ready.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="hadCode">
+ <Setter Property="Source" Value="Resource/barcode.png"/>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding status}" Value="abort">
+ <Setter Property="Source" Value="Resource/abort.png"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Image.Style>
+ </Image>
+
+ <ui:ScrollLabel Grid.Row="1" Grid.Column="0" FontSize="10" Grid.ColumnSpan="2" Margin="3,0,0,0" Padding="0" Value="{Binding sn}"/>
+
+ <StackPanel Orientation="Horizontal" Background="LightGray" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Top" HorizontalAlignment="Right">
+ <TextBlock Foreground="Red" Text="{DynamicResource Ts.ProbeAlarm}" FontSize="10">
+ <TextBlock.Style>
+ <Style TargetType="TextBlock">
+ <Setter Property="Visibility" Value="Collapsed"/>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding probeAlarm}" Value="True">
+ <Setter Property="Visibility" Value="Visible"/>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </TextBlock.Style>
+ </TextBlock>
+ <TextBlock Margin="0" FontSize="10">
+ <Run Text="{Binding ProbeCount}"/>
+ <Run Text="/"/>
+ <Run Text="{Binding ProbeWarn}"/>
+ </TextBlock>
+ </StackPanel>
+ </Grid>
+</UserControl>
diff --git a/Plugin.BurnIn/SingleCell.xaml.cs b/Plugin.BurnIn/SingleCell.xaml.cs
new file mode 100644
index 0000000..8fafd4f
--- /dev/null
+++ b/Plugin.BurnIn/SingleCell.xaml.cs
@@ -0,0 +1,1174 @@
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using HMI.Util;
+using PLCHelper;
+using Plugin.BurnIn.Constant;
+using Plugin.BurnIn.Model;
+using Plugin.BurnIn.Util;
+using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// SingleCell.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class SingleCell : UserControl, INotifyPropertyChanged
+ {
+
+ #region ...
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public virtual void RaisePropertyChanged(string name)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void RaiseAndSetIfchanged<T>(ref T old, T @new, [CallerMemberName] string propertyName = null)
+ {
+ old = @new;
+ if (propertyName != null) RaisePropertyChanged(propertyName);
+ }
+ #endregion
+
+ private static readonly HashSet<string> IgnoreTestItem = new HashSet<string> {
+ "浜у搧鏉$爜","checkin","棰勬鐢垫祦","precheckresult","checkout",
+ };
+
+ private InfoWindow window;
+ private int maxSize;
+
+ public DataTable table { get; private set; }
+
+ public SingleCell(DataTable table, string title, int index, int maxSize, string iniFile)
+ {
+ this.table = table;
+ this.title = title;
+ this.index = index;
+ this.maxSize = maxSize;
+ this.countIniPath = iniFile;
+ DataContext = this;
+ InitializeComponent();
+ RefreshProbe();
+ }
+
+ public void RefreshProbe()
+ {
+ try
+ {
+ string key = string.Empty;
+ ParameterData value;
+ if (ParamSetting.ProbeByModel)
+ {
+ string model = table.CbProduct?.SelectedItem?.ToString();
+ key = $"{title}_{model}";
+ value = ProductManager.GetParameterByProductAndName(model, "ProbeWarn");
+ if (value == null)
+ {
+ value = ParameterManager.GetCommonParameterByName("ProbeWarn");
+ }
+ ProbeWarn = value != null ? int.Parse(value.Value) : 1000;
+ }
+ else
+ {
+ key = $"{title}";
+ value = ParameterManager.GetCommonParameterByName("ProbeWarn");
+ ProbeWarn = value != null ? int.Parse(value.Value) : 1000;
+ }
+ string temp = IniFileHelper.ReadIniData(key, "ProbeCount", "0", countIniPath);
+ int count = Convert.ToInt32(temp);
+ ProbeCount = count;
+ }
+ catch
+ {
+ ProbeWarn = 1000;
+ }
+ if (window != null) window.UpdateProbeCount(ProbeCount, ProbeWarn);
+ }
+
+ public void RefreshCharts()
+ {
+ charts = new LiveChart[3];
+ try
+ {
+ ParameterData value;
+ string model = table.CbProduct?.SelectedItem?.ToString();
+
+ for (int i = 0; i < charts.Length; i++)
+ {
+ value = ProductManager.GetParameterByProductAndName(model, $"ChartConfig_{i}");
+ if (value == null)
+ {
+ value = ParameterManager.GetCommonParameterByName($"ChartConfig_{i}");
+ }
+ var config = value != null ? value.Value : null;
+
+ if (string.IsNullOrEmpty(config))
+ {
+ charts[i] = null;
+ }
+ else
+ {
+ charts[i] = new LiveChart(config) //new string[] { "娓╁害(鈩�)", "娴侀噺(L/m)" }
+ {
+ MinHeight = 120
+ };
+ }
+ }
+ }
+ catch
+ {
+ charts = new LiveChart[0];
+ }
+ }
+
+ private string _sn;
+ public string sn
+ {
+ get { return _sn; }
+ set
+ {
+ RaiseAndSetIfchanged(ref _sn, value);
+ RaisePropertyChanged("sn");
+ }
+ }
+
+ private int _index;
+
+ public int index
+ {
+ get { return _index; }
+ set
+ {
+ RaiseAndSetIfchanged(ref _index, value);
+ RaisePropertyChanged("title");
+ }
+ }
+
+ private bool cellIsDisabled;
+
+ public bool CellIsDisabled
+ {
+ get { return cellIsDisabled; }
+ set
+ {
+ RaiseAndSetIfchanged(ref cellIsDisabled, value);
+ }
+ }
+
+ private string _title;
+ public string title
+ {
+ get => _title;
+ set
+ {
+ RaiseAndSetIfchanged(ref _title, value);
+ }
+ }
+
+ private int _probeWarn;
+ public int ProbeWarn
+ {
+ get => _probeWarn;
+ set
+ {
+ RaiseAndSetIfchanged(ref _probeWarn, value);
+ }
+ }
+
+ private string _status = CommonStatus.WAITING;
+
+ public string tooltipContent
+ {
+ get
+ {
+ string dataStr = "";
+ if (infos != null && infos.Count > 0)
+ {
+ foreach (var info in infos)
+ {
+ dataStr += $"\r\nStep:{info.step},Result:{info.result}";
+ }
+ }
+ return $"{title}\r\n鐘舵��:{CommonStatus.GetStatusDescription(status)}{dataStr}";
+ }
+ }
+
+ public string status
+ {
+ get { return _status; }
+ set => RaiseAndSetIfchanged(ref _status, value);
+ }
+
+ private ConcurrentQueue<Info> queue = new ConcurrentQueue<Info>();
+
+ private List<Info> allInfos = new List<Info>();
+
+ private ObservableCollection<Info> _infos = new ObservableCollection<Info>();
+
+ public ObservableCollection<Info> infos
+ {
+ get => _infos;
+ set
+ {
+ RaiseAndSetIfchanged(ref _infos, value);
+ RaisePropertyChanged("tooltipContent");
+ }
+ }
+
+ private string countIniPath;
+ /// <summary>
+ /// 鎺㈤拡瀵垮懡
+ /// </summary>
+ private int probeCount;
+ public int ProbeCount
+ {
+ get => probeCount;
+ set
+ {
+ RaiseAndSetIfchanged(ref probeCount, value);
+ probeAlarm = value >= ProbeWarn;
+ }
+ }
+
+ private bool _probeAlarm;
+ public bool probeAlarm
+ {
+ get => _probeAlarm;
+ set
+ {
+ RaiseAndSetIfchanged(ref _probeAlarm, value);
+ }
+ }
+
+ private void UpdateProbeCount(int count)
+ {
+ ProbeCount = count;
+ string key = $"{title}";
+ if (ParamSetting.ProbeByModel)
+ {
+ string model = table?.CbProduct?.SelectedItem?.ToString();
+ key = $"{title}_{model}";
+ }
+ IniFileHelper.WriteIniData(key, "ProbeCount", ProbeCount.ToString(), countIniPath);
+ if (window != null) window.UpdateProbeCount(ProbeCount, ProbeWarn);
+ }
+
+ private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e)
+ {
+ if (window == null)
+ {
+ window = new InfoWindow(title, infos, charts, ProbeCount, ProbeWarn);
+ window.Closed += Window_Closed;
+ window.ClearProbeCountEvent += Window_ClearProbeCountEvent;
+ window.Owner = Window.GetWindow(this);
+ window.Show();
+ }
+ else
+ {
+ window.Activate();
+ }
+ }
+
+ private void Window_ClearProbeCountEvent(object sender, EventArgs e)
+ {
+ UpdateProbeCount(0);
+ }
+
+ private void Window_Closed(object sender, EventArgs e)
+ {
+ this.window = null;
+ }
+
+ private string visualTestId;
+ private Sqlite3Helper helper;
+
+ private void InitCurrentTestHelper()
+ {
+ if (helper == null)
+ {
+ var now = DateTime.Now;
+ string dateStr = now.ToString("yyyyMMdd");
+ visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}";
+ helper = CheckSqlHelper(dateStr);
+ }
+ }
+
+ public void SetStatus(string status)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ var oldStatus = this.status;
+ this.status = status;
+ if (oldStatus != "testing" && status == "testing")
+ {
+ UpdateProbeCount(ProbeCount + 1);
+ InitCurrentTestHelper();
+ InsertARecord();
+ }
+
+ if (oldStatus != "ok" && status == "ok")
+ {
+ SaveInfoToDB();
+ }
+
+ if (oldStatus != "ng" && status == "ng")
+ {
+ SaveInfoToDB();
+ }
+ });
+ }
+
+ private void InsertARecord()
+ {
+ try
+ {
+ string model = table?.CbProduct?.SelectedItem?.ToString();
+ var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ var sql = $"INSERT INTO testResult (sn,model,station,position,result,time,resultId) VALUES ('{sn}','{model}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+ helper.Execute(sql);
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Cell[{title}] InsertARecord Error.", ex);
+ }
+ }
+
+ public void WriteCSV(Info info)
+ {
+ //try
+ //{
+ // if (ParamSetting.CustomerCode != "LIXUN")
+ // {
+ // return;
+ // }
+ // string fileName = this.sn?.Replace("/", "#")?.Replace("\\", "#") + ".csv";
+ // string dir = Path.Combine(ParamSetting.DataLogFolder, "csv", this.title);
+ // string title = $"{this.lang("Test.Name")},{this.lang("Test.Value")},{this.lang("Test.LimitDown")},{this.lang("Test.LimitUp")},{this.lang("Test.Unit")},{this.lang("Test.Result")},{this.lang("Test.TestTime")}";
+ // string line = $"{info.step},{info.value},{info.limitDown},{info.limitUp},{info.unit},{info.result},{info.updateTime}";
+
+ // CSVPrinter.Print(dir, fileName, title, line);
+ // // ReverseCSV(Path.Combine(dir, fileName));
+ //}
+ //catch (Exception ex)
+ //{
+ //}
+ }
+
+ public void SendToChart(Info info)
+ {
+ try
+ {
+ foreach (var chart in charts)
+ {
+ if (chart?.CanHandle(info.step) == true)
+ {
+ chart.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+ }
+ }
+ //if (electricChart.CanHandle(info.step))
+ //{
+ // electricChart.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+ //}
+
+ //if (vChart.CanHandle(info.step))
+ //{
+ // vChart.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+ //}
+
+ //if (waterChart?.CanHandle(info.step) == true)
+ //{
+ // waterChart?.AddData(info.step, DateTime.Parse(info.updateTime), double.Parse(info.value));
+ //}
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+
+ public void SetInfos(Info info)
+ {
+ string sql = string.Empty;
+ try
+ {
+ allInfos.Add(info);
+ SendToChart(info);
+ WriteCSV(info);
+
+ /// 鐩墠鍏堜笉闄愬埗鏁伴噺锛屽悗缁鏋滄暟鎹繃澶氬鑷存�ц兘闂鍐嶈�冭檻闄愬埗鏁伴噺
+ //if (queue.Count >= maxSize)
+ //{
+ // queue.TryDequeue(out var first);
+ // queue.Enqueue(info);
+ // this.infos = new ObservableCollection<Info>(queue);
+ // if (window != null) window.UpdateSource(this.infos);
+ //}
+ //else
+ //{
+ // queue.Enqueue(info);
+ // if (window != null)
+ // {
+ // window.Dispatcher.Invoke(() =>
+ // {
+ // this.infos.Add(info);
+ // });
+ // }
+ // else
+ // {
+ // Dispatcher.Invoke(() =>
+ // {
+ // this.infos.Add(info);
+ // });
+ // }
+ //}
+
+ if (window != null)
+ {
+ window.Dispatcher.Invoke(() =>
+ {
+ this.infos.Add(info);
+ });
+ }
+ else
+ {
+ Dispatcher.Invoke(() =>
+ {
+ this.infos.Add(info);
+ });
+ }
+
+ Dispatcher.Invoke(() =>
+ {
+ string dateStr = string.Empty;
+ try
+ {
+ dateStr = DateTime.Parse(info.updateTime).ToString("yyyy-MM-dd HH:mm:ss");
+ }
+ catch
+ {
+ dateStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ try
+ {
+ InitCurrentTestHelper();
+ string model = table?.CbProduct?.SelectedItem?.ToString();
+ sql = $@"INSERT INTO serialData (sn,model,station,position,step,limitDown,limitUp,unit,value,status,finalStatus,time,resultId)
+VALUES ('{sn}','{model}','','{this.title}','{info.step}','{info.limitDown}','{info.limitUp}','{info.unit}','{info.value}','{info.result}',
+NULL,'{dateStr}','{visualTestId}');";
+ helper.Execute(sql);
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Save DB Test Data Error. {sql}", ex);
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Add Test Data Error. {sql}", ex);
+ }
+ }
+
+ public void ClearInfo()
+ {
+ allInfos.Clear();
+ queue = new ConcurrentQueue<Info>();
+ var list = new ObservableCollection<Info>(queue);
+ this.infos = list;
+ if (window != null) window.UpdateSource(this.infos);
+ }
+
+ //private Chart waterChart = null;
+ //private Chart electricChart = new Chart(LangUtil.Get("Tr.CurrentChart"), false, 20)
+ //{
+ // Height = 120
+ //};
+
+ //private Chart vChart = new Chart(LangUtil.Get("Tr.VoltChart"), false, 20)
+ //{
+ // Height = 120
+ //};
+
+ private LiveChart[] charts = new LiveChart[0];
+
+ //private LiveChart waterChart = null;
+ //private LiveChart electricChart = new LiveChart("瀛愭澘鐢垫祦,鐢垫祦(A);姣嶆澘鐢垫祦,鐢垫祦(A)") //new string[] { "瀛愭澘鐢垫祦", "妯℃澘鐢垫祦" }
+ //{
+ // MinHeight = 120
+ //};
+
+ //private LiveChart vChart = new LiveChart("瀛愭澘鐢靛帇,鐢靛帇(V);姣嶆澘鐢靛帇,鐢靛帇(V)") //new string[] { "瀛愭澘鐢靛帇", "妯℃澘鐢靛帇" }
+ //{
+ // MinHeight = 120
+ //};
+
+ public void AddWaterData(double temp, double backTemp, double pressure)
+ {
+ //waterChart?.AddData(0, "姘寸娓╁害", temp);
+ //waterChart?.AddData(0, "鍥炴按娓╁害", backTemp);
+ //waterChart?.AddData(1, "娴侀噺", pressure);
+
+ //waterChart?.AddData("姘寸娓╁害", temp);
+ //waterChart?.AddData("鍥炴按娓╁害", backTemp);
+ //waterChart?.AddData("娴侀噺", pressure);
+ }
+
+ public void AddElectricData(double data)
+ {
+ //electricChart.AddData("", data);
+ }
+
+ public void AddVData(double data)
+ {
+ //vChart.AddData("", data);
+ }
+
+ public void ClearChart()
+ {
+ foreach (var chart in charts)
+ {
+ chart?.Clear();
+ }
+ }
+
+ //public void ClearWaterData()
+ //{
+ // waterChart?.Clear();
+ //}
+
+ //public void ClearElectricData()
+ //{
+ // electricChart.Clear();
+ //}
+
+ //public void ClearVData()
+ //{
+ // vChart.Clear();
+ //}
+
+
+ public void SaveElectricDataToCSV(string filePath)
+ {
+ try
+ {
+ List<double> datas = charts[1]?.GetSingleData("");
+
+ FileInfo fi = new FileInfo(filePath);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = this.lang("Tr.CurrentChart");
+ sw.WriteLine(title);
+ if (datas != null)
+ {
+ for (int i = 0; i < datas.Count; i++)
+ {
+ sw.WriteLine(datas[i].ToString());
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ }
+ }
+
+ public void SaveVDataToCSV(string filePath)
+ {
+ try
+ {
+ List<double> datas = charts[2]?.GetSingleData("");
+
+ FileInfo fi = new FileInfo(filePath);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = this.lang("Tr.VoltChart");
+ sw.WriteLine(title);
+ if (datas != null)
+ {
+ for (int i = 0; i < datas.Count; i++)
+ {
+ sw.WriteLine(datas[i].ToString());
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ }
+ }
+
+ public void NormalCSV(string filePath)
+ {
+ try
+ {
+ FileInfo fi = new FileInfo(filePath);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = $"{this.lang("Test.Name")},{this.lang("Test.Value")},{this.lang("Test.LimitDown")},{this.lang("Test.LimitUp")},{this.lang("Test.Unit")},{this.lang("Test.Result")},{this.lang("Test.TestTime")}";
+ sw.WriteLine(title);
+ foreach (var info in allInfos)
+ {
+ string row = $"{info.step},{info.value},{info.limitDown},{info.limitUp},{info.unit},{info.result},{info.updateTime}";
+ sw.WriteLine(row);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex);
+ }
+ }
+
+ public void ReverseCSV_Bak(string filePath)
+ {
+ try
+ {
+ if (allInfos == null || allInfos.Count < 4) return;
+
+ Dictionary<string, int> columnMap = new Dictionary<string, int>();
+ int colPoint = 0;
+ List<string> titleRow = new List<string>();
+ List<string[]> datas = new List<string[]>();
+
+ void AddTitle(string title)
+ {
+ if (titleRow.IndexOf(title) < 0)
+ {
+ titleRow.Add(title);
+ }
+ }
+
+ // 鍏堣缃〃澶�
+ for (int row = 0; row < allInfos.Count; row++)
+ {
+ var info = allInfos[row];
+ if (IgnoreTestItem.Contains(info.step.ToLower()))
+ {
+ continue;
+ }
+
+ string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+ AddTitle("娴嬭瘯鏃堕棿");
+ AddTitle(title);
+ if (!string.IsNullOrEmpty(info.limitDown))
+ {
+ string key2 = $"{info.step}涓嬮檺";
+ AddTitle(key2);
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}涓婇檺";
+ AddTitle(key2);
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}娴嬭瘯缁撴灉";
+ AddTitle(key2);
+ }
+
+ //if (!string.IsNullOrEmpty(info.updateTime))
+ //{
+ // string key2 = $"{info.step}娴嬭瘯鏃堕棿";
+ // AddTitle(key2);
+ //}
+ }
+
+ int rowPoint = -1;
+ for (int row = 0; row < allInfos.Count; row++)
+ {
+ var info = allInfos[row];
+ if (IgnoreTestItem.Contains(info.step.ToLower()))
+ {
+ continue;
+ }
+
+ string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+ int col = titleRow.IndexOf(title);
+ if (col == 1)
+ {
+ rowPoint++;
+ }
+ if (datas.Count <= rowPoint)
+ {
+ datas.Add(new string[titleRow.Count]);
+ }
+ var arr = datas[rowPoint];
+ arr[col] = info.value;
+
+
+ if (!string.IsNullOrEmpty(info.limitDown))
+ {
+ string key2 = $"{info.step}涓嬮檺";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.limitDown;
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}涓婇檺";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.limitUp;
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}娴嬭瘯缁撴灉";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.result;
+ }
+
+ if (!string.IsNullOrEmpty(info.updateTime))
+ {
+ string key2 = "娴嬭瘯鏃堕棿";// $"{info.step}娴嬭瘯鏃堕棿";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.updateTime;
+ }
+ }
+
+
+ FileInfo fi = new FileInfo(filePath);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = string.Join(",", titleRow);
+ sw.WriteLine(title);
+ foreach (var info in datas)
+ {
+ string row = string.Join(",", info);
+ sw.WriteLine(row);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex);
+ }
+ }
+
+ public void ReverseCSV(string filePath)
+ {
+ try
+ {
+ if (allInfos == null || allInfos.Count < 4) return;
+
+ Dictionary<string, int> columnMap = new Dictionary<string, int>();
+ int colPoint = 0;
+ List<string> titleRow = new List<string>();
+ List<string[]> datas = new List<string[]>();
+ List<string> timeRow = new List<string>();
+
+ void AddTitle(string title)
+ {
+ if (titleRow.IndexOf(title) < 0)
+ {
+ titleRow.Add(title);
+ }
+ }
+
+ // 鍏堣缃〃澶�
+ for (int i = 0; i < allInfos.Count; i++)
+ {
+ var info = allInfos[i];
+ if (IgnoreTestItem.Contains(info.step.ToLower()))
+ {
+ continue;
+ }
+ string testTime = info.updateTime;
+ int rowIndex = timeRow.IndexOf(testTime);
+ if (rowIndex < 0)
+ {
+ timeRow.Add(testTime);
+ }
+
+ string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+ AddTitle("娴嬭瘯鏃堕棿");
+ AddTitle(title);
+ if (!string.IsNullOrEmpty(info.limitDown))
+ {
+ string key2 = $"{info.step}涓嬮檺";
+ AddTitle(key2);
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}涓婇檺";
+ AddTitle(key2);
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}娴嬭瘯缁撴灉";
+ AddTitle(key2);
+ }
+
+ //if (!string.IsNullOrEmpty(info.updateTime))
+ //{
+ // string key2 = $"{info.step}娴嬭瘯鏃堕棿";
+ // AddTitle(key2);
+ //}
+ }
+
+ for (int i = 0; i < allInfos.Count; i++)
+ {
+ var info = allInfos[i];
+ if (IgnoreTestItem.Contains(info.step.ToLower()))
+ {
+ continue;
+ }
+ string testTime = info.updateTime;
+ int row = timeRow.IndexOf(testTime);
+ if (row < 0)
+ {
+ continue;
+ }
+
+
+
+ string title = $"{info.step}{(string.IsNullOrEmpty(info.unit) ? "" : $"({info.unit})")}";
+ int col = titleRow.IndexOf(title);
+
+ if (datas.Count <= row)
+ {
+ datas.Add(new string[titleRow.Count]);
+ }
+ var arr = datas[row];
+ arr[col] = info.value;
+
+
+ if (!string.IsNullOrEmpty(info.limitDown))
+ {
+ string key2 = $"{info.step}涓嬮檺";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.limitDown;
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}涓婇檺";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.limitUp;
+ }
+
+ if (!string.IsNullOrEmpty(info.limitUp))
+ {
+ string key2 = $"{info.step}娴嬭瘯缁撴灉";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.result;
+ }
+
+ if (!string.IsNullOrEmpty(info.updateTime))
+ {
+ string key2 = "娴嬭瘯鏃堕棿";// $"{info.step}娴嬭瘯鏃堕棿";
+ int col2 = titleRow.IndexOf(key2);
+ arr[col2] = info.updateTime;
+ }
+ }
+
+
+ FileInfo fi = new FileInfo(filePath);
+ if (!fi.Directory.Exists)
+ {
+ fi.Directory.Create(); //鏂囦欢涓嶅瓨鍦紝鍒涘缓鏂囦欢
+ }
+
+ using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+ using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
+ {
+ string title = string.Join(",", titleRow);
+ sw.WriteLine(title);
+ foreach (var info in datas)
+ {
+ string row = string.Join(",", info);
+ sw.WriteLine(row);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex);
+ }
+ }
+
+ /// <summary>
+ /// 淇濆瓨娴嬭瘯鏁版嵁鍒癈SV
+ /// </summary>
+ /// <param name="filePath"></param>
+ public void SaveInfoToCSV(string filePath)
+ {
+ if (ParamSetting.ReverseCSV)
+ {
+ ReverseCSV(filePath);
+ }
+ else
+ {
+ NormalCSV(filePath);
+ }
+ }
+
+ private Sqlite3Helper CheckSqlHelper(string dateStr = null)
+ {
+ dateStr = string.IsNullOrEmpty(dateStr) ? DateTime.Now.ToString("yyyyMMdd") : dateStr;
+ string dbPath = Path.Combine(ParamSetting.DataLogFolder, $"Data_{dateStr}.db");
+ if (!File.Exists(dbPath))
+ {
+ Sqlite3Helper.CreateDatabase(dbPath);
+ }
+ var sqliteHelper = new Sqlite3Helper(dbPath);
+ sqliteHelper.Execute(@"CREATE TABLE IF NOT EXISTS serialData (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ sn TEXT NOT NULL,
+ model TEXT,
+ station TEXT NOT NULL,
+ step TEXT NOT NULL,
+ position TEXT,
+ limitDown TEXT,
+ limitUp TEXT,
+ unit TEXT,
+ offset TEXT,
+ value TEXT,
+ status TEXT,
+ finalStatus TEXT,
+ consumeTime TEXT,
+ totalConsumeTime TEXT,
+ resultId TEXT,
+ time DATETIME NOT NULL);");
+ sqliteHelper.Execute(@"CREATE TABLE IF NOT EXISTS testResult (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ sn TEXT NOT NULL,
+ model TEXT,
+ station TEXT NOT NULL,
+ position TEXT,
+ status TEXT,
+ result TEXT NOT NULL,
+ resultId TEXT,
+ time DATETIME NOT NULL);");
+ if (!sqliteHelper.HasData("SELECT 1 FROM pragma_table_info('serialData') WHERE name = 'resultId';"))
+ {
+ sqliteHelper.Execute("ALTER TABLE serialData ADD resultId TEXT;");
+ }
+ if (!sqliteHelper.HasData("SELECT 1 FROM pragma_table_info('testResult') WHERE name = 'resultId';"))
+ {
+ sqliteHelper.Execute("ALTER TABLE testResult ADD resultId TEXT;");
+ }
+ return sqliteHelper;
+ }
+
+ /// <summary>
+ /// 淇濆瓨娴嬭瘯鏁版嵁鍒癝qlite
+ /// </summary>
+ /// <param name="filePath"></param>
+ public void SaveInfoToDB()
+ {
+ Dispatcher.Invoke(() =>
+ {
+ try
+ {
+ string model = table?.CbProduct?.SelectedItem?.ToString();
+ var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ //var sql = $"INSERT INTO testResult (sn,model,station,position,result,time,resultId) VALUES ('{sn}','{model}','','{title}','{this.status}','{timestr}','{visualTestId}');";
+ var sql = $"UPDATE testResult SET time = '{timestr}', result = '{this.status}' WHERE resultId = '{visualTestId}'";
+ helper.Execute(sql);
+ helper.Dispose();
+ helper = null;
+ // using (var helper = CheckSqlHelper())
+ // {
+ // List<string> sqls = new List<string>();
+ // var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+ // foreach (var info in allInfos)
+ // {
+ // string sql = $@"INSERT INTO serialData (sn,station,step,limitDown,limitUp,unit,value,status,finalStatus,time)
+ //VALUES ('{sn}','','{info.step}','{info.limitDown}','{info.limitUp}','{info.unit}','{info.value}','{info.result}','{this.status}','{timestr}');";
+ // sqls.Add(sql);
+ // }
+ // sqls.Add($"INSERT INTO testResult (sn,station,position,result,time) VALUES ('{sn}','','{title}','{this.status}','{timestr}');");
+ // helper.ExecuteBatchSql(sqls);
+ // }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error($"Cell[{title}] SaveToDB Error.", ex);
+ }
+ });
+ }
+
+ private void MenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ var item = sender as MenuItem;
+ switch (item?.Name)
+ {
+ case "clearSNRItem":
+ table.TryClearCellSN(this.index);
+ break;
+ case "exportCSVItem":
+ TryExportCSV();
+ break;
+ case "manualDebugItem":
+ OpenManualDebugWindow();
+ break;
+ default:
+ break;
+ }
+ }
+
+ /// <summary>
+ /// 鎵撳紑鎵嬪姩璋冭瘯绐楀彛
+ /// </summary>
+ private void OpenManualDebugWindow()
+ {
+ string manualDebugSeq = ParameterManager.GetCommonParameterByName("ManualDebugSeqPath")?.Value;
+ if (string.IsNullOrEmpty(manualDebugSeq))
+ {
+ MsgBoxHelper2.Error("璇峰厛璁剧疆鎵嬪姩璋冭瘯搴忓垪璺緞[ManualDebugSeqPath]!");
+ return;
+ }
+ string modelPath = table.parent.testModelFile;
+ int dutNo = table.index * table.cellCount + this.index;
+ var win = new ManualDebugWindow(manualDebugSeq, modelPath)
+ {
+ Title = $"{this.title}鎵嬪姩璋冭瘯",
+ Owner = Window.GetWindow(this),
+ OvenIndex = this.table.index,
+ OvenName = this.table.title,
+
+ CellIndex = dutNo,
+ CellName = this.title
+ };
+ win.ShowDialog();
+ }
+
+ /// <summary>
+ /// 灏濊瘯瀵煎嚭CSV
+ /// </summary>
+ private void TryExportCSV()
+ {
+ System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog
+ {
+ Filter = "CSV (*.csv)|*.csv"
+ };
+ if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
+ {
+ this.NormalCSV(sfd.FileName);
+ }
+ }
+
+ public void ClearSN()
+ {
+ sn = string.Empty;
+ LightGreen(false, out _);
+ LightRed(false, out _);
+ }
+
+ public bool LightGreen(bool on, out string msg)
+ {
+ string key = $"Oven{table.index + 1}_Cell{index + 1}_Light_OK";
+ bool res = S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME, key, on, out msg);
+ if (res)
+ {
+ BurnInUI.Logger.Debug($"Set Light [{key}] {on}.");
+ }
+ else
+ {
+ BurnInUI.Logger.Debug($"Open Light [{key}] {on} Error.{msg}");
+ }
+ return res;
+ }
+
+ public bool LightRed(bool on, out string msg)
+ {
+ return S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME,
+ $"Oven{table.index + 1}_Cell{index + 1}_Light_NG", on, out msg);
+ }
+
+ private void OnPreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+ {
+
+ ContextMenu contextMenu = new ContextMenu();
+ contextMenu.Closed += ContextMenu_Closed;
+
+ //< />
+ //<
+ //< MenuItem IsCheckable = "False" x: Name = "manualDebugItem" Click = "MenuItem_Click" Header = "鎵嬪姩璋冭瘯" >
+ // < MenuItem.Style >
+ // < Style TargetType = "MenuItem" BasedOn = "{StaticResource {x:Static pu:StyleKeys.MenuItemStyle}}" >
+
+ // </ Style >
+ // </ MenuItem.Style >
+ //</ MenuItem >
+
+ var item = new MenuItem
+ {
+ IsCheckable = false,
+ IsEnabled = !table.IsTesting,
+ Name = "clearSNRItem",
+ Header = this.lang("Tr.ClearSNR"),
+ };
+ item.Click += MenuItem_Click;
+ contextMenu.Items.Add(item);
+
+ item = new MenuItem
+ {
+ IsCheckable = false,
+ Name = "exportCSVItem",
+ Header = this.lang("App.ExportCSV"),
+ };
+ item.Click += MenuItem_Click;
+ contextMenu.Items.Add(item);
+
+ if (table.parent.inManualDebugMode)
+ {
+ item = new MenuItem
+ {
+ IsCheckable = false,
+ Name = "manualDebugItem",
+ Header = this.lang("鎵嬪姩璋冭瘯"),
+ };
+ item.Click += MenuItem_Click;
+ contextMenu.Items.Add(item);
+ }
+
+ this.ContextMenu = contextMenu;
+ }
+
+ private void ContextMenu_Closed(object sender, RoutedEventArgs e)
+ {
+ this.ContextMenu = null;
+ }
+ }
+}
diff --git a/Plugin.BurnIn/TestResultView.xaml b/Plugin.BurnIn/TestResultView.xaml
new file mode 100644
index 0000000..1c28689
--- /dev/null
+++ b/Plugin.BurnIn/TestResultView.xaml
@@ -0,0 +1,21 @@
+锘�<UserControl x:Class="Plugin.BurnIn.TestResultView"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+xmlns:uic="clr-namespace:HMI.UI.Converter;assembly=HMI.UI"
+xmlns:pw="https://opensource.panuon.com/wpf"
+xmlns:pu="https://opensource.panuon.com/wpf-ui"
+xmlns:ui="clr-namespace:HMI.UI;assembly=HMI.UI"
+xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ mc:Ignorable="d"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid x:Name="panel">
+ <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
+ <Grid x:Name="mainGrid" dp:GridHelper.Space="6">
+
+ </Grid>
+ </Grid>
+</UserControl>
diff --git a/Plugin.BurnIn/TestResultView.xaml.cs b/Plugin.BurnIn/TestResultView.xaml.cs
new file mode 100644
index 0000000..f58724d
--- /dev/null
+++ b/Plugin.BurnIn/TestResultView.xaml.cs
@@ -0,0 +1,683 @@
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using Plugin.BurnIn.Model;
+using Plugin.TsSupport;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Plugin.BurnIn
+{
+ /// <summary>
+ /// TestResultView.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ public partial class TestResultView : UserControl
+ {
+ private int rowCount;
+ private int colCount;
+ private int cellCount;
+
+ public static DataTable[] tables { get; private set; }
+ public static Dictionary<string, DataTable> nameTables { get; private set; } = new Dictionary<string, DataTable>();
+ private readonly BaseConfig config;
+
+
+
+ public string testModelFile;
+ public string testSeqFile;
+ public bool inManualDebugMode = false;
+
+ #region TS鐩稿叧
+ //public AxApplicationMgr testApp;
+ ///// <summary>
+ ///// 娴嬭瘯搴忓垪
+ ///// </summary>
+ //private SequenceFile testSeq = null;
+ //public Engine engine;
+ //private Execution execution = null;
+ ///// <summary>
+ ///// 娴嬭瘯搴忓垪鎿嶄綔鍙ユ焺
+ ///// </summary>
+ //public SequenceContext SequenceContext { get; private set; } = null;
+ ///// <summary>
+ ///// 娴嬭瘯妯″瀷搴忓垪
+ ///// </summary>
+ //private SequenceFile modeSeq;
+
+ public ITestExecutionWrapper executionWrapper;
+ #endregion
+
+ public TestResultView() : this(new BaseConfig { testing = false })
+ {
+
+ }
+
+ public bool IsRunning { get; set; } = false;
+
+ public void RefreshCooler()
+ {
+
+ }
+
+ private void RefreshNumberConfig(BaseConfig config)
+ {
+ ParameterData value = null;
+ try
+ {
+ value = ParameterManager.GetCommonParameterByName("BurnInOvenCount");
+ string[] datas = value.Value.Trim().Split(',');
+ config.Row = int.Parse(datas[0]);
+ config.Column = int.Parse(datas[1]);
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ try
+ {
+ value = ParameterManager.GetCommonParameterByName("BurnInOvenName");
+ config.NameStr = value.Value;
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ try
+ {
+ value = ParameterManager.GetCommonParameterByName("BurnInOvenPort");
+ config.PortStart = int.Parse(value.Value);
+ }
+ catch (Exception ex)
+ {
+
+ }
+
+ try
+ {
+ value = ParameterManager.GetCommonParameterByName("BurnInCellCount");
+ string[] datas = value.Value.Trim().Split(',');
+ config.PositionColumn = int.Parse(datas[0]);
+ config.PositionCount = int.Parse(datas[1]);
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ public TestResultView(BaseConfig config)
+ {
+ try
+ {
+ var value = ParameterManager.GetCommonParameterByName("TsModelPath");
+ testModelFile = value?.Value ?? @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
+ }
+ catch
+ {
+ //@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"
+ testModelFile = @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
+ }
+
+ RefreshNumberConfig(config);
+ this.rowCount = config.Row;
+ this.colCount = config.Column;
+ this.config = config;
+ if (config.CellCount < 0)
+ {
+ this.cellCount = rowCount * colCount;
+ }
+ else
+ {
+ this.cellCount = config.CellCount;
+ }
+ tables = new DataTable[this.cellCount];
+
+
+ InitializeComponent();
+
+
+ }
+
+ private void ExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+ {
+ try
+ {
+ HandleUIMessage(e.EventCode, Convert.ToInt16(e.NumberData), e.StrData, e.Data);
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ private void Refresh()
+ {
+ }
+
+ /// <summary>
+ /// 鎺㈤拡璁℃暟閰嶇疆璺緞
+ /// </summary>
+ private string CountIniPath;
+ public void SetCountIniPath(string countIniPath)
+ {
+ CountIniPath = countIniPath;
+ }
+
+ public void InitMainGrid()
+ {
+ nameTables = new Dictionary<string, DataTable>();
+ for (int r = 0; r < rowCount; r++)
+ {
+ RowDefinition row = new RowDefinition();
+ mainGrid.RowDefinitions.Add(row);
+ }
+
+ for (int c = 0; c < colCount; c++)
+ {
+ ColumnDefinition col = new ColumnDefinition();
+ mainGrid.ColumnDefinitions.Add(col);
+ }
+ string[] names = config.NameStr.Split(',');
+ for (int n = 0; n < cellCount; n++)
+ {
+ string name = n < names.Length ? names[n] : "";
+ DataTable child = new DataTable(this, n, name, CountIniPath, config);
+ mainGrid.Children.Add(child);
+ tables[n] = child;
+ nameTables[name] = child;
+ int row = n / colCount;
+ int col = n % colCount;
+ Grid.SetRow(child, row);
+ Grid.SetColumn(child, col);
+ }
+ if (config.testing) Refresh();
+ }
+
+ public DataTable GetDataTable(int index)
+ {
+ if (index >= 0 && index < tables.Length) return tables[index];
+ return null;
+ }
+
+ /// <summary>
+ /// 鍚姩娴嬭瘯搴忓垪
+ /// </summary>
+ public void InitTestStandEngine(bool isTap)
+ {
+ try
+ {
+ if (isTap)
+ {
+ executionWrapper = new TapWrapper();
+ }
+ else
+ {
+ executionWrapper = new TsExecutionWrapper();
+ }
+ executionWrapper.UIMessageEvent += ExecutionWrapper_UIMessageEvent;
+
+ if (executionWrapper is TsExecutionWrapper tsWrapper)
+ {
+ ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).BeginInit();
+ host.Child = tsWrapper.AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).EndInit();
+ }
+ //this.engine = this.testApp.GetEngine();
+ //this.engine.PersistBreakpoints = false;
+ //this.testApp.IsEditor = true;
+ //this.testApp.LoginOnStart = false;
+ //this.testApp.Start();
+ //this.modeSeq = this.engine.GetSequenceFileEx(testModelFile);
+ executionWrapper.Init();
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("InitTestStandEngine Failed.", ex);
+ throw new Exception($"{this.lang("Ts.InitTestStandEngineFail")}: {ex.Message}");
+ }
+ }
+
+ public void SetOvenName()
+ {
+ foreach (var oven in tables)
+ {
+ executionWrapper?.SetStationGlobalValue<string>($"StationHMI.UUTHMI[{oven.index}].Name", 1, oven.Name);
+ }
+ executionWrapper?.CommitToDisk(false);
+ }
+
+ public void StartTestSequence()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(testSeqFile)) return;
+ executionWrapper?.StartSequence(this.testSeqFile,
+ @"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
+
+ executionWrapper.SetStationGlobalValue<bool>("StationHMI.AllStop", 0, false);
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("StartTestSequence Failed.", ex);
+ throw new Exception($"{this.lang("Ts.StartTestSequenceFailed")}: {ex.Message}");
+ }
+ }
+
+ public void StopTest()
+ {
+ try
+ {
+ executionWrapper?.SetStationGlobalValue<bool>("StationState.StopTest", 0, true, true);
+
+ try
+ {
+ executionWrapper?.WaitForExit();
+ executionWrapper?.ReleaseSeqFile();
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("Wait For Exit error.", ex);
+ //if (ex is NullReferenceException ne)
+ //{
+
+ //}
+ //else
+ //{
+ // throw ex;
+ //}
+ }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Error("StopTest Failed.", ex);
+ throw new Exception($"{this.lang("Ts.StopTestSequenceFailed")}: {ex.Message}");
+ }
+ }
+
+ [Obsolete]
+ private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
+ {
+ //Environment.ExitCode = testApp.ExitCode;
+ //TSHelper.DoSynchronousGCForCOMObjectDestruction();
+ }
+
+ [Obsolete]
+ private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
+ {
+ try
+ {
+ //this.ReleaseSequenceFile();
+ }
+ catch (Exception ex)
+ {
+ MsgBoxHelper.Error(Window.GetWindow(this),
+ $"{this.lang("Ts.ReleaseSequenceFileFail")}: {ex.Message}");
+ }
+ }
+
+
+ private void HandleUIMessage(int EventCase, int MethodCode, string strData, object xData)
+ {
+ try
+ {
+ if (EventCase != 10014) return;
+
+ if (MethodCode == 0)
+ {
+ /// 璁剧疆鍙ユ焺
+ executionWrapper.SetContext(xData);
+ return;
+ }
+
+ if (MethodCode == 1)
+ {
+ /// 鏇存柊鐐夊瓙鐘舵��
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string status = datas_10014[1];
+ tables[ovenIndex].SetStatus(status);
+ return;
+ }
+ if (MethodCode == 2)
+ {
+ /// 鏇存柊鐐夊瓙鏁伴噺淇℃伅
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string okCount = datas_10014[1];
+ string ngCount = datas_10014[2];
+ tables[ovenIndex].SetOkCount(int.Parse(okCount));
+ tables[ovenIndex].SetNgCount(int.Parse(ngCount));
+ return;
+ }
+ if (MethodCode == 3)
+ {
+ /// 鏇存柊鐐夊瓙鏃堕棿淇℃伅
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+ string startTime = datas_10014[1];
+ string consumeTime = datas_10014[2];
+ string planEndTime = datas_10014[3];
+
+ tables[ovenIndex].SetStartTime(startTime);
+ tables[ovenIndex].SetEndTime(planEndTime);
+ double? leftTime = null;
+ /// 涓轰簡鍏煎鏃х増鏈紝濡傛灉鏈夊墿浣欐椂闂村氨浼狅紝娌℃湁灏变紶null
+ if (datas_10014.Length >= 5)
+ {
+ leftTime = double.Parse(datas_10014[4]);
+ }
+ tables[ovenIndex].UpdateConsumeTime(double.Parse(consumeTime), leftTime);
+ return;
+ }
+ if (MethodCode == 4)
+ {
+ /// 鏇存柊鑰佸寲鐐夊簳閮ㄧ姸鎬佹爮
+ string[] datas_10014 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10014[0]);
+
+ string statusBar = datas_10014[1];
+ tables[ovenIndex].SetStatusText(statusBar);
+ return;
+ }
+ if (MethodCode == 5)
+ {
+ /// 閲囬泦鐐夋俯搴�
+ string[] datas_10016 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10016[0]);
+
+ string[] names = datas_10016[1].Split(',');
+ string[] values = datas_10016[2].Split(',');
+
+ for (int x = 0; x < values.Length; x++)
+ {
+ if (x == 0) tables[ovenIndex].SetTemperature(double.Parse(values[x]));
+ else tables[ovenIndex].SetTemperature(names[x - 1], double.Parse(values[x]));
+ }
+ return;
+ }
+ if (MethodCode == 6)
+ {
+ Dispatcher.Invoke(() =>
+ {/// 鏇存柊绌翠綅鐘舵��
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+ string status_10015 = datas_10015[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).SetStatus(status_10015);
+
+ if (status_10015 == "OK" || status_10015 == "ok")
+ {
+ tables[ovenIndex].RefreshCount(1, 0);
+ }
+ else if (status_10015 == "ng" || status_10015 == "NG")
+ {
+ tables[ovenIndex].RefreshCount(0, 1);
+ }
+ });
+ return;
+ }
+ if (MethodCode == 7)
+ {
+ /// 鏇存柊绌翠綅鍙傛暟
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+
+ string strs = datas_10015[2];
+ string[] values = strs.Split(',');
+
+ //string step = datas_10015[2];
+ //string result = datas_10015[3];
+ tables[ovenIndex].GetSingleCell(cellIndex).SetInfos(new Info
+ {
+ step = values[0],
+ value = values[1],
+ limitUp = values[2],
+ limitDown = values[3],
+ unit = values[4],
+ result = values[5],
+ updateTime = values[6]
+ });
+ return;
+ }
+ if (MethodCode == 10)
+ {
+ /// 娓呯┖鐐夊瓙鐨勬俯搴﹀浘琛�
+ int ovenIndex = int.Parse(strData);
+ tables[ovenIndex].ClearChartData();
+ return;
+ }
+ if (MethodCode == 11)
+ {
+ /// 娓呴櫎绌翠綅鍙傛暟
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+ tables[ovenIndex].GetSingleCell(cellIndex).ClearInfo();
+ //GC.Collect();
+ return;
+ }
+ if (MethodCode == 12)
+ {
+ /// 淇濆瓨鐐変綋娓╁害鏂囦欢
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ string folder = datas[1];
+ tables[ovenIndex].SaveTempFile(folder);
+ return;
+ }
+ if (MethodCode == 13)
+ {
+ /// 娣诲姞鐢垫祦鏁版嵁
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ double eData = double.Parse(datas[2]);
+ tables[ovenIndex].GetSingleCell(cellIndex).AddElectricData(eData);
+ return;
+ }
+
+ if (MethodCode == 14)
+ {
+ /// 娓呯┖鐢垫祦鍜岀數鍘嬫暟鎹�
+ int ovenIndex = int.Parse(strData);
+ tables[ovenIndex].ClearCellData();
+ //tables[ovenIndex].ClearElectricData();
+ //tables[ovenIndex].ClearVData();
+ //tables[ovenIndex].ClearWaterData();
+ return;
+ }
+
+ if (MethodCode == 15)
+ {
+ /// 淇濆瓨鐢垫祦鏁版嵁
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ string filePath = datas[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).SaveElectricDataToCSV(filePath);
+ return;
+ }
+
+ if (MethodCode == 16)
+ {
+ /// 娣诲姞鐢靛帇鍥捐〃鏁版嵁
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ double eData = double.Parse(datas[2]);
+ tables[ovenIndex].GetSingleCell(cellIndex).AddVData(eData);
+ return;
+ }
+
+ if (MethodCode == 17)
+ {
+ /// 淇濆瓨鐢靛帇鏁版嵁
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ string filePath = datas[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).SaveVDataToCSV(filePath);
+ return;
+ }
+
+ if (MethodCode == 18)
+ {
+ /// 淇濆瓨绌翠綅娴嬭瘯鏁版嵁鍒癈SV
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ string filePath = datas[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).SaveInfoToCSV(filePath);
+ return;
+ }
+ if (MethodCode == 180)
+ {
+ /// 淇濆瓨绌翠綅娴嬭瘯鏁版嵁鍒癈SV
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ string filePath = datas[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).NormalCSV(filePath);
+ return;
+ }
+
+ if (MethodCode == 19)
+ {
+ /// 淇濆瓨绌翠綅娴嬭瘯鏁版嵁鍒癝qlite
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ tables[ovenIndex].GetSingleCell(cellIndex).SaveInfoToDB();
+ return;
+ }
+
+ if (MethodCode == 20)
+ {
+ /// 娓呯┖鏉$爜
+ int ovenIndex = int.Parse(strData);
+ tables[ovenIndex].ClearAllSN();
+ return;
+ }
+
+ if (MethodCode == 21)
+ {
+ /// 娣诲姞姘存祦鍥捐〃鏁版嵁
+ string[] datas = strData.Split(';');
+ int ovenIndex = int.Parse(datas[0]);
+ int cellIndex = int.Parse(datas[1]);
+ double waterTemp = double.Parse(datas[2]);
+ double backWaterTemp = double.Parse(datas[3]);
+ double waterPressure = double.Parse(datas[4]);
+ tables[ovenIndex].GetSingleCell(cellIndex).AddWaterData(waterTemp, backWaterTemp, waterPressure);
+ return;
+ }
+
+ if (MethodCode == 99)
+ {
+ string[] datas = strData.Split(';');
+ int index = int.Parse(datas[0]);
+ if (MsgBoxHelper2.WarnChoose(datas[1], "鎻愮ず") == MessageBoxResult.OK)
+ {
+ executionWrapper.SetStationGlobalValue<int>($"StationState.Pipe[{index}]", 1, 1);
+ //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 1);
+ }
+ else
+ {
+ executionWrapper.SetStationGlobalValue<int>($"StationState.Pipe[{index}]", 1, 0);
+ //SequenceContext.StationGlobals.SetValNumber($"StationState.Pipe[{index}]", 1, 0);
+ }
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Warn("TestStand Event Error.", ex);
+ }
+ }
+
+ private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+ {
+ int EventCase = Convert.ToInt32(e.uiMsg.Event);
+ int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
+ string strData = e.uiMsg.StringData;
+ HandleUIMessage(EventCase, MethodCode, strData, e.uiMsg.ActiveXData);
+ }
+
+ public void SetStartFlag(int index, bool data)
+ {
+ string name = tables[index].title;
+ string key = string.Empty;
+ if (data)
+ {
+ BurnInUI.Logger?.Info($"鍚姩鑰佸寲鐐塠{name}]");
+ key = $"StationHMI.UUTHMI[{index}].Start";
+ }
+ else
+ {
+ BurnInUI.Logger?.Info($"鍋滄鑰佸寲鐐塠{name}]");
+ key = $"StationHMI.UUTHMI[{index}].Stop";
+ }
+ executionWrapper?.SetStationGlobalValue<bool>(key, 1, true);
+ }
+
+ public void ReleaseResource()
+ {
+ executionWrapper.UIMessageEvent -= ExecutionWrapper_UIMessageEvent;
+
+ foreach (var table in tables)
+ {
+ table.RelaseResource();
+ }
+ }
+
+ /// <summary>
+ /// 璁℃暟娓呴浂
+ /// </summary>
+ public void ClearNumber()
+ {
+ foreach (var table in tables)
+ {
+ table.ClearNumber();
+ }
+ }
+
+ public void SetProductSource(List<string> productSource)
+ {
+ foreach (var table in tables)
+ {
+ table.SetProductSource(productSource);
+ }
+ }
+
+ public void SetCurrentProduct(string currentProduct)
+ {
+ for (int i = 0; i < tables.Length; i++)
+ {
+ var table = tables[i];
+ string LookupStr = $"StationHMI.UUTHMI[{i}].Model";
+
+ string tableModel = executionWrapper?.GetStationGlobalValue<string>(LookupStr, 1);
+ //engine?.Globals?.GetValString(LookupStr, 1);
+ table.SetCurrentProduct(tableModel);
+ }
+ }
+
+ public void SetOvenProduct(int index, string product)
+ {
+ string LookupStr = $"StationHMI.UUTHMI[{index}].Model";
+ executionWrapper?.SetStationGlobalValue<string>(LookupStr, 1, product);
+ executionWrapper?.CommitToDisk(false);
+ }
+
+ public void RefreshProducts()
+ {
+ }
+ }
+}
diff --git a/Plugin.BurnIn/UI/LiveChart.xaml b/Plugin.BurnIn/UI/LiveChart.xaml
new file mode 100644
index 0000000..72d5fce
--- /dev/null
+++ b/Plugin.BurnIn/UI/LiveChart.xaml
@@ -0,0 +1,29 @@
+锘�<hb:NotifyControl x:Class="Plugin.BurnIn.LiveChart"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.BurnIn"
+ mc:Ignorable="d"
+
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
+
+ Loaded="UserControl_Loaded"
+ Unloaded="UserControl_Unloaded"
+ SizeChanged="UserControl_SizeChanged"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <Grid>
+ <lvc:CartesianChart Series="{Binding Series}" BorderThickness="1" BorderBrush="Black"
+ Padding="0"
+ Margin="2"
+ SyncContext="{Binding Sync}"
+ XAxes="{Binding XAxes}"
+ YAxes="{Binding YAxes}"
+ TooltipTextPaint="{Binding TooltipTextPaint}"
+ TooltipTextSize="{Binding TooltipTextSize}"
+ DrawMarginFrame="{Binding DrawMarginFrame}"
+ x:Name="chart">
+ </lvc:CartesianChart>
+ </Grid>
+</hb:NotifyControl>
diff --git a/Plugin.BurnIn/UI/LiveChart.xaml.cs b/Plugin.BurnIn/UI/LiveChart.xaml.cs
new file mode 100644
index 0000000..6e5ad76
--- /dev/null
+++ b/Plugin.BurnIn/UI/LiveChart.xaml.cs
@@ -0,0 +1,516 @@
+锘縰sing HMI.Base;
+using LiveChartsCore;
+using LiveChartsCore.Defaults;
+using LiveChartsCore.Drawing;
+using LiveChartsCore.Drawing.Layouts;
+using LiveChartsCore.Kernel.Sketches;
+using LiveChartsCore.SkiaSharpView;
+using LiveChartsCore.SkiaSharpView.Drawing;
+using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
+using LiveChartsCore.SkiaSharpView.Drawing.Layouts;
+using LiveChartsCore.SkiaSharpView.Painting;
+using LiveChartsCore.SkiaSharpView.SKCharts;
+using SkiaSharp;
+using System.Collections.ObjectModel;
+
+namespace Plugin.BurnIn
+{
+ public class SeriesConfig
+ {
+ public static readonly float FontSize = 12;
+ /// <summary>
+ /// 鏁版嵁鍚�
+ /// </summary>
+ public string Name { get; set; }
+ public string YAxesName { get; set; }
+ public int YAxesIndex { get; set; }
+ }
+
+ public class CustomLegend : SKDefaultLegend
+ {
+
+ protected override Layout<SkiaSharpDrawingContext> GetLayout(LiveChartsCore.Chart chart)
+ {
+ var stackLayout = new StackLayout
+ {
+ Orientation = ContainerOrientation.Horizontal,
+ Padding = new Padding(0, 10, 0, 0),
+ HorizontalAlignment = Align.Start,
+ VerticalAlignment = Align.Middle,
+ };
+
+ foreach (var series in chart.Series.Where(x => x.IsVisibleAtLegend))
+ {
+ stackLayout.Children.Add(new LegendItem(series));
+ }
+ return stackLayout;
+ }
+ }
+
+ public class LegendItem : StackLayout
+ {
+ public LegendItem(ISeries series)
+ {
+ Orientation = ContainerOrientation.Horizontal;
+ Padding = new Padding(0);
+ VerticalAlignment = Align.Start;
+ HorizontalAlignment = Align.Middle;
+ Opacity = series.IsVisible ? 1 : 0.5f;
+
+ var miniature = (IDrawnElement<SkiaSharpDrawingContext>)series.GetMiniatureGeometry(null);
+ Children = new List<IDrawnElement<SkiaSharpDrawingContext>> {
+ miniature,
+ new LabelGeometry
+ {
+ Text = series.Name,
+ TextSize = SeriesConfig.FontSize,
+ Paint = new SolidColorPaint(SKColors.Black){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new Padding(5,0,10,0),
+ VerticalAlign = Align.Middle,
+ HorizontalAlign = Align.Start
+ }};
+ }
+ }
+
+ public partial class LiveChart : NotifyControl
+ {
+ private static SKColor[] colors = new SKColor[] {
+ //new SKColor(229, 84, 62),
+ //new SKColor(72, 143, 239),
+ //new SKColor(147, 196, 83),
+ new SKColor(255, 0, 0),
+ new SKColor(0, 0, 255),
+ new SKColor(0, 255, 0),
+ new SKColor(76, 184, 210),
+ new SKColor(246, 198, 50),
+ };
+
+ private DateTime startTime;
+ private string configText;
+ private bool showLegend;
+ private bool enableResize;
+
+ private SolidColorPaint tooltipTextPaint = new SolidColorPaint(SKColors.Black)
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ };
+ public SolidColorPaint TooltipTextPaint
+ {
+ get => tooltipTextPaint;
+ set
+ {
+ Set(ref tooltipTextPaint, value);
+ }
+ }
+
+ private double tooltipTextSize = SeriesConfig.FontSize;
+ public double TooltipTextSize
+ {
+ get => tooltipTextSize;
+ set
+ {
+ Set(ref tooltipTextSize, value);
+ }
+ }
+
+ private Dictionary<string, SeriesConfig> configCache = new Dictionary<string, SeriesConfig>();
+
+ private Dictionary<string, ISeries> seriesCache = new Dictionary<string, ISeries>();
+ private Dictionary<string, List<DateTimePoint>> valueCache = new Dictionary<string, List<DateTimePoint>>();
+
+ private Dictionary<string, double> minValueCache = new Dictionary<string, double>();
+ private Dictionary<string, double> maxValueCache = new Dictionary<string, double>();
+
+ private ObservableCollection<ISeries> series = new ObservableCollection<ISeries>();
+ public ObservableCollection<ISeries> Series
+ {
+ get => series;
+ set
+ {
+
+ Set(ref series, value);
+ }
+ }
+
+ public ObservableCollection<ICartesianAxis> YAxes { get; set; } = new ObservableCollection<ICartesianAxis>();
+
+ private Axis[] xAxes;
+ public Axis[] XAxes
+ {
+ get => xAxes; set
+ {
+ Set(ref xAxes, value);
+ }
+ }
+
+ public DrawMarginFrame DrawMarginFrame => new DrawMarginFrame()
+ {
+ Fill = new SolidColorPaint(new SKColor(223, 223, 223)),
+ Stroke = new SolidColorPaint(new SKColor(180, 180, 180), 1)
+ };
+
+ public object Sync { get; } = new object();
+
+ private int CreateYAxis(string name)
+ {
+ for (int i = 0; i < YAxes.Count; i++)
+ {
+ if (YAxes[i].Name == name)
+ {
+ return i;
+ }
+ }
+ if (YAxes.Count == 0)
+ {
+ YAxes.Add(new Axis
+ {
+ Name = name,
+ MinStep = 1,
+ TextSize = SeriesConfig.FontSize,
+ NameTextSize = SeriesConfig.FontSize,
+ NamePaint = new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new Padding(0, 0, 5, 0),
+ LabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
+ SeparatorsPaint = new SolidColorPaint
+ {
+ Color = SKColors.Black.WithAlpha(30),
+ StrokeThickness = 0.5f
+ },
+ TicksPaint = new SolidColorPaint
+ {
+ Color = SKColor.Empty,
+ StrokeThickness = 0
+ },
+ });
+ }
+ else
+ {
+ YAxes.Add(new Axis
+ {
+ Name = name,
+ Position = LiveChartsCore.Measure.AxisPosition.End,
+ MinStep = 1,
+ TextSize = SeriesConfig.FontSize,
+ NameTextSize = SeriesConfig.FontSize,
+ NamePaint = new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new Padding(5, 0, 0, 0),
+ LabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
+ TicksPaint = new SolidColorPaint
+ {
+ Color = SKColor.Empty,
+ StrokeThickness = 0
+ },
+ ShowSeparatorLines = false,
+ });
+ }
+ return YAxes.Count - 1;
+ }
+
+ public void RefreshConfig(string configStr)
+ {
+ configText = configStr;
+ configCache.Clear();
+ seriesCache.Clear();
+ valueCache.Clear();
+ minValueCache.Clear();
+ maxValueCache.Clear();
+ Series.Clear();
+ YAxes.Clear();
+ startTime = DateTime.MinValue;
+ try
+ {
+ string[] arr = configStr.Split(';');
+ for (int i = 0; i < arr.Length; i++)
+ {
+ var config = arr[i];
+ string[] datas = config.Split(',');
+ var sConfig = new SeriesConfig();
+ if (datas.Length >= 2)
+ {
+ sConfig.YAxesName = datas[1];
+ }
+ else
+ {
+ sConfig.YAxesName = datas[0];
+ }
+
+ sConfig.Name = datas[0];
+ sConfig.YAxesIndex = CreateYAxis(sConfig.YAxesName);
+ if (!string.IsNullOrEmpty(sConfig.Name))
+ {
+ configCache[sConfig.Name] = sConfig;
+ var values = new List<DateTimePoint>();
+ valueCache[sConfig.Name] = values;
+
+ var ls = new LineSeries<DateTimePoint>
+ {
+ Name = sConfig.Name,
+ Values = values,
+ ScalesYAt = sConfig.YAxesIndex,
+ Fill = null,
+ GeometryFill = null,
+ GeometryStroke = null,
+ LineSmoothness = 0,
+ Stroke = new SolidColorPaint(GetColor(i)) { StrokeThickness = 0.8f },
+ };
+ seriesCache[sConfig.Name] = ls;
+ Series.Add(ls);
+ }
+ }
+ if (showLegend)
+ {
+ chart.LegendPosition = LiveChartsCore.Measure.LegendPosition.Top;
+ chart.Legend = new CustomLegend();
+ }
+ chart.TooltipTextPaint = new SolidColorPaint(SKColors.Black)
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ };
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ public LiveChart(string configStr, bool showLegend = true, bool enableResize = false)
+ {
+ DataContext = this;
+ this.showLegend = showLegend;
+ this.enableResize = enableResize;
+
+ var xAxis = new DateTimeAxis(TimeSpan.FromSeconds(10), Formatter)
+ {
+ Padding = new Padding(0),
+ TextSize = SeriesConfig.FontSize,
+ NameTextSize = SeriesConfig.FontSize,
+ CustomSeparators = GetSeparators(),
+ AnimationsSpeed = TimeSpan.FromMilliseconds(0),
+ SeparatorsPaint = new SolidColorPaint(SKColors.Black.WithAlpha(30)),
+ };
+
+ XAxes = new Axis[] { xAxis };
+ InitializeComponent();
+ RefreshConfig(configStr);
+ }
+
+ private double[] GetSeparators()
+ {
+ if (valueCache.Count <= 0)
+ {
+ return new double[] { DateTime.Now.Ticks };
+ }
+ if (valueCache.Values.First().Count <= 5)
+ {
+ //return new double[] { now.Ticks };
+ return valueCache.Values.First().Select(e => (double)e.DateTime.Ticks).ToArray();
+ }
+ var now = valueCache.Values.First().Last().DateTime;
+
+ var step = (now - startTime).TotalSeconds / 6;
+
+ return
+ new double[] {
+ now.AddSeconds(-5*step).Ticks,
+ now.AddSeconds(-4*step).Ticks,
+ now.AddSeconds(-3*step).Ticks,
+ now.AddSeconds(-2*step).Ticks,
+ now.AddSeconds(-step).Ticks,
+ };
+ }
+
+ private static string Formatter(DateTime date)
+ {
+ //var secsAgo = (DateTime.Now - date).TotalSeconds;
+ //return secsAgo < 1
+ // ? "now"
+ // : $"{secsAgo:N0}s ago";
+ return date.ToString("HH:mm:ss");
+ }
+
+ private void RefreshChart()
+ {
+ XAxes[0].CustomSeparators = GetSeparators();
+ }
+
+ private double GetMaxByName(string name)
+ {
+ return maxValueCache.ContainsKey(name) ? maxValueCache[name] : double.MinValue;
+ }
+
+ private double GetMinByName(string name)
+ {
+ return minValueCache.ContainsKey(name) ? minValueCache[name] : double.MaxValue;
+ }
+
+ //public void AddData(string name, double value)
+ //{
+ // var now = DateTime.Now;
+ // if (valueCache.ContainsKey(name))
+ // {
+ // var config = configCache[name];
+ // valueCache[name].Add(new DateTimePoint(now, value));
+
+
+ // minValueCache[config.YAxesName] = Math.Min(GetMinByName(config.YAxesName), value);
+ // maxValueCache[config.YAxesName] = Math.Max(GetMaxByName(config.YAxesName), value);
+
+ // YAxes[config.YAxesIndex].MinLimit = minValueCache[config.YAxesName] - 1;
+ // YAxes[config.YAxesIndex].MaxLimit = maxValueCache[config.YAxesName] + 1;
+
+ // RefreshChart();
+ // }
+ // if (startTime == DateTime.MinValue)
+ // {
+ // startTime = now;
+ // }
+ //}
+
+ private SKColor GetColor(int index)
+ {
+ if (index >= colors.Length)
+ {
+ return colors[index % colors.Length];
+ }
+ return colors[index];
+ }
+
+ private void AddNewSeries(string name, string YName)
+ {
+ var config = new SeriesConfig
+ {
+ Name = name,
+ YAxesName = YName,
+ YAxesIndex = CreateYAxis(YName)
+ };
+ configCache[name] = config;
+
+ var values = new List<DateTimePoint>();
+ valueCache[name] = values;
+
+ var ls = new LineSeries<DateTimePoint>
+ {
+ Name = name,
+ Values = values,
+ ScalesYAt = config.YAxesIndex,
+ Fill = null,
+ GeometryFill = null,
+ GeometryStroke = null,
+ LineSmoothness = 0,
+ Stroke = new SolidColorPaint(GetColor(Series.Count)) { StrokeThickness = 0.8f },
+ };
+ seriesCache[Name] = ls;
+ Series.Add(ls);
+ }
+
+ public void AddDynamicData(string name, string YName, DateTime now, double value)
+ {
+ if (!valueCache.ContainsKey(name))
+ {
+ AddNewSeries(name, YName);
+ }
+
+ var config = configCache[name];
+ valueCache[name].Add(new DateTimePoint(now, value));
+
+
+ minValueCache[config.YAxesName] = Math.Min(GetMinByName(config.YAxesName), value);
+ maxValueCache[config.YAxesName] = Math.Max(GetMaxByName(config.YAxesName), value);
+
+ YAxes[config.YAxesIndex].MinLimit = minValueCache[config.YAxesName] - 1;
+ YAxes[config.YAxesIndex].MaxLimit = maxValueCache[config.YAxesName] + 1;
+
+ RefreshChart();
+
+
+ if (startTime == DateTime.MinValue)
+ {
+ startTime = now;
+ }
+ }
+
+ public void AddData(string name, DateTime now, double value)
+ {
+ if (valueCache.ContainsKey(name))
+ {
+ var config = configCache[name];
+ valueCache[name].Add(new DateTimePoint(now, value));
+
+
+ minValueCache[config.YAxesName] = Math.Min(GetMinByName(config.YAxesName), value);
+ maxValueCache[config.YAxesName] = Math.Max(GetMaxByName(config.YAxesName), value);
+
+ YAxes[config.YAxesIndex].MinLimit = minValueCache[config.YAxesName] - 1;
+ YAxes[config.YAxesIndex].MaxLimit = maxValueCache[config.YAxesName] + 1;
+
+ RefreshChart();
+ }
+ if (startTime == DateTime.MinValue)
+ {
+ startTime = now;
+ }
+ }
+
+ public void Clear()
+ {
+ RefreshConfig(configText);
+ }
+
+ public bool CanHandle(string name)
+ {
+ return configCache.ContainsKey(name);
+ }
+
+ public List<double> GetSingleData(string name)
+ {
+ if (valueCache.ContainsKey(name))
+ {
+ return valueCache[name].Select(d => d.Value.Value).ToList();
+ }
+ return null;
+ }
+
+ private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ //refreshTimer.Start();
+ //timer?.Start();
+ }
+
+ private void UserControl_Unloaded(object sender, System.Windows.RoutedEventArgs e)
+ {
+ //timer?.Stop();
+ }
+
+ private void UserControl_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
+ {
+ if (enableResize)
+ {
+ var size = FontSizeConverter.CountFontSize(12, ActualHeight, 92);
+ foreach (var y in YAxes)
+ {
+ y.TextSize = size;
+ y.NameTextSize = size;
+ }
+
+ foreach (var x in XAxes)
+ {
+ x.TextSize = size;
+ x.NameTextSize = size;
+ }
+ TooltipTextSize = size;
+ //TooltipTextPaint = new SolidColorPaint(SKColors.Black)
+ //{
+ // SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ //};
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/CommonCodeParser.cs b/Plugin.BurnIn/Util/CommonCodeParser.cs
new file mode 100644
index 0000000..7acea73
--- /dev/null
+++ b/Plugin.BurnIn/Util/CommonCodeParser.cs
@@ -0,0 +1,28 @@
+锘縰sing Plugin.BurnIn.Model;
+
+namespace Plugin.BurnIn.Util
+{
+ public class CommonCodeParser : ICodeParser
+ {
+ public CellInfo GetCellInfoByCode(string code)
+ {
+ string[] arr = code.Split('-');
+ if (arr == null || arr.Length != 3)
+ {
+ throw new Exception("鎵爜鏍煎紡寮傚父");
+ }
+ return new CellInfo()
+ {
+ OriginCode = code,
+ MachineName = arr[0],
+ OvenName = arr[1],
+ Index = int.Parse(arr[2]) - 1,
+ };
+ }
+
+ public CellInfo GetCellInfoByCode(string model, int columns, int rows, string code)
+ {
+ return GetCellInfoByCode(code);
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/DpUtil.cs b/Plugin.BurnIn/Util/DpUtil.cs
new file mode 100644
index 0000000..c1bfd5a
--- /dev/null
+++ b/Plugin.BurnIn/Util/DpUtil.cs
@@ -0,0 +1,220 @@
+锘縰sing System.Windows;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Media;
+
+namespace Plugin.BurnIn
+{
+ public class GridProperties
+ {
+ public static bool GetShowBorder(DependencyObject obj)
+ {
+ return (bool)obj.GetValue(ShowBorderProperty);
+ }
+ public static void SetShowBorder(DependencyObject obj, bool value)
+ {
+ obj.SetValue(ShowBorderProperty, value);
+ }
+ public static readonly DependencyProperty ShowBorderProperty =
+ DependencyProperty.RegisterAttached("ShowBorder", typeof(bool), typeof(Grid), new PropertyMetadata(false, OnShowBorderChanged));
+
+ public static int GetBorderSpace(DependencyObject obj)
+ {
+ return (int)obj.GetValue(BorderSpaceProperty);
+ }
+ public static void SetBorderSpace(DependencyObject obj, int value)
+ {
+ obj.SetValue(BorderSpaceProperty, value);
+ }
+ public static readonly DependencyProperty BorderSpaceProperty =
+ DependencyProperty.RegisterAttached("BorderSpace", typeof(int), typeof(Grid), new PropertyMetadata(0, OnShowBorderChanged));
+
+
+
+ private static void OnShowBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is Grid grid)
+ {
+ if (e.Property == ShowBorderProperty)
+ {
+ grid.Loaded += GridInnerBorderLoaded;
+ return;
+ }
+ else if (e.Property == BorderSpaceProperty)
+ {
+ grid.Loaded += GridSpaceOnLoaded;
+ return;
+ }
+ }
+ else if (d is UniformGrid uniformGrid)
+ {
+ uniformGrid.Loaded += UniformGridOnLoad;
+ return;
+ }
+ }
+
+ private static void GridInnerBorderLoaded(object sender, RoutedEventArgs e)
+ {
+ if (!(sender is Grid grid)) return;
+ var rowCount = grid.RowDefinitions.Count;
+ var columnCount = grid.ColumnDefinitions.Count;
+ int totalCount = rowCount * columnCount;
+
+ int width = 1;
+
+ string baseData = "None";
+ HashSet<string> data = new HashSet<string>(baseData.Split(','));
+ bool ignoreTop = data.Contains("All") || data.Contains("Top"),
+ ignoreBottom = data.Contains("All") || data.Contains("Bottom"),
+ ignoreLeft = data.Contains("All") || data.Contains("Left"),
+ ignoreRight = data.Contains("All") || data.Contains("Right");
+
+ foreach (var child in grid.Children)
+ {
+ int row = Grid.GetRow((UIElement)child);
+ int col = Grid.GetColumn((UIElement)child);
+
+ var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0,
+ row == 0 ? (ignoreTop ? 0 : width) : 0,
+ (col == columnCount - 1 && ignoreRight) ? 0 : width,
+ width);
+
+ if (child is UserControl control)
+ {
+ control.BorderBrush = Brushes.Black;
+ control.BorderThickness = bt;
+ }
+
+ if (child is Label label)
+ {
+ label.BorderBrush = Brushes.Black;
+ label.BorderThickness = bt;
+ }
+
+ if (child is TextBox box)
+ {
+ box.BorderBrush = Brushes.Black;
+ box.BorderThickness = bt;
+ }
+ }
+
+ /// 寮冪敤
+ //for (int i = 0; i < totalCount; i++)
+ //{
+ // int row = i / columnCount;
+ // int col = i % columnCount;
+
+ // if (i > grid.Children.Count - 1) {
+ // continue;
+ // }
+ // var cell = grid.Children[i];
+ // var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0,
+ // row == 0 ? (ignoreTop ? 0 : width) : 0,
+ // (col == columnCount - 1 && ignoreRight) ? 0 : width,
+ // width);
+
+ // if (cell is UserControl child)
+ // {
+ // child.BorderBrush = Brushes.Black;
+ // child.BorderThickness = bt;
+ // }
+
+ // if (cell is Label label)
+ // {
+ // label.BorderBrush = Brushes.Black;
+ // label.BorderThickness = bt;
+ // }
+
+ // if (cell is TextBox box)
+ // {
+ // box.BorderBrush = Brushes.Black;
+ // box.BorderThickness = bt;
+ // }
+ //}
+ grid.Loaded -= GridInnerBorderLoaded;
+ }
+
+ private static void GridSpaceOnLoaded(object sender, RoutedEventArgs e)
+ {
+ if (!(sender is Grid grid)) return;
+ int space = GetBorderSpace(grid);
+ if (space <= 0)
+ {
+ return;
+ }
+
+ var rowCount = grid.RowDefinitions.Count;
+ var columnCount = grid.ColumnDefinitions.Count;
+ int totalCount = rowCount * columnCount;
+
+ for (int i = 0; i < totalCount; i++)
+ {
+ int row = i / columnCount;
+ int col = i % columnCount;
+
+ if (i > grid.Children.Count - 1)
+ {
+ continue;
+ }
+ var cell = grid.Children[i];
+
+ var bt = new Thickness(col == 0 ? space : 0, row == 0 ? space : 0, space, space);
+
+ if (cell is UserControl child)
+ {
+ child.Margin = bt;
+ }
+ }
+ grid.Loaded -= GridSpaceOnLoaded;
+ }
+
+ private static void UniformGridOnLoad(object sender, RoutedEventArgs e)
+ {
+ if (!(sender is UniformGrid grid)) return;
+ //var rowCount = grid.Rows;
+ int columnCount = grid.Columns;
+ int totalCount = grid.Children.Count;
+ int rowCount = totalCount / columnCount;
+ int width = 1;
+
+ for (int i = 0; i < grid.Children.Count; i++)
+ {
+ int row = i / columnCount;
+ int col = i % columnCount;
+ var child = grid.Children[i];
+
+ string baseData = "None";
+ HashSet<string> data = new HashSet<string>(baseData.Split(','));
+ bool ignoreTop = data.Contains("All") || data.Contains("Top"),
+ ignoreBottom = data.Contains("All") || data.Contains("Bottom"),
+ ignoreLeft = data.Contains("All") || data.Contains("Left"),
+ ignoreRight = data.Contains("All") || data.Contains("Right");
+
+ var bt = new Thickness(col == 0 ? (ignoreLeft ? 0 : width) : 0,
+ row == 0 ? (ignoreTop ? 0 : width) : 0,
+ (col == columnCount - 1 && ignoreRight) ? 0 : width,
+ (row == rowCount && ignoreBottom) ? 0 : width);
+
+ if (child is UserControl control)
+ {
+ control.BorderBrush = Brushes.Black;
+ control.BorderThickness = bt;
+ }
+
+ if (child is Label label)
+ {
+ label.BorderBrush = Brushes.Black;
+ label.BorderThickness = bt;
+ }
+
+ if (child is TextBox box)
+ {
+ box.BorderBrush = Brushes.Black;
+ box.BorderThickness = bt;
+ }
+ }
+ grid.Loaded -= UniformGridOnLoad;
+ }
+ }
+
+}
diff --git a/Plugin.BurnIn/Util/FontSizeConverter.cs b/Plugin.BurnIn/Util/FontSizeConverter.cs
new file mode 100644
index 0000000..9e04df9
--- /dev/null
+++ b/Plugin.BurnIn/Util/FontSizeConverter.cs
@@ -0,0 +1,32 @@
+锘縰sing System.Globalization;
+using System.Windows.Data;
+
+namespace Plugin.BurnIn
+{
+ public class FontSizeConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (parameter == null) return 15;
+
+ string[] ps = parameter.ToString().Split(',');
+ int size = int.Parse(ps[0]);
+ int baseSize = int.Parse(ps[1]);
+ if (value is double width)
+ {
+ return CountFontSize(size, width, baseSize);
+ }
+ return 15;
+ }
+
+ public static double CountFontSize(double size, double limit, double baseSize)
+ {
+ return size * limit / baseSize;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/ICodeParser.cs b/Plugin.BurnIn/Util/ICodeParser.cs
new file mode 100644
index 0000000..ef4865d
--- /dev/null
+++ b/Plugin.BurnIn/Util/ICodeParser.cs
@@ -0,0 +1,10 @@
+锘縰sing Plugin.BurnIn.Model;
+
+namespace Plugin.BurnIn.Util
+{
+ public interface ICodeParser
+ {
+ CellInfo GetCellInfoByCode(string code);
+ CellInfo GetCellInfoByCode(string model,int columns,int rows, string code);
+ }
+}
diff --git a/Plugin.BurnIn/Util/JKCodeParser.cs b/Plugin.BurnIn/Util/JKCodeParser.cs
new file mode 100644
index 0000000..1176191
--- /dev/null
+++ b/Plugin.BurnIn/Util/JKCodeParser.cs
@@ -0,0 +1,30 @@
+锘縰sing Plugin.BurnIn.Model;
+
+namespace Plugin.BurnIn.Util
+{
+ public class JKCodeParser : ICodeParser
+ {
+ public CellInfo GetCellInfoByCode(string code)
+ {
+ string[] arr = code.Split('-');
+ if (arr == null || arr.Length != 3)
+ {
+ throw new Exception("鎵爜鏍煎紡寮傚父");
+ }
+ int row = int.Parse(arr[1]);
+ int index = int.Parse(arr[2]);
+
+ return new CellInfo()
+ {
+ OriginCode = code,
+ OvenName = arr[0],
+ Index = (row - 1) * 4 + (index - 1),
+ };
+ }
+
+ public CellInfo GetCellInfoByCode(string model, int columns, int rows, string code)
+ {
+ return GetCellInfoByCode(code);
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/ModelCodeParser.cs b/Plugin.BurnIn/Util/ModelCodeParser.cs
new file mode 100644
index 0000000..da04201
--- /dev/null
+++ b/Plugin.BurnIn/Util/ModelCodeParser.cs
@@ -0,0 +1,97 @@
+锘縰sing HMI.Core.Entity;
+using HMI.Core.Manager;
+using Plugin.BurnIn.Model;
+
+namespace Plugin.BurnIn.Util
+{
+ public class ModelCodeParser : ICodeParser
+ {
+ public CellInfo GetCellInfoByCode(string code)
+ {
+ string[] arr = code.Split('-');
+ if (arr == null || arr.Length != 3)
+ {
+ throw new Exception("鎵爜鏍煎紡寮傚父");
+ }
+ return new CellInfo()
+ {
+ OriginCode = code,
+ MachineName = arr[0],
+ OvenName = arr[1],
+ Index = int.Parse(arr[2]) - 1,
+ };
+ }
+
+ public CellInfo GetCellInfoByCode(string model, int columns, int rows, string code)
+ {
+ var list = ProductManager.GetParametersByProductName(model);
+ ParameterData config = null;
+ if (list != null && list.Count > 0)
+ {
+ config = list.Where(e => e.Name == "PositionCodeConfig").FirstOrDefault();
+ }
+ if (string.IsNullOrEmpty(config?.Value))
+ {
+ // 浜у搧娌℃湁灏辨寜榛樿鐨勫幓閰�
+ config = ParameterManager.GetCommonParameterByName("PositionCodeConfig");
+ if (string.IsNullOrEmpty(config?.Value))
+ {
+ throw new Exception($"褰撳墠鍨嬪彿[{model}]鏈厤缃┐浣嶈鍒�");
+ }
+ }
+ string value = config.Value;
+ string[] arr = value?.Split(';');
+ try
+ {
+ if (arr.Length == 2)
+ {
+ string[] v1s = arr[0].Split(',');
+ string[] v2s = arr[1].Split(',');
+
+ return new CellInfo
+ {
+ OriginCode = code,
+ OvenName = code.Substring(int.Parse(v1s[0]), int.Parse(v1s[1])),
+ Index = int.Parse(code.Substring(int.Parse(v2s[0]), int.Parse(v2s[1]))) - 1
+ };
+ }
+ else if (arr.Length == 3)
+ {
+ string[] v1s = arr[0].Split(',');
+ string[] v2s = arr[1].Split(',');
+ string[] v3s = arr[2].Split(',');
+
+ int row = int.Parse(code.Substring(int.Parse(v2s[0]), int.Parse(v2s[1])));
+ int index = int.Parse(code.Substring(int.Parse(v3s[0]), int.Parse(v3s[1])));
+
+ return new CellInfo()
+ {
+ OriginCode = code,
+ OvenName = code.Substring(int.Parse(v1s[0]), int.Parse(v1s[1])),
+ Index = (row - 1) * columns + (index - 1),
+ };
+ }
+ else if (arr.Length >= 4)
+ {
+ string[] v1s = arr[0].Split(',');
+ string[] v2s = arr[1].Split(',');
+ string[] v3s = arr[2].Split(',');
+ columns = int.Parse(arr[3]);
+ int row = int.Parse(code.Substring(int.Parse(v2s[0]), int.Parse(v2s[1])));
+ int index = int.Parse(code.Substring(int.Parse(v3s[0]), int.Parse(v3s[1])));
+ return new CellInfo()
+ {
+ OriginCode = code,
+ OvenName = code.Substring(int.Parse(v1s[0]), int.Parse(v1s[1])),
+ Index = (row - 1) * columns + (index - 1),
+ };
+ }
+ throw new Exception($"褰撳墠鍨嬪彿[{model}]绌翠綅瑙勫垯閰嶇疆寮傚父");
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"褰撳墠鍨嬪彿[{model}]瑙f瀽寮傚父:{ex.Message}", ex);
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/PNUtil.cs b/Plugin.BurnIn/Util/PNUtil.cs
new file mode 100644
index 0000000..955f732
--- /dev/null
+++ b/Plugin.BurnIn/Util/PNUtil.cs
@@ -0,0 +1,106 @@
+锘縰sing HMI.Core.Util;
+using log4net;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.Net.Http;
+using System.Text;
+
+namespace Plugin.BurnIn.Util
+{
+ public class HttpResult
+ {
+ public int code { get; set; }
+ public string msg { get; set; }
+ public string ipn { get; set; }
+ }
+
+ public class PNUtil
+ {
+ public static bool GetPN(string mesAddress, string stationName, string sn, out string pn, out string msg)
+ {
+ pn = null;
+ msg = string.Empty;
+ try
+ {
+ //OP170Burn-In鑰佸寲
+ string json = $"{{\"csn\":\"{sn}\",\"station_name\":\"{stationName}\"}}";
+ HttpClient val = new HttpClient();
+ BurnInUI.Logger.Debug($"Get PN Send: [{json}]");
+ try
+ {
+ StringContent val2 = new StringContent(json, Encoding.UTF8, "application/json");
+ HttpResponseMessage result = val.PostAsync($"http://{mesAddress}/mes-module-system-2.1.1/lixun/api/getPn", (HttpContent)(object)val2).Result;
+ result.EnsureSuccessStatusCode();
+ string resJson = result.Content.ReadAsStringAsync().Result;
+ HttpResult httpResult = JsonUtil.Deserialize<HttpResult>(resJson);
+ BurnInUI.Logger.Debug($"Get PN Receive: [{resJson}]");
+ if (httpResult.code == 200)
+ {
+ pn = httpResult.ipn;
+ return true;
+ }
+ msg = httpResult.msg;
+ return false;
+ }
+ finally
+ {
+ ((IDisposable)val)?.Dispose();
+ }
+ }
+ catch (Exception ex)
+ {
+ BurnInUI.Logger.Debug($"Get PN Error.", ex);
+ msg = $"璇锋眰PN寮傚父锛亄ex.Message}";
+ return false;
+ }
+ }
+
+
+ public static bool CheckIn(ILog log, string mesAddress, string stationName, string sn, out bool needCheckIn, out string msg)
+ {
+ JObject data = new JObject();
+ data.Add("cmd", "QUERY_RECORD");
+ data.Add("p", "UOP");
+
+ data.Add("sn", sn);
+ data.Add("station_name", stationName);
+ data.Add("op", "A0000001");
+
+ needCheckIn = false;
+ msg = string.Empty;
+ string sendData = string.Empty;
+ string resData = null;
+ try
+ {
+ sendData = data.ToString(Formatting.None);
+ using (HttpClient val = new HttpClient())
+ {
+ StringContent val2 = new StringContent(sendData, Encoding.UTF8, "application/json");
+ HttpResponseMessage result = val.PostAsync("http://" + mesAddress + "/mes-module-system-2.1.1/lixun/api/checkIn", (HttpContent)(object)val2).Result;
+ result.EnsureSuccessStatusCode();
+ resData = result.Content.ReadAsStringAsync().Result;
+ JObject httpResult = JObject.Parse(resData);
+
+ log.Info("CheckIn Send: " + httpResult.Value<string>("sendStr"));
+ log.Info("CheckIn Receive: " + httpResult.Value<string>("receiveStr"));
+ log.Info("CheckIn Get: " + resData);
+
+ msg = httpResult.Value<string>("msg");
+ if (httpResult.Value<int>("code") == 200)
+ {
+ needCheckIn = httpResult.Value<bool>("needCheckIn");
+ return true;
+ }
+ log.Error("CheckIn Error: " + msg);
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message + " in " + ex.StackTrace + ".SendStr: " + sendData + ",ResultStr: " + resData;
+ log.Error("CheckIn Unknow Error: " + msg);
+ return false;
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/RunTimeVariablePool.cs b/Plugin.BurnIn/Util/RunTimeVariablePool.cs
new file mode 100644
index 0000000..1ea1933
--- /dev/null
+++ b/Plugin.BurnIn/Util/RunTimeVariablePool.cs
@@ -0,0 +1,11 @@
+锘縰sing System.Collections.Generic;
+
+namespace Plugin.BurnIn.Util
+{
+ public class RunTimeVariablePool
+ {
+ public static readonly string DEFAULT_PLC_NAME = "BurnInControler";
+
+ public static readonly Dictionary<string, string> CurrentOvenModel = new Dictionary<string, string>();
+ }
+}
diff --git a/Plugin.BurnIn/Util/SNValidator.cs b/Plugin.BurnIn/Util/SNValidator.cs
new file mode 100644
index 0000000..b51934f
--- /dev/null
+++ b/Plugin.BurnIn/Util/SNValidator.cs
@@ -0,0 +1,86 @@
+锘縰sing HMI.Core.Manager;
+
+namespace Plugin.BurnIn.Util
+{
+ public class SNValidator
+ {
+ public static bool ValidateSN(string model, string sn, out string msg)
+ {
+ msg = string.Empty;
+ string validate = string.Empty;
+ try
+ {
+ validate = ProductManager.GetParameterByProductAndName(model, "SNRValidate")?.Value;
+ if (string.IsNullOrEmpty(validate))
+ {
+ msg = $"褰撳墠鍨嬪彿[{model}]鏈厤缃甋NRValidate鍙傛暟锛屾棤娉曟牎楠孲N鍚堟硶鎬�";
+ return true;
+ }
+ string[] arr = validate.Split(';');
+ if (arr.Length == 1)
+ {
+ if (!sn.Contains(arr[0]))
+ {
+ msg = $"鏉$爜涓嶅寘鍚浐瀹氱爜[{arr[0]}]";
+ return false;
+ }
+ return true;
+ }
+
+ if (arr.Length == 2)
+ {
+ int length = int.Parse(arr[1]);
+ if (!sn.Contains(arr[0]))
+ {
+ msg = $"鏉$爜涓嶅寘鍚浐瀹氱爜[{arr[0]}]";
+ return false;
+ }
+ if (sn.Length != length)
+ {
+ msg = $"鏉$爜闀垮害搴斾负[{length}]";
+ return false;
+ }
+ return true;
+ }
+
+ if (arr.Length >= 3)
+ {
+ int length = int.Parse(arr[1]);
+ int startIndex = int.Parse(arr[2]);
+
+ if (sn.Length != length)
+ {
+ msg = $"鏉$爜闀垮害搴斾负[{length}]";
+ return false;
+ }
+
+ if (startIndex >= sn.Length)
+ {
+ msg = $"鏉$爜闀胯灏忎簬璧峰涓嬫爣[{validate}]";
+ return false;
+ }
+
+ if (arr[0].Length > sn.Length)
+ {
+ msg = $"鏉$爜闀胯灏忎簬鍥哄畾鐮侀暱搴{validate}]";
+ return false;
+ }
+
+ if (sn.Substring(startIndex, arr[0].Length) != arr[0])
+ {
+ msg = $"鍥哄畾鐮佹鏌ュけ璐ワ細 [{validate}]";
+ return false;
+ }
+ return true;
+ }
+ msg = $"褰撳墠鍨嬪彿[{model}]閰嶇疆鍙傛暟[{validate}]瑙f瀽澶辫触";
+ return false;
+ }
+ catch (Exception ex)
+ {
+ msg = $"褰撳墠鍨嬪彿[{model}]閰嶇疆鍙傛暟[{validate}]瑙f瀽澶辫触";
+ return false;
+ }
+ }
+ }
+}
diff --git a/Plugin.BurnIn/Util/ScannerParser.cs b/Plugin.BurnIn/Util/ScannerParser.cs
new file mode 100644
index 0000000..3043ee5
--- /dev/null
+++ b/Plugin.BurnIn/Util/ScannerParser.cs
@@ -0,0 +1,30 @@
+锘縰sing Plugin.BurnIn.Model;
+
+namespace Plugin.BurnIn.Util
+{
+ public class ScannerParser
+ {
+ public static ICodeParser parser;
+
+ public static void Init(string code)
+ {
+ if (code == "JK01")
+ {
+ parser = new JKCodeParser();
+ }
+ else if (code == "Model")
+ {
+ parser = new ModelCodeParser();
+ }
+ else
+ {
+ parser = new CommonCodeParser();
+ }
+ }
+
+ public static CellInfo GetCellInfoByCode(string model, int columns, int rows, string code)
+ {
+ return parser?.GetCellInfoByCode(model, columns, rows, code);
+ }
+ }
+}
diff --git a/Plugin.DataBoard/DataBoard.xaml b/Plugin.DataBoard/DataBoard.xaml
index c512b0f..3dcec31 100644
--- a/Plugin.DataBoard/DataBoard.xaml
+++ b/Plugin.DataBoard/DataBoard.xaml
@@ -11,6 +11,7 @@
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
+ xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
Loaded="PluginControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
@@ -130,10 +131,54 @@
Content="{DynamicResource bd.btn}"/>
</Grid>
- <wv2:WebView2 Grid.Row="3" Grid.ColumnSpan="4" Name = "webview2"
+ <lvc:CartesianChart Grid.Row="3" Background="#FFF" BorderThickness="1" BorderBrush="{DynamicResource CommonBoarder}"
+ Title="{Binding Chart0Title}"
+ TooltipTextPaint="{Binding TooltipTextPaint}"
+ Padding="0"
+ Margin="2"
+ Series="{Binding Chart0_series}"
+ XAxes="{Binding Chart0_xAxes}"
+ YAxes="{Binding Chart0_yAxes}"
+ x:Name="chart0">
+ </lvc:CartesianChart>
+
+ <lvc:PieChart Grid.Row="3" Grid.Column="1" Background="#FFF" BorderThickness="1" BorderBrush="{DynamicResource CommonBoarder}"
+ Title="{Binding Chart1Title}"
+ TooltipTextPaint="{Binding TooltipTextPaint}"
+ Padding="0"
+ Margin="2"
+ Series="{Binding Chart1_series}"
+ LegendPosition="Top"
+ x:Name="chart1">
+ </lvc:PieChart>
+
+ <lvc:CartesianChart Grid.Row="3" Grid.Column="2" Background="#FFF" BorderThickness="1" BorderBrush="{DynamicResource CommonBoarder}"
+ Title="{Binding Chart2Title}"
+ TooltipTextPaint="{Binding TooltipTextPaint}"
+ Padding="0"
+ Margin="2"
+ Series="{Binding Chart2_series}"
+ XAxes="{Binding Chart2_xAxes}"
+ YAxes="{Binding Chart2_yAxes}"
+ LegendPosition="Top"
+ x:Name="chart2">
+ </lvc:CartesianChart>
+
+ <lvc:CartesianChart Grid.Row="3" Grid.Column="3" Background="#FFF" BorderThickness="1" BorderBrush="{DynamicResource CommonBoarder}"
+Title="{Binding Chart3Title}"
+TooltipTextPaint="{Binding TooltipTextPaint}"
+Padding="0"
+Margin="2"
+Series="{Binding Chart3_series}"
+XAxes="{Binding Chart3_xAxes}"
+YAxes="{Binding Chart3_yAxes}"
+x:Name="chart3">
+ </lvc:CartesianChart>
+
+ <!--<wv2:WebView2 Grid.Row="3" Grid.ColumnSpan="4" Name="webview2"
SizeChanged="webview2_SizeChanged"
NavigationCompleted="Webview2_NavigationCompleted"
- Loaded="webview2_Loaded"/>
+ Loaded="webview2_Loaded"/>-->
</Grid>
</Border>
</hb:PluginControl>
diff --git a/Plugin.DataBoard/DataBoard.xaml.cs b/Plugin.DataBoard/DataBoard.xaml.cs
index ad70928..538e8c7 100644
--- a/Plugin.DataBoard/DataBoard.xaml.cs
+++ b/Plugin.DataBoard/DataBoard.xaml.cs
@@ -5,12 +5,23 @@
using HMI.Core.Util;
using HMI.UI.Util;
using HMI.Util;
+using LiveChartsCore;
+using LiveChartsCore.Drawing;
+using LiveChartsCore.Drawing.Layouts;
+using LiveChartsCore.Kernel.Sketches;
+using LiveChartsCore.SkiaSharpView;
+using LiveChartsCore.SkiaSharpView.Drawing;
+using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
+using LiveChartsCore.SkiaSharpView.Drawing.Layouts;
+using LiveChartsCore.SkiaSharpView.Painting;
+using LiveChartsCore.SkiaSharpView.SKCharts;
+using LiveChartsCore.SkiaSharpView.VisualElements;
using Microsoft.Web.WebView2.Core;
+using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
-using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@@ -19,6 +30,54 @@
namespace Plugin.DataBoard
{
+ public class CustomLegend : SKDefaultLegend
+ {
+
+ protected override Layout<SkiaSharpDrawingContext> GetLayout(LiveChartsCore.Chart chart)
+ {
+ var stackLayout = new StackLayout
+ {
+ Orientation = ContainerOrientation.Horizontal,
+ Padding = new Padding(0, 10, 0, 0),
+ HorizontalAlignment = Align.Start,
+ VerticalAlignment = Align.Middle,
+ };
+
+ foreach (var series in chart.Series.Where(x => x.IsVisibleAtLegend))
+ {
+ stackLayout.Children.Add(new LegendItem(series));
+ }
+ return stackLayout;
+ }
+ }
+
+ public class LegendItem : StackLayout
+ {
+ public LegendItem(ISeries series)
+ {
+ Orientation = ContainerOrientation.Horizontal;
+ Padding = new Padding(0);
+ VerticalAlignment = Align.Start;
+ HorizontalAlignment = Align.Middle;
+ Opacity = series.IsVisible ? 1 : 0.5f;
+
+ var miniature = (IDrawnElement<SkiaSharpDrawingContext>)series.GetMiniatureGeometry(null);
+ Children = new List<IDrawnElement<SkiaSharpDrawingContext>> {
+ miniature,
+ new LabelGeometry
+ {
+ Text = series.Name,
+ TextSize = 12,
+ Paint = new SolidColorPaint(SKColors.Black){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new Padding(5,0,10,0),
+ VerticalAlign = Align.Middle,
+ HorizontalAlign = Align.Start
+ }};
+ }
+ }
+
/// <summary>
/// UserControl1.xaml 鐨勪氦浜掗�昏緫
/// </summary>
@@ -28,8 +87,308 @@
{
DataContext = this;
InitializeComponent();
- webview2.DefaultBackgroundColor = Color.Transparent;//Color.FromArgb(243, 249, 255);
+ //webview2.DefaultBackgroundColor = Color.Transparent;//Color.FromArgb(243, 249, 255);
}
+
+ private SolidColorPaint tooltipTextPaint = new SolidColorPaint(SKColors.Black)
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ };
+ public SolidColorPaint TooltipTextPaint
+ {
+ get => tooltipTextPaint;
+ set
+ {
+ Set(ref tooltipTextPaint, value);
+ }
+ }
+ #region chart0
+
+ public LabelVisual Chart0Title { get; set; } = new LabelVisual
+ {
+ Text = "鎶曞叆浜у嚭缁熻",
+ TextSize = 20,
+ Paint = new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new LiveChartsCore.Drawing.Padding(15)
+ };
+
+ private ISeries[] chart0_series = new ISeries[] {
+ new ColumnSeries<int> {
+ Fill= new SolidColorPaint(new SKColor(34, 68, 139)),
+ DataLabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
+ DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Top,
+ Values = new int[]{ 0,0} }
+ };
+
+ public ISeries[] Chart0_series
+ {
+ get => chart0_series;
+ set
+ {
+ Set(ref chart0_series, value);
+ }
+ }
+
+ private ObservableCollection<Axis> chart0_yAxes = new ObservableCollection<Axis> {
+ new Axis
+ {
+ MinStep = 1,
+ MinLimit = 0,
+ LabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
+ SeparatorsPaint = new SolidColorPaint
+ {
+ Color = SKColors.Black.WithAlpha(30),
+ StrokeThickness = 0.5f
+ },
+ TicksPaint = new SolidColorPaint
+ {
+ Color = SKColor.Empty,
+ StrokeThickness = 0
+ },
+ }
+ };
+
+ public ObservableCollection<Axis> Chart0_yAxes
+ {
+ get => chart0_yAxes;
+ set
+ {
+ Set(ref chart0_yAxes, value);
+ }
+ }
+
+ private Axis[] chart0_xAxes = new Axis[] {
+ new Axis
+ {
+ Labels = new string[]{"鎶曞叆", "浜у嚭" },
+ LabelsPaint=new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ LabelsRotation = 0,
+ SeparatorsAtCenter = false,
+ TicksPaint = new SolidColorPaint(new SKColor(35, 35, 35)),
+ TicksAtCenter = true,
+ ForceStepToMin = true,
+ MinStep = 1
+ }
+ };
+ public Axis[] Chart0_xAxes
+ {
+ get => chart0_xAxes;
+ set
+ {
+ Set(ref chart0_xAxes, value);
+ }
+ }
+ #endregion
+
+ #region chart1
+
+ public LabelVisual Chart1Title { get; set; } = new LabelVisual
+ {
+ Text = "浜у搧鐘舵�佺粺璁�",
+ TextSize = 20,
+ Paint = new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new LiveChartsCore.Drawing.Padding(15)
+ };
+
+ public ISeries[] Chart1_series { get; set; } = new PieSeries<int>[]
+ {
+ new PieSeries<int> {
+ Name="Passed",
+ Values = new int[]{ 0},
+ DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Outer,
+ DataLabelsSize = 15,
+ DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Fill = new SolidColorPaint(new SKColor(0, 128, 0)),
+ DataLabelsFormatter =
+ point =>point.StackedValue.Total>0?
+ $"Passed\r\n璁℃暟:{point.Coordinate.PrimaryValue}\r\n鍗犳瘮:{point.StackedValue.Share:P2}":"",
+ ToolTipLabelFormatter = point => $"{point.StackedValue.Share:P2}"
+ },
+ new PieSeries<int> { Values = new int[]{ 0} ,
+ Name="Failed",
+ DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Outer,
+ DataLabelsSize = 15,
+ DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Fill = new SolidColorPaint(new SKColor(255, 0, 0)),
+ DataLabelsFormatter =
+ point =>point.StackedValue.Total>0?
+ $"Failed\r\n璁℃暟:{point.Coordinate.PrimaryValue}\r\n鍗犳瘮:{point.StackedValue.Share:P2}":"",
+ ToolTipLabelFormatter = point => $"{point.StackedValue.Share:P2}"},
+ };
+
+ #endregion
+
+ #region chart2
+
+ public LabelVisual Chart2Title { get; set; } = new LabelVisual
+ {
+ Text = "鑹巼缁熻",
+ TextSize = 20,
+ Paint = new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new LiveChartsCore.Drawing.Padding(15)
+ };
+
+ public ISeries[] Chart2_series { get; set; } = new ISeries[]
+ {
+ new LineSeries<double> {
+ Name="鐩撮�氱巼",
+ Values = new double[]{ 0},
+ DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Top,
+ DataLabelsFormatter =
+ point => $"鐩撮�氱巼:{point.Coordinate.PrimaryValue:f2}%",
+ DataLabelsSize = 15,
+ DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Stroke = new SolidColorPaint(new SKColor(255,0,0)){
+ StrokeThickness = 2
+ },
+ Fill = null,
+ GeometryStroke = new SolidColorPaint(new SKColor(255,0,0)){
+ StrokeThickness = 2
+ },
+ GeometrySize=5
+ },
+ new LineSeries<double> {
+ Name="鑹巼",
+ Values = new double[]{ 0},
+ DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Bottom,
+ DataLabelsFormatter =
+ point => $"鑹巼:{point.Coordinate.PrimaryValue:f2}%",
+ DataLabelsSize = 10,
+ DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Stroke = new SolidColorPaint(new SKColor(34, 68, 139)){
+ StrokeThickness = 2
+ },
+ GeometryStroke = new SolidColorPaint(new SKColor(34, 68, 139)){
+ StrokeThickness = 2
+ },
+ Fill = null,
+ },
+ };
+
+ private ObservableCollection<Axis> chart2_yAxes = new ObservableCollection<Axis> {
+ new Axis
+ {
+ LabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
+ SeparatorsPaint = new SolidColorPaint
+ {
+ Color = SKColors.Black.WithAlpha(30),
+ StrokeThickness = 0.5f
+ },
+ TicksPaint = new SolidColorPaint
+ {
+ Color = SKColor.Empty,
+ StrokeThickness = 0
+ },
+ MinLimit = 0
+ }
+ };
+ public ObservableCollection<Axis> Chart2_yAxes
+ {
+ get => chart2_yAxes;
+ set
+ {
+ Set(ref chart2_yAxes, value);
+ }
+ }
+
+ private ObservableCollection<ICartesianAxis> chart2_xAxes = new ObservableCollection<ICartesianAxis> {
+ new Axis
+ {
+ Labels = new string[]{"" },
+ }
+ };
+
+ public ObservableCollection<ICartesianAxis> Chart2_xAxes {
+ get => chart2_xAxes;
+ set {
+ Set(ref chart2_xAxes, value);
+ }
+ }
+
+ #endregion
+
+ #region chart3
+
+ public LabelVisual Chart3Title { get; set; } = new LabelVisual
+ {
+ Text = "TOP10涓嶈壇缁熻",
+ TextSize = 20,
+ Paint = new SolidColorPaint(new SKColor(0, 0, 0))
+ {
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ Padding = new LiveChartsCore.Drawing.Padding(15)
+ };
+
+ public ISeries[] Chart3_series { get; set; } = new ISeries[]
+ {
+ new RowSeries<SimpleData> {
+ Values = new SimpleData[]{},
+ DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Left,
+ DataLabelsFormatter =
+ point => $"{point.Model.Name}",
+
+ DataLabelsSize = 15,
+ DataLabelsPadding = new Padding(30,0,0,0),
+ DataLabelsTranslate = new LvcPoint(1, 0),
+ // DataLabelsTranslate = new LvcPoint(-1, 0),
+ DataLabelsPaint = new SolidColorPaint(new SKColor(255,0,0)){
+ SKTypeface = SKFontManager.Default.MatchCharacter('姹�')
+ },
+ YToolTipLabelFormatter = point => $"{point.Model.Name} {point.Model.Value}"
+ },
+ };
+
+ public ObservableCollection<Axis> chart3_yAxes = new ObservableCollection<Axis> {
+ new Axis
+ {
+ IsVisible = false
+ }
+ };
+ public ObservableCollection<Axis> Chart3_yAxes
+ {
+ get => chart3_yAxes;
+ set
+ {
+ Set(ref chart3_yAxes, value);
+ }
+ }
+
+ private ObservableCollection<ICartesianAxis> chart3_xAxes = new ObservableCollection<ICartesianAxis> {
+ new Axis { SeparatorsPaint = new SolidColorPaint(new SKColor(220, 220, 220)) }
+ };
+
+ public ObservableCollection<ICartesianAxis> Chart3_xAxes
+ {
+ get => chart3_xAxes;
+ set
+ {
+ Set(ref chart3_xAxes, value);
+ }
+ }
+
+ #endregion
+
private ObservableCollection<OptionData> _options = new ObservableCollection<OptionData> {
new OptionData { Name = LangUtil.Get("bd.today"), Value = "today" },
@@ -49,6 +408,7 @@
private string DataFolder;
public override void InitFinish()
{
+ chart2.Legend = new CustomLegend();
iniFile = Path.Combine(BaseFolder, "Config.ini");
if (!File.Exists(iniFile))
{
@@ -60,7 +420,10 @@
private void PluginControl_Loaded(object sender, RoutedEventArgs e)
{
-
+ cb0.SelectedIndex = 0;
+ cb1.SelectedIndex = 0;
+ cb2.SelectedIndex = 0;
+ cb3.SelectedIndex = 0;
}
private void LoadProduct()
@@ -223,7 +586,7 @@
segment = $"AND model = '{model}'";
}
- string sql = $@"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' {segment};";
+ string sql = $@"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' {segment} Order BY id DESC;";
DataTable dt = new DataTable();
foreach (string file in files)
@@ -240,22 +603,23 @@
private void webview2_Loaded(object sender, RoutedEventArgs e)
{
string path = Path.Combine(PathHelper.AppFolder, "Libs", "Static", "test.html");
- webview2.Source = new Uri(path);
+ //webview2.EnsureCoreWebView2Async();
+ // webview2.Source = new Uri(path);
}
private void Webview2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
- cb0.SelectedIndex = 0;
- cb1.SelectedIndex = 0;
- cb2.SelectedIndex = 0;
- cb3.SelectedIndex = 0;
+ //cb0.SelectedIndex = 0;
+ //cb1.SelectedIndex = 0;
+ //cb2.SelectedIndex = 0;
+ //cb3.SelectedIndex = 0;
}
private void webview2_SizeChanged(object sender, SizeChangedEventArgs e)
{
- var width = this.webview2.ActualWidth - 100;
- var height = this.webview2.ActualHeight;
- webview2.CoreWebView2?.ExecuteScriptAsync($"resize({width},{height})");
+ //var width = this.webview2.ActualWidth - 100;
+ //var height = this.webview2.ActualHeight;
+ //webview2.CoreWebView2?.ExecuteScriptAsync($"resize({width},{height})");
}
//private void RefreshChart0(DateTime start, DateTime end)
@@ -305,7 +669,7 @@
{
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('鍔犺浇涓紝璇风◢鍚�...')");
+ // webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('鍔犺浇涓紝璇风◢鍚�...')");
}));
List<SerialData> datas = SelectResultDataByTime(model, start, end);
datas.OrderByDescending(e => e.time);
@@ -321,7 +685,8 @@
var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
+ Chart0_series[0].Values = new int[] { all, output };
+ //webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
}));
}
catch (Exception ex)
@@ -343,12 +708,12 @@
{
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('鍔犺浇涓紝璇风◢鍚�...')");
+ //webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('鍔犺浇涓紝璇风◢鍚�...')");
}));
List<SerialData> datas = SelectResultDataByTime(model, start, end);
datas = datas.OrderByDescending(e => e.time).ToList();
- Dictionary<string, int?> pieData = new Dictionary<string, int?> {
+ Dictionary<string, int> pieData = new Dictionary<string, int> {
{ "Passed",0},
{ "Failed",0},
//{ "Action",0},
@@ -380,7 +745,9 @@
res += "]";
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
+ Chart1_series[0].Values = new int[] { pieData["Passed"] };
+ Chart1_series[1].Values = new int[] { pieData["Failed"] };
+ // webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
}));
}
catch (Exception ex)
@@ -468,7 +835,7 @@
{
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('鍔犺浇涓紝璇风◢鍚�...')");
+ // webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('鍔犺浇涓紝璇风◢鍚�...')");
}));
List<SerialData> datas = SelectResultDataByTime(model, start, end);
@@ -513,20 +880,46 @@
});
}
- string fields = "[", vals0 = "[", vals1 = "[";
- foreach (var key in res.Keys)
- {
- fields += $"'{key}',";
- vals0 += $"{res[key].onePassRate},";
- vals1 += $"{res[key].passRate},";
- }
- fields += "]";
- vals0 += "]";
- vals1 += "]";
+ //string fields = "[", vals0 = "[", vals1 = "[";
+ //foreach (var key in res.Keys)
+ //{
+ // fields += $"'{key}',";
+ // vals0 += $"{res[key].onePassRate},";
+ // vals1 += $"{res[key].passRate},";
+ //}
+ //fields += "]";
+ //vals0 += "]";
+ //vals1 += "]";
var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
+ if (res.Count == 0)
+ {
+ res[DateTime.Now.ToString("yyyy-MM-dd")] = new PassRateData
+ {
+ onePassRate = 0,
+ passRate = 0
+ };
+ }
+
+ string[] keys = new string[res.Count];
+ double[] val0 = new double[res.Count];
+ double[] val1 = new double[res.Count];
+ int i = 0;
+ foreach (var key in res.Keys)
+ {
+ keys[i] = key;
+ val0[i] = res[key].onePassRate;
+ val1[i] = res[key].passRate;
+ i++;
+ }
+ Chart2_xAxes[0] = new Axis
+ {
+ Labels = keys,
+ };
+ Chart2_series[0].Values = val0;
+ Chart2_series[1].Values = val1;
+ //webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
}));
}
catch (Exception ex)
@@ -548,7 +941,7 @@
{
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('鍔犺浇涓紝璇风◢鍚�...')");
+ //webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('鍔犺浇涓紝璇风◢鍚�...')");
}));
var st = DateTime.Now;
List<SerialData> datas = SelectSerialDataByTime(model, start, end);
@@ -585,15 +978,16 @@
var s3 = DateTime.Now;
log.Info($"RefreshChart3 Build {(s3 - s2).TotalMilliseconds}");
- string names = string.Empty, vals = string.Empty;
- foreach (var data in datasource)
- {
- names += $"'{data.Name}',";
- vals += $"{data.Value},";
- }
+ //string names = string.Empty, vals = string.Empty;
+ //foreach (var data in datasource)
+ //{
+ // names += $"'{data.Name}',";
+ // vals += $"{data.Value},";
+ //}
Dispatcher.BeginInvoke(new Action(() =>
{
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
+ Chart3_series[0].Values = datasource.OrderBy(x => x.Value).ToList(); ;
+ //webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
}));
}
catch (Exception ex)
diff --git a/Plugin.DataBoard/Plugin.DataBoard.csproj b/Plugin.DataBoard/Plugin.DataBoard.csproj
index 37ffdf2..b931527 100644
--- a/Plugin.DataBoard/Plugin.DataBoard.csproj
+++ b/Plugin.DataBoard/Plugin.DataBoard.csproj
@@ -52,8 +52,23 @@
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="HarfBuzzSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\HarfBuzzSharp.7.3.0.3\lib\net462\HarfBuzzSharp.dll</HintPath>
+ </Reference>
+ <Reference Include="LiveChartsCore, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc92a3e13d40c573, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\LiveChartsCore.2.0.0-rc5.4\lib\net462\LiveChartsCore.dll</HintPath>
+ </Reference>
+ <Reference Include="LiveChartsCore.SkiaSharpView, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc92a3e13d40c573, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\LiveChartsCore.SkiaSharpView.2.0.0-rc5.4\lib\net462\LiveChartsCore.SkiaSharpView.dll</HintPath>
+ </Reference>
+ <Reference Include="LiveChartsCore.SkiaSharpView.WPF, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc92a3e13d40c573, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\LiveChartsCore.SkiaSharpView.WPF.2.0.0-rc5.4\lib\net462\LiveChartsCore.SkiaSharpView.WPF.dll</HintPath>
+ </Reference>
<Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\WPFProject\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.WebView2.Core, Version=1.0.3240.44, Culture=neutral, PublicKeyToken=2a8ab48044d2601e, processorArchitecture=MSIL">
<HintPath>..\WPFProject\packages\Microsoft.Web.WebView2.1.0.3240.44\lib\net462\Microsoft.Web.WebView2.Core.dll</HintPath>
@@ -70,10 +85,50 @@
<Reference Include="Panuon.WPF.UI, Version=1.3.0.2, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\WPFProject\packages\Panuon.WPF.UI.1.3.0.2\lib\net472\Panuon.WPF.UI.dll</HintPath>
</Reference>
+ <Reference Include="SkiaSharp, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.2.88.9\lib\net462\SkiaSharp.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp.HarfBuzz, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.HarfBuzz.2.88.9\lib\net462\SkiaSharp.HarfBuzz.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp.Views.Desktop.Common, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.Views.Desktop.Common.2.88.9\lib\net462\SkiaSharp.Views.Desktop.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="SkiaSharp.Views.WPF, Version=2.88.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\SkiaSharp.Views.WPF.2.88.9\lib\net462\SkiaSharp.Views.WPF.dll</HintPath>
+ </Reference>
<Reference Include="System" />
+ <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
+ </Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
+ <Reference Include="System.Drawing.Common, Version=4.0.0.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Drawing.Common.4.7.3\lib\net461\System.Drawing.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Text.Json, Version=8.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
+ </Reference>
+ <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\WPFProject\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
+ </Reference>
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
@@ -120,6 +175,7 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
+ <None Include="app.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -162,5 +218,13 @@
<ErrorText>杩欏彴璁$畻鏈轰笂缂哄皯姝ら」鐩紩鐢ㄧ殑 NuGet 绋嬪簭鍖呫�備娇鐢ㄢ�淣uGet 绋嬪簭鍖呰繕鍘熲�濆彲涓嬭浇杩欎簺绋嬪簭鍖呫�傛湁鍏虫洿澶氫俊鎭紝璇峰弬瑙� http://go.microsoft.com/fwlink/?LinkID=322105銆傜己灏戠殑鏂囦欢鏄� {0}銆�</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\WPFProject\packages\Microsoft.Web.WebView2.1.0.3240.44\build\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\Microsoft.Web.WebView2.1.0.3240.44\build\Microsoft.Web.WebView2.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets'))" />
+ <Error Condition="!Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets'))" />
</Target>
+ <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.macOS.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.macOS.targets')" />
+ <Import Project="..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets" Condition="Exists('..\WPFProject\packages\HarfBuzzSharp.NativeAssets.Win32.7.3.0.3\build\net462\HarfBuzzSharp.NativeAssets.Win32.targets')" />
+ <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.macOS.2.88.9\build\net462\SkiaSharp.NativeAssets.macOS.targets')" />
+ <Import Project="..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets" Condition="Exists('..\WPFProject\packages\SkiaSharp.NativeAssets.Win32.2.88.9\build\net462\SkiaSharp.NativeAssets.Win32.targets')" />
</Project>
\ No newline at end of file
diff --git a/Plugin.DataBoard/SimpleData.cs b/Plugin.DataBoard/SimpleData.cs
index 0f33917..c51e555 100644
--- a/Plugin.DataBoard/SimpleData.cs
+++ b/Plugin.DataBoard/SimpleData.cs
@@ -1,8 +1,9 @@
-锘縩amespace Plugin.DataBoard
+锘縰sing LiveChartsCore.Defaults;
+
+namespace Plugin.DataBoard
{
- public class SimpleData
+ public class SimpleData: ObservableValue
{
public string Name { get; set; }
- public int Value { get; set; }
}
}
diff --git a/Plugin.DataBoard/app.config b/Plugin.DataBoard/app.config
new file mode 100644
index 0000000..1696df6
--- /dev/null
+++ b/Plugin.DataBoard/app.config
@@ -0,0 +1,11 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
\ No newline at end of file
diff --git a/Plugin.DataBoard/packages.config b/Plugin.DataBoard/packages.config
index f28691b..13092b2 100644
--- a/Plugin.DataBoard/packages.config
+++ b/Plugin.DataBoard/packages.config
@@ -1,7 +1,29 @@
锘�<?xml version="1.0" encoding="utf-8"?>
<packages>
+ <package id="HarfBuzzSharp" version="7.3.0.3" targetFramework="net472" />
+ <package id="HarfBuzzSharp.NativeAssets.macOS" version="7.3.0.3" targetFramework="net472" />
+ <package id="HarfBuzzSharp.NativeAssets.Win32" version="7.3.0.3" targetFramework="net472" />
+ <package id="LiveChartsCore" version="2.0.0-rc5.4" targetFramework="net472" />
+ <package id="LiveChartsCore.SkiaSharpView" version="2.0.0-rc5.4" targetFramework="net472" />
+ <package id="LiveChartsCore.SkiaSharpView.WPF" version="2.0.0-rc5.4" targetFramework="net472" />
<package id="log4net" version="3.0.4" targetFramework="net472" />
+ <package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net472" />
<package id="Microsoft.Web.WebView2" version="1.0.3240.44" targetFramework="net472" />
<package id="Panuon.WPF" version="1.1.3" targetFramework="net472" />
<package id="Panuon.WPF.UI" version="1.3.0.2" targetFramework="net472" />
+ <package id="SkiaSharp" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.HarfBuzz" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.NativeAssets.macOS" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.NativeAssets.Win32" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.Views.Desktop.Common" version="2.88.9" targetFramework="net472" />
+ <package id="SkiaSharp.Views.WPF" version="2.88.9" targetFramework="net472" />
+ <package id="System.Buffers" version="4.5.1" targetFramework="net472" />
+ <package id="System.Drawing.Common" version="4.7.3" targetFramework="net472" />
+ <package id="System.Memory" version="4.5.5" targetFramework="net472" />
+ <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
+ <package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
+ <package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net472" />
+ <package id="System.Text.Json" version="8.0.5" targetFramework="net472" />
+ <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
+ <package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
</packages>
\ No newline at end of file
diff --git a/Plugin.QualityReport/AssemblyInfo.cs b/Plugin.QualityReport/AssemblyInfo.cs
new file mode 100644
index 0000000..f2c9b42
--- /dev/null
+++ b/Plugin.QualityReport/AssemblyInfo.cs
@@ -0,0 +1,13 @@
+using HMI.Core.Annotation;
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+[assembly: PluginClassName("Plugin.QualityReport.QualityReport")]
\ No newline at end of file
diff --git "a/Plugin.QualityReport/Libs/Static/CMK\346\250\241\346\235\277.xls" "b/Plugin.QualityReport/Libs/Static/CMK\346\250\241\346\235\277.xls"
new file mode 100644
index 0000000..a6e8cf8
--- /dev/null
+++ "b/Plugin.QualityReport/Libs/Static/CMK\346\250\241\346\235\277.xls"
Binary files differ
diff --git "a/Plugin.QualityReport/Libs/Static/MSA\346\250\241\346\235\277.xlsx" "b/Plugin.QualityReport/Libs/Static/MSA\346\250\241\346\235\277.xlsx"
new file mode 100644
index 0000000..c8fab10
--- /dev/null
+++ "b/Plugin.QualityReport/Libs/Static/MSA\346\250\241\346\235\277.xlsx"
Binary files differ
diff --git "a/Plugin.QualityReport/Libs/Static/\351\207\215\345\244\215\346\200\247\346\250\241\346\235\277.xls" "b/Plugin.QualityReport/Libs/Static/\351\207\215\345\244\215\346\200\247\346\250\241\346\235\277.xls"
new file mode 100644
index 0000000..6d78229
--- /dev/null
+++ "b/Plugin.QualityReport/Libs/Static/\351\207\215\345\244\215\346\200\247\346\250\241\346\235\277.xls"
Binary files differ
diff --git a/Plugin.QualityReport/Plugin.QualityReport.csproj b/Plugin.QualityReport/Plugin.QualityReport.csproj
new file mode 100644
index 0000000..55e04c1
--- /dev/null
+++ b/Plugin.QualityReport/Plugin.QualityReport.csproj
@@ -0,0 +1,46 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ <Platforms>AnyCPU;x64</Platforms>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="log4net" Version="3.0.4" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ <PackageReference Include="NPOI" Version="2.4.1" />
+ <PackageReference Include="Panuon.WPF" Version="1.1.3" />
+ <PackageReference Include="Panuon.WPF.UI" Version="1.3.0.2" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\HMI.Base\HMI.Base.csproj" />
+ <ProjectReference Include="..\HMI.Core\HMI.Core.csproj" />
+ <ProjectReference Include="..\HMI.UI\HMI.UI.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Reference Include="NPOI">
+ <HintPath>..\HMI.ParameterManage\bin\x64\Debug\NPOI.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Update="Libs\Static\CMK妯℃澘.xls">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Update="Libs\Static\MSA妯℃澘.xlsx">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Update="Libs\Static\閲嶅鎬фā鏉�.xls">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+
+</Project>
diff --git a/Plugin.QualityReport/QualityReport.xaml b/Plugin.QualityReport/QualityReport.xaml
new file mode 100644
index 0000000..484ff2a
--- /dev/null
+++ b/Plugin.QualityReport/QualityReport.xaml
@@ -0,0 +1,249 @@
+锘�<hb:SimpleMaskControl x:Class="Plugin.QualityReport.QualityReport"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:local="clr-namespace:Plugin.QualityReport"
+ mc:Ignorable="d"
+ xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
+ xmlns:pu="https://opensource.panuon.com/wpf-ui"
+ xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
+ x:Name="control"
+ d:DesignHeight="450" d:DesignWidth="800">
+ <UserControl.Resources>
+
+
+
+ <Style x:Key="ReportDataGridRow" TargetType="DataGridRow">
+ <Setter Property="Background" Value="White"/>
+ <Style.Triggers>
+ <Trigger Property="AlternationIndex" Value="1">
+ <Setter Property="Background" Value="#eeeeee"/>
+ </Trigger>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter Property="Background" Value="{DynamicResource SecondPrimaryColor}"/>
+ <Setter Property="Foreground" Value="{DynamicResource SecondPrimaryColorContract}"/>
+ </Trigger>
+ </Style.Triggers>
+ </Style>
+
+ <Style x:Key="ReportDataGrid" TargetType="DataGrid">
+ <Setter Property="FontSize" Value="16"/>
+ <Setter Property="AlternationCount" Value="2"/>
+ <Setter Property="AutoGenerateColumns" Value="False"/>
+ <Setter Property="RowHeight" Value="30"/>
+ <Setter Property="IsReadOnly" Value="True"/>
+ <Setter Property="RowStyle" Value="{StaticResource ReportDataGridRow}"/>
+ </Style>
+
+ <Style TargetType="ListBox" x:Key="ListBoxItemStyle1">
+ <Setter Property="Background" Value="Transparent"/>
+ <Setter Property="Padding" Value="-1"/>
+ <Setter Property="ItemContainerStyle">
+ <Setter.Value>
+ <Style TargetType="ListBoxItem">
+ <Setter Property="Margin" Value="0"/>
+ <Setter Property="Padding" Value="0"/>
+ <Setter Property="Foreground" Value="Black"/>
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="ListBoxItem">
+ <Border x:Name="border" Padding="10,5" Cursor="Hand" Margin="5,2" Height="30"
+ BorderThickness="1" BorderBrush="{DynamicResource CommonBoarder}">
+ <DockPanel VerticalAlignment="Center">
+ <Button Margin="10,0,0,0" DockPanel.Dock="Right"
+ Command="{Binding RemoveSNCommand,RelativeSource={RelativeSource AncestorType=local:QualityReport}}"
+ CommandParameter="{Binding }"
+ Tag="{Binding }">X</Button>
+ <ContentPresenter x:Name="cp" Content="{TemplateBinding Content}"
+ContentStringFormat="{TemplateBinding ContentStringFormat}"
+ContentTemplate="{TemplateBinding ContentTemplate}" />
+ </DockPanel>
+ </Border>
+
+ <ControlTemplate.Triggers>
+ <Trigger Property="IsMouseOver" Value="True">
+ <Setter TargetName="border" Property="Background" Value="#7093d3" />
+ <Setter Property="Foreground" Value="{StaticResource SecondPrimaryColorContract}" />
+ </Trigger>
+ </ControlTemplate.Triggers>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </Setter.Value>
+ </Setter>
+ <Setter Property="ItemsPanel">
+ <Setter.Value>
+ <ItemsPanelTemplate>
+ <VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal"/>
+ </ItemsPanelTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
+ </UserControl.Resources>
+
+ <Border Style="{StaticResource CardBoarder}" Padding="0">
+ <TabControl Style="{StaticResource HeaderTabControl}" >
+ <TabItem Header="CMK">
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="10">
+ <pu:FormGroup Header="鍨嬪彿" Style="{StaticResource InputFormGroupStyle}">
+ <ComboBox MinWidth="180" ItemsSource="{Binding Models}" Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding Model}"
+SelectedValuePath="Name" DisplayMemberPath="Name" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="鏃堕棿" Style="{StaticResource InputFormGroupStyle}">
+ <StackPanel Orientation="Horizontal">
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{Binding StartTimeCMK}"></pu:DateTimePicker>
+ <TextBlock VerticalAlignment="Center" Text=" 鑷� "/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{Binding EndTimeCMK}"></pu:DateTimePicker>
+ </StackPanel>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="娴嬭瘯椤�" Style="{StaticResource InputFormGroupStyle}">
+ <pu:SearchBox Text="{Binding TestItemCMK,Mode=TwoWay}" Tag="Step" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+ </pu:FormGroup>
+
+ <Button Style="{StaticResource QueryBtn}" Command="{Binding QueryCMKCommand}"/>
+ <Button Style="{StaticResource ExportBtn}" Command="{Binding ExportCMKCommand}"/>
+ </StackPanel>
+ <DataGrid Grid.Row="2" Style="{StaticResource ReportDataGrid}"
+ ItemsSource="{Binding DatasourceCMK}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Width="*" Header="鏁版嵁1" Binding="{Binding d1}"/>
+ <DataGridTextColumn Width="*" Header="鏁版嵁2" Binding="{Binding d2}"/>
+ <DataGridTextColumn Width="*" Header="鏁版嵁3" Binding="{Binding d3}"/>
+ <DataGridTextColumn Width="*" Header="鏁版嵁4" Binding="{Binding d4}"/>
+ <DataGridTextColumn Width="*" Header="鏁版嵁5" Binding="{Binding d5}"/>
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+ </TabItem>
+ <TabItem Header="MSA">
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="10">
+ <pu:FormGroup Header="鍨嬪彿" Style="{StaticResource InputFormGroupStyle}">
+ <ComboBox MinWidth="180" ItemsSource="{Binding Models}" Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding Model}"
+ SelectedValuePath="Name" DisplayMemberPath="Name" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="SN" Style="{StaticResource InputFormGroupStyle}">
+ <DockPanel>
+ <Button DockPanel.Dock="Right"
+ Command="{Binding AddSnrCommand}"
+ Style="{StaticResource PrimaryButton}"
+ FontFamily="{StaticResource iconfont}"
+ Content=""/>
+ <pu:SearchBox Text="{Binding Snr,Mode=TwoWay}" Tag="SN" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+ </DockPanel>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="鏃堕棿" Style="{StaticResource InputFormGroupStyle}">
+ <StackPanel Orientation="Horizontal">
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{Binding StartTimeCMK}"></pu:DateTimePicker>
+ <TextBlock VerticalAlignment="Center" Text=" 鑷� "/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{Binding EndTimeCMK}"></pu:DateTimePicker>
+ </StackPanel>
+ </pu:FormGroup>
+
+ <Button Style="{StaticResource QueryBtn}" Command="{Binding QueryMSACommand}"/>
+ <Button Style="{StaticResource ExportBtn}" Command="{Binding ExportMSACommand}"/>
+ </StackPanel>
+ <pu:FormGroup Grid.Row="1" Header="宸查�塖N" Style="{StaticResource InputFormGroupStyle}">
+ <ListBox Style="{StaticResource ListBoxItemStyle1}" ItemsSource="{Binding SelectedSnr}" Height="40">
+ </ListBox>
+ </pu:FormGroup>
+
+ <DataGrid Grid.Row="2" Style="{StaticResource ReportDataGrid}"
+ ItemsSource="{Binding DatasourceMSA}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Width="*" Header="鏉$爜1" Binding="{Binding d1}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜2" Binding="{Binding d2}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜3" Binding="{Binding d3}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜4" Binding="{Binding d4}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜5" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜6" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜7" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜8" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜9" Binding="{Binding d5}"/>
+ </DataGrid.Columns>
+ </DataGrid>
+ <!--<Grid Grid.Row="2" x:Name="msaGrid" dp:GridHelper.InnerBorder="1" dp:GridHelper.InnerBorderBrush="Black">
+
+ </Grid>-->
+ </Grid>
+ </TabItem>
+ <TabItem Header="閲嶅鎬�">
+ <Grid dp:GridHelper.Space="10">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <StackPanel Orientation="Horizontal" VerticalAlignment="Center" dp:StackPanelHelper.ChildSpace="10">
+ <pu:FormGroup Header="鍨嬪彿" Style="{StaticResource InputFormGroupStyle}">
+ <ComboBox MinWidth="180" ItemsSource="{Binding Models}" Style="{StaticResource FormComboxStyle}" SelectedValue="{Binding Model}"
+ SelectedValuePath="Name" DisplayMemberPath="Name" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="SN" Style="{StaticResource InputFormGroupStyle}">
+ <DockPanel>
+ <Button DockPanel.Dock="Right"
+ Command="{Binding AddSnr2RepeatCommand}"
+ Style="{StaticResource PrimaryButton}"
+ FontFamily="{StaticResource iconfont}"
+ Content=""/>
+ <pu:SearchBox Text="{Binding Snr,Mode=TwoWay}" Tag="SN" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+ </DockPanel>
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="娴嬭瘯椤�" Style="{StaticResource InputFormGroupStyle}">
+ <pu:SearchBox Text="{Binding TestItemCMK,Mode=TwoWay}" Tag="Step" SearchTextChanged="SearchTextChanged" MinWidth="180" />
+ </pu:FormGroup>
+
+ <pu:FormGroup Header="鏃堕棿" Style="{StaticResource InputFormGroupStyle}">
+ <StackPanel Orientation="Horizontal">
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{Binding StartTimeCMK}"></pu:DateTimePicker>
+ <TextBlock VerticalAlignment="Center" Text=" 鑷� "/>
+ <pu:DateTimePicker Style="{StaticResource TimePicker}" SelectedDateTime="{Binding EndTimeCMK}"></pu:DateTimePicker>
+ </StackPanel>
+ </pu:FormGroup>
+
+ <Button Style="{StaticResource QueryBtn}" Command="{Binding QueryRepeatCommand}"/>
+ <Button Style="{StaticResource ExportBtn}" Command="{Binding ExportRepeatCommand}"/>
+ </StackPanel>
+ <pu:FormGroup Grid.Row="1" Header="宸查�塖N" Style="{StaticResource InputFormGroupStyle}">
+ <ListBox Style="{StaticResource ListBoxItemStyle1}" ItemsSource="{Binding SelectedSnrRepeat}" Height="40">
+ </ListBox>
+ </pu:FormGroup>
+
+ <DataGrid Grid.Row="2" Style="{StaticResource ReportDataGrid}" ItemsSource="{Binding DatasourceRepeat}">
+ <DataGrid.Columns>
+ <DataGridTextColumn Width="*" Header="鏉$爜1" Binding="{Binding d1}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜2" Binding="{Binding d2}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜3" Binding="{Binding d3}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜4" Binding="{Binding d4}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜5" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜6" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜7" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜8" Binding="{Binding d5}"/>
+ <DataGridTextColumn Width="*" Header="鏉$爜9" Binding="{Binding d5}"/>
+ </DataGrid.Columns>
+ </DataGrid>
+ </Grid>
+
+ </TabItem>
+ </TabControl>
+ </Border>
+</hb:SimpleMaskControl>
diff --git a/Plugin.QualityReport/QualityReport.xaml.cs b/Plugin.QualityReport/QualityReport.xaml.cs
new file mode 100644
index 0000000..538968c
--- /dev/null
+++ b/Plugin.QualityReport/QualityReport.xaml.cs
@@ -0,0 +1,705 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using HMI.Base;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI.Util;
+using Microsoft.Win32;
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using NPOI.Util;
+using NPOI.XSSF.UserModel;
+using Panuon.WPF.UI;
+using System.Collections.ObjectModel;
+using System.Data;
+using System.IO;
+using System.Windows;
+
+namespace Plugin.QualityReport
+{
+ public class CMKData
+ {
+ public object[] values = new object[5];
+ public object d1 { get => values[0]; set => values[0] = value; }
+ public object d2 { get => values[1]; set => values[1] = value; }
+ public object d3 { get => values[2]; set => values[2] = value; }
+ public object d4 { get => values[3]; set => values[3] = value; }
+ public object d5 { get => values[4]; set => values[4] = value; }
+ }
+
+ public class MSAData
+ {
+ public object[] values = new object[9];
+ public object d1 { get => values[0]; set => values[0] = value; }
+ public object d2 { get => values[1]; set => values[1] = value; }
+ public object d3 { get => values[2]; set => values[2] = value; }
+ public object d4 { get => values[3]; set => values[3] = value; }
+ public object d5 { get => values[4]; set => values[4] = value; }
+ public object d6 { get => values[5]; set => values[5] = value; }
+ public object d7 { get => values[6]; set => values[6] = value; }
+ public object d8 { get => values[7]; set => values[7] = value; }
+ public object d9 { get => values[8]; set => values[8] = value; }
+ }
+
+ public class RepeatData
+ {
+ public string Title { get; set; }
+
+ public object[] values = new object[10];
+ public object d1 { get => values[0]; set => values[0] = value; }
+ public object d2 { get => values[1]; set => values[1] = value; }
+ public object d3 { get => values[2]; set => values[2] = value; }
+ public object d4 { get => values[3]; set => values[3] = value; }
+ public object d5 { get => values[4]; set => values[4] = value; }
+ public object d6 { get => values[5]; set => values[5] = value; }
+ public object d7 { get => values[6]; set => values[6] = value; }
+ public object d8 { get => values[7]; set => values[7] = value; }
+ public object d9 { get => values[8]; set => values[8] = value; }
+ public object d10 { get => values[9]; set => values[9] = value; }
+ }
+
+ /// <summary>
+ /// QualityReport.xaml 鐨勪氦浜掗�昏緫
+ /// </summary>
+ [ObservableObject]
+ public partial class QualityReport : SimpleMaskControl
+ {
+ [ObservableProperty]
+ private string model;
+
+ [ObservableProperty]
+ private List<ProductData> models;
+
+ [ObservableProperty]
+ private DateTime startTimeCMK;
+
+ [ObservableProperty]
+ private DateTime endTimeCMK;
+
+ [ObservableProperty]
+ private string testItemCMK = "TestItem";
+
+ [ObservableProperty]
+ private List<CMKData> datasourceCMK = null;
+
+ [ObservableProperty]
+ private List<MSAData> datasourceMSA = null;
+
+ [ObservableProperty]
+ private List<RepeatData> datasourceRepeat = null;
+
+ [ObservableProperty]
+ private string snr;
+
+ [ObservableProperty]
+ private ObservableCollection<string> selectedSnr = new ObservableCollection<string> { };
+
+ [ObservableProperty]
+ private ObservableCollection<string> selectedSnrRepeat = new ObservableCollection<string> { };
+
+ public QualityReport()
+ {
+ DataContext = this;
+ InitializeComponent();
+ StartTimeCMK = DateTime.Today;
+ EndTimeCMK = DateTime.Today.AddDays(1);
+ }
+
+ public override void Active()
+ {
+ base.Active();
+ Models = ProductManager.GetProducts<List<ProductData>>()
+ ?? new List<ProductData>();
+ }
+
+ private string[] GetFiles(DateTime? startTime, DateTime? endTime)
+ {
+ string dir = ParamSetting.DataLogFolder;
+ string startName = $"Data_{startTime?.ToString("yyyyMMdd")}";
+ string endName = $"Data_{endTime?.ToString("yyyyMMdd")}";
+ var oldFiles = Directory.GetFiles(dir, "Data_*.db");
+ oldFiles = oldFiles.Where(file =>
+ {
+ var fileName = Path.GetFileNameWithoutExtension(file);
+ bool flag = true;
+ flag &= (string.Compare(fileName, startName) == 1 || fileName == startName);
+ flag &= (string.Compare(endName, fileName) == 1 || fileName == endName);
+ return flag;
+ }).ToArray();
+ return oldFiles;
+ }
+
+ public DataTable SelectByFiles(string[] files, Func<string, string, string> ConcatAction, SortParam sorter, PageParam page)
+ {
+ if (files == null || files.Length <= 0)
+ {
+ return new DataTable();
+ }
+ if (files.Length < Sqlite3Helper.MAX_ATTACHED)
+ {
+ using (var helper = new Sqlite3Helper(files[0]))
+ {
+ string[] sqls = new string[files.Length];
+ for (int i = 0; i < files.Length; i++)
+ {
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ sqls[i] = ConcatAction(files[i], $"db{i}");
+ }
+ string sql = string.Join(" UNION ALL ", sqls);
+
+ sql = $"SELECT * FROM ({sql}) as _temp";
+ if (sorter != null)
+ {
+ sql = $"{sql} ORDER BY {sorter.field} {sorter.sort}";
+ }
+ if (page != null)
+ {
+ sql = $"{sql} LIMIT {page.limit} OFFSET {page.offset}";
+ }
+ return helper.GetDataTable(sql);
+ }
+ }
+ else
+ {
+ DataTable dt = new DataTable();
+ Sqlite3Helper helper = null;
+ string[] sqls = new string[Sqlite3Helper.MAX_ATTACHED];
+
+ var fff = () =>
+ {
+ if (helper != null)
+ {
+ string sql = string.Join(" UNION ALL ", sqls.Where(s => s != null));
+
+ sql = $"SELECT * FROM ({sql}) as _temp";
+
+
+ dt.Merge(helper.GetDataTable(sql));
+ sqls = new string[Sqlite3Helper.MAX_ATTACHED];
+ helper.Dispose();
+ helper = null;
+ }
+ };
+
+ try
+ {
+ for (int i = 0; i < files.Length; i++)
+ {
+ if (i % Sqlite3Helper.MAX_ATTACHED == 0)
+ {
+ fff();
+ helper = new Sqlite3Helper(files[i]);
+ }
+ var attach = $"ATTACH DATABASE '{files[i]}' AS 'db{i}'";
+ helper.Execute(attach);
+ sqls[i % Sqlite3Helper.MAX_ATTACHED] = ConcatAction(files[i], $"db{i}");
+ }
+ fff();
+ if (dt.Rows.Count > 0)
+ {
+ if (sorter != null)
+ {
+ dt.DefaultView.Sort = $"{sorter.field} {sorter.sort}";
+ }
+ if (page != null)
+ {
+ var rows = dt.Rows.Cast<DataRow>();
+ var curRows = rows.Skip(page.offset).Take(page.limit).ToArray();
+ var sb = dt.Clone();
+ if (dt.Rows.Count > page.offset)
+ {
+ if (dt.Rows.Count < page.limit)
+ {
+ sb = dt;
+ }
+ else
+ {
+ for (int i = page.offset; i < page.offset + page.limit; i++)
+ {
+ sb.ImportRow(dt.Rows[i]);
+ }
+ }
+ }
+ dt = sb;
+ // dt = new DataTable(curRows);
+ }
+ }
+ }
+ finally
+ {
+ helper?.Dispose();
+ }
+ return dt;
+ }
+ }
+
+
+ [RelayCommand]
+ public void QueryCMK()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(Model) || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+ {
+ ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+ return;
+ }
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+
+
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' AND step='{TestItemCMK}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+ }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 50, offset = 0 });
+ List<CMKData> list = new List<CMKData>();
+ object[] values = null;
+ for (int i = 0; i < dt.Rows.Count; i++)
+ {
+ if (i % 5 == 0)
+ {
+ values = new object[5];
+ list.Add(new CMKData { values = values });
+ }
+ values[i % 5] = dt.Rows[i]["value"];
+ }
+ DatasourceCMK = list;
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ [RelayCommand]
+ public void ExportCMK()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(Model) || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+ {
+ ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+ return;
+ }
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+
+
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' AND step='{TestItemCMK}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+ }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 50, offset = 0 });
+ List<CMKData> list = new List<CMKData>();
+ object[] values = null;
+ for (int i = 0; i < dt.Rows.Count; i++)
+ {
+ if (i % 5 == 0)
+ {
+ values = new object[5];
+ list.Add(new CMKData { values = values });
+ }
+ values[i % 5] = dt.Rows[i]["value"];
+ }
+
+ using (FileStream fs = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Libs", "Static", "CMK妯℃澘.xls")))
+ {
+ IWorkbook workbook = new HSSFWorkbook(fs);
+ ISheet sheet = workbook.GetSheet("CMK");
+ for (int i = 0; i < list.Count; i++)
+ {
+ int num = i + 9;
+ if (num > 24)
+ {
+ break;
+ }
+ IRow row = sheet.GetRow(num);
+ CMKData data = list[i];
+ for (int j = 0; j < 5; j++)
+ {
+ if (data.values[j] != null)
+ {
+ row.GetCell(j).SetCellValue(double.Parse(data.values[j].ToString()));
+ }
+ }
+ }
+ sheet.ForceFormulaRecalculation = true;//鎵ц鍏紡
+
+ //鏂规硶浜�
+ //workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();
+
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ Filter = "Excel鏂囦欢 (*.xls)|*.xls",
+ };
+ if (sfd.ShowDialog() == true)
+ {
+ using (FileStream sfs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
+ {
+ workbook.Write(sfs);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ [RelayCommand]
+ private void AddSnr()
+ {
+ if (SelectedSnr.Count >= 9)
+ {
+ ToastHelper.Warning("鏈�澶氶�夊彇9涓骇鍝�");
+ return;
+ }
+
+ if (SelectedSnr.Contains(Snr))
+ {
+ ToastHelper.Warning($"鏉$爜锛歔{Snr}] 宸茶閫変腑");
+ return;
+ }
+ SelectedSnr.Add(Snr);
+ }
+
+ [RelayCommand]
+ private void AddSnr2Repeat()
+ {
+ if (SelectedSnrRepeat.Count >= 10)
+ {
+ ToastHelper.Warning("鏈�澶氶�夊彇10涓骇鍝�");
+ return;
+ }
+
+ if (SelectedSnrRepeat.Contains(Snr))
+ {
+ ToastHelper.Warning($"鏉$爜锛歔{Snr}] 宸茶閫変腑");
+ return;
+ }
+ SelectedSnrRepeat.Add(Snr);
+ }
+
+ [RelayCommand]
+ public void RemoveSN(object obj)
+ {
+ SelectedSnr.Remove(obj.ToString());
+ }
+
+ [RelayCommand]
+ public void QueryMSA()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(Model) || SelectedSnr.Count <= 0 || StartTimeCMK == null || EndTimeCMK == null)
+ {
+ ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+ return;
+ }
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+ Dictionary<string, List<int>> map = new Dictionary<string, List<int>>();
+ foreach (var sn in SelectedSnr)
+ {
+ List<int> datas = new List<int>();
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT result,time FROM {db}.testResult WHERE model='{Model}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+ }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 10, offset = 0 });
+
+ datas = dt.Rows.Cast<DataRow>().Select(r =>
+ string.Equals(r["result"].ToString(), "passed", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(r["result"].ToString(), "ok", StringComparison.OrdinalIgnoreCase) ? 1 : 0)
+ .ToList();
+ map[sn] = datas;
+ }
+ List<MSAData> temp = new List<MSAData>() { new MSAData() };
+
+ int i = 0;
+ foreach (var key in map.Keys)
+ {
+ temp[0].values[i] = key;
+ var vals = map[key];
+ for (int j = 0; j < vals.Count; j++)
+ {
+ if (temp.Count < j + 2)
+ {
+ temp.Add(new MSAData());
+ }
+ temp[j + 1].values[i] = vals[j];
+ }
+ i++;
+ }
+ DatasourceMSA = temp;
+
+ //RefreshMSAGrid(map);
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+
+ [RelayCommand]
+ public void ExportMSA()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(Model) || SelectedSnr.Count <= 0 || StartTimeCMK == null || EndTimeCMK == null)
+ {
+ ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+ return;
+ }
+
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+ Dictionary<string, List<int>> map = new Dictionary<string, List<int>>();
+ foreach (var sn in SelectedSnr)
+ {
+ List<int> datas = new List<int>();
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT result,time FROM {db}.testResult WHERE model='{Model}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+ }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 10, offset = 0 });
+
+ datas = dt.Rows.Cast<DataRow>().Select(r =>
+ string.Equals(r["result"].ToString(), "passed", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(r["result"].ToString(), "ok", StringComparison.OrdinalIgnoreCase) ? 1 : 0)
+ .ToList();
+ map[sn] = datas;
+ }
+ using (FileStream fs = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Libs", "Static", "MSA妯℃澘.xlsx")))
+ {
+ IWorkbook workbook = new XSSFWorkbook(fs);
+ ISheet sheet = workbook.GetSheet("鏁版嵁杈撳叆");
+
+ int column = 2;
+ foreach (string snr in map.Keys)
+ {
+ if (column > 10)
+ {
+ break;
+ }
+ var datas = map[snr];
+ sheet.GetRow(9).GetCell(column).SetCellValue(snr);
+
+ for (int i = 0; i < datas.Count; i++)
+ {
+ if (i > 49) break;
+ sheet.GetRow(i + 11).GetCell(column).SetCellValue(datas[i]);
+ }
+ column++;
+ }
+ sheet.ForceFormulaRecalculation = true;//鎵ц鍏紡
+
+ //鏂规硶浜�
+ //workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();
+
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ Filter = "Excel鏂囦欢 (*.xlsx)|*.xlsx",
+ };
+ if (sfd.ShowDialog() == true)
+ {
+ using (FileStream sfs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
+ {
+ workbook.Write(sfs);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+
+ [RelayCommand]
+ public void QueryRepeat()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(Model) || SelectedSnrRepeat.Count <= 0 || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+ {
+ ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+ return;
+ }
+
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+ Dictionary<string, List<double>> map = new Dictionary<string, List<double>>();
+ foreach (var sn in SelectedSnrRepeat)
+ {
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' And step='{TestItemCMK}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+ }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 9, offset = 0 });
+
+ var datas = dt.Rows.Cast<DataRow>().Select(r => Math.Round(double.Parse(r["value"].ToString()), 3, MidpointRounding.AwayFromZero)).ToList();
+ map[sn] = datas;
+ }
+ List<RepeatData> temp = new List<RepeatData>() { new RepeatData { Title = "鏉$爜" } };
+
+ int i = 0;
+ foreach (var key in map.Keys)
+ {
+ temp[0].values[i] = key;
+ var vals = map[key];
+ for (int j = 0; j < vals.Count; j++)
+ {
+ if (temp.Count < j + 2)
+ {
+ temp.Add(new RepeatData());
+ }
+ temp[j + 1].values[i] = vals[j];
+ }
+ i++;
+ }
+ DatasourceRepeat = temp;
+ }
+ catch (Exception ex)
+ {
+ log.Error("閲嶅鎬ф煡璇㈠け璐�", ex);
+ MsgBoxHelper2.Error($"閲嶅鎬ф煡璇㈠け璐�: {ex.Message}");
+ }
+ }
+
+
+ [RelayCommand]
+ public void ExportRepeat()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(Model) || SelectedSnrRepeat.Count <= 0 || string.IsNullOrEmpty(TestItemCMK) || StartTimeCMK == null || EndTimeCMK == null)
+ {
+ ToastHelper.Error("璇疯緭鍏ュ瀷鍙枫�侀�変腑鐨勬潯鐮併�佹祴璇曢」銆佸紑濮嬫椂闂村拰缁撴潫鏃堕棿锛�");
+ return;
+ }
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK);
+ Dictionary<string, List<double>> map = new Dictionary<string, List<double>>();
+ foreach (var sn in SelectedSnrRepeat)
+ {
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT value,time FROM {db}.serialData WHERE model='{Model}' And step='{TestItemCMK}' AND sn='{sn}' AND time>='{StartTimeCMK:yyyy-MM-dd HH:mm:ss}' AND time<'{EndTimeCMK:yyyy-MM-dd HH:mm:ss}'";
+ }, new SortParam { field = "time", sort = "DESC" }, new PageParam { limit = 9, offset = 0 });
+
+ var datas = dt.Rows.Cast<DataRow>().Select(r => Math.Round(double.Parse(r["value"].ToString()), 3, MidpointRounding.AwayFromZero)).ToList();
+ map[sn] = datas;
+ }
+ List<RepeatData> temp = new List<RepeatData>() { new RepeatData() };
+
+ int i = 0;
+ foreach (var key in map.Keys)
+ {
+ temp[0].values[i] = key;
+ var vals = map[key];
+ for (int j = 0; j < vals.Count; j++)
+ {
+ if (temp.Count < j + 2)
+ {
+ temp.Add(new RepeatData());
+ }
+ temp[j + 1].values[i] = vals[j];
+ }
+ i++;
+ }
+
+ using (FileStream fs = File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Libs", "Static", "閲嶅鎬фā鏉�.xls")))
+ {
+ IWorkbook workbook = new HSSFWorkbook(fs);
+ ISheet sheet = workbook.GetSheet("sheet1");
+
+ sheet.GetRow(10).GetCell(2).SetCellValue(TestItemCMK);
+
+ int column = 2;
+ foreach (string snr in map.Keys)
+ {
+ if (column > 11)
+ {
+ break;
+ }
+ var datas = map[snr];
+ sheet.GetRow(11).GetCell(column).SetCellValue(snr);
+
+ for (int j = 0; j < datas.Count; j++)
+ {
+ if (j > 8) break;
+ int row = j + 13;
+ if (j > 2 && j <= 5)
+ {
+ row = j + 15;
+ }
+ else if (j > 5)
+ {
+ row = j + 17;
+ }
+ sheet.GetRow(row).GetCell(column).SetCellValue(datas[j]);
+ }
+ column++;
+ }
+ sheet.ForceFormulaRecalculation = true;//鎵ц鍏紡
+
+ //鏂规硶浜�
+ //workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();
+
+ SaveFileDialog sfd = new SaveFileDialog
+ {
+ Filter = "Excel鏂囦欢 (*.xls)|*.xls",
+ };
+ if (sfd.ShowDialog() == true)
+ {
+ using (FileStream sfs = new FileStream(sfd.FileName, FileMode.OpenOrCreate))
+ {
+ workbook.Write(sfs);
+ ToastHelper.Success("瀵煎嚭鎴愬姛");
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ log.Error("閲嶅鎬у鍑哄け璐�", ex);
+ MsgBoxHelper2.Error($"瀵煎嚭澶辫触: {ex.Message}");
+ }
+ }
+
+ private void SearchTextChanged(object sender, Panuon.WPF.SearchTextChangedRoutedEventArgs e)
+ {
+ SearchBox box = (SearchBox)sender;
+ try
+ {
+ string[] files = GetFiles(StartTimeCMK, EndTimeCMK).OrderBy(s => s).Take(7).ToArray();
+
+ if (box.Tag.ToString() == "Step")
+ {
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT DISTINCT step FROM {db}.serialData WHERE model='{Model}' And step LIKE '%{TestItemCMK}%'";
+ }, null, null);
+
+ var datas = dt.Rows.Cast<DataRow>().Select(r => r["step"].ToString()).Distinct().ToList();
+ box.ItemsSource = datas;
+ }
+ else
+ {
+ DataTable dt = SelectByFiles(files, (file, db) =>
+ {
+ return $"SELECT DISTINCT sn FROM {db}.testResult WHERE model='{Model}' And sn LIKE '%{Snr}%'";
+ }, null, null);
+
+ var datas = dt.Rows.Cast<DataRow>().Select(r => r["sn"].ToString()).Distinct().ToList();
+ box.ItemsSource = datas;
+ }
+ }
+ catch
+ {
+ box.ItemsSource = new string[] { };
+ }
+ }
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/Plugin.TestResult/DataTable.xaml b/Plugin.TestResult/DataTable.xaml
index 12a6b61..13e0adf 100644
--- a/Plugin.TestResult/DataTable.xaml
+++ b/Plugin.TestResult/DataTable.xaml
@@ -135,6 +135,7 @@
<ColumnDefinition/>
</UniformGrid.ColumnDefinitions>-->
<Button Click="ScanWindow_Click" Style="{StaticResource PrimaryButton}"
+ IsEnabled="{Binding IsTesting,Converter={StaticResource reverseBool}}"
Content="{DynamicResource Tr.Scan}"/>
<Button Grid.Column="1" Click="ClearAllSnr_Click" Style="{StaticResource DangerButton}"
IsEnabled="{Binding IsTesting,Converter={StaticResource reverseBool}}"
diff --git a/Plugin.TestResult/DataTable.xaml.cs b/Plugin.TestResult/DataTable.xaml.cs
index 4be9f27..29d402c 100644
--- a/Plugin.TestResult/DataTable.xaml.cs
+++ b/Plugin.TestResult/DataTable.xaml.cs
@@ -319,7 +319,7 @@
else
{
/// 妫�鏌ユ槸鍚﹀叧闂�
- if (parent.executionWrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) != true)
+ if (!GetDoorClose(parent.executionWrapper))
{
/// 娌″叧闂ㄤ笉鍏佽鍚姩
MsgBoxHelper2.Warn("璇峰厛鍏抽棴鑸遍棬锛�");
@@ -390,6 +390,11 @@
scanner = null;
}
+ public bool GetDoorClose(ITestExecutionWrapper wrapper)
+ {
+ return wrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) == true;
+ }
+
private void Scanner_FinishBarcode(object sender, BarcodeEventArg e)
{
if (parent.executionWrapper == null) return;
@@ -399,19 +404,37 @@
CellInfo cellInfo = ScannerParser.GetCellInfoByCode(CbProduct.SelectedItem?.ToString(), mainGrid.Columns, rows, e.positionCode);
string positionCode = e.positionCode, snrCode = e.snrCode;
- //灏嗚鍒扮殑鏉$爜鍐欏叆鍒癝N涓�
- int dutNo = this.index * this.cellCount + cellInfo.Index;
+ //if (cellInfo.OvenName != this.title)
+ //{
+ // MsgBoxHelper2.Warn($"璇峰垏鎹㈣嚦 [{cellInfo.OvenName}] 鍖烘壂鐮侊紝褰撳墠涓� [{this.title}] 鍖猴紒");
+ // return;
+ //}
+
+ var targetTable = TestResultView.nameTables[cellInfo.OvenName];
+
+ //灏嗚鍒扮殑鏉$爜鍐欏叆鍒癝N涓�
+ int dutNo = targetTable.index * targetTable.cellCount + cellInfo.Index;
string LookupStr = $"StationState.SN[{dutNo}]";
cellInfo.LookUpStr = LookupStr;
- ViewControl.Logger.Debug($"PositionCode: [{e.positionCode}], SNR: [{e.snrCode}], LookUpStr: [{LookupStr}]");
- ViewControl.Logger.Debug($"OvenName: [{cellInfo.OvenName}], CellIndex: [{cellInfo.Index}]");
- var cell = TestResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index);
+ ViewControl.Logger.Info($"PositionCode: [{e.positionCode}], SNR: [{e.snrCode}], LookUpStr: [{LookupStr}]");
+ ViewControl.Logger.Info($"OvenName: [{cellInfo.OvenName}], CellIndex: [{cellInfo.Index}]");
+ var cell = targetTable.GetSingleCell(cellInfo.Index);
+
+ if (targetTable.GetDoorClose(parent.executionWrapper))
+ {
+ /// 鍏抽棬浜嗗氨涓嶅厑璁告竻鏉$爜
+ MsgBoxHelper2.Warn($"{targetTable.title}鐐夌敓浜т腑锛屼笉鍏佽鎿嶄綔鏉$爜");
+ //MsgBoxHelper2.Warn(this.lang("Tr.CantClearSNR"));
+ return;
+ }
+
if (snrCode == null)
{
var oldCellInfo = e.lastInfo;
- var oldCell = TestResultView.nameTables[oldCellInfo.OvenName].GetSingleCell(oldCellInfo.Index);
+ var oldTable = TestResultView.nameTables[oldCellInfo.OvenName];
+ var oldCell = oldTable.GetSingleCell(oldCellInfo.Index);
if (oldCell.status != "hadCode")
{
throw new Exception(this.lang("Tr.PositionCantClearSNR", oldCellInfo.OriginCode));
@@ -441,18 +464,10 @@
//parent.engine.Globals.SetValString(LookupStr, 1, snrCode);
//parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false);
- TestResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).SetStatus("hadCode");
- TestResultView.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).sn = snrCode;
+ cell.SetStatus("hadCode");
+ cell.sn = snrCode;
Scanner.InsertNewCode(snrCode, cellInfo);
- var light = $"Oven{this.index + 1}_Cell{cell.index + 1}_Light_OK";
- if (cell.LightGreen(true, out string msg))
- {
- ViewControl.Logger.Debug($"Open Light [{light}] ON.");
- }
- else
- {
- ViewControl.Logger.Debug($"Open Light [{light}] Error.{msg}");
- }
+ cell.LightGreen(true, out string msg);
}
@@ -572,16 +587,18 @@
string strs = datas_10015[2];
string[] values = strs.Split(',');
-
- GetSingleCell(cellIndex).SetInfos(new Info
+ Dispatcher.Invoke(() =>
{
- step = values[0],
- value = values[1],
- limitUp = values[2],
- limitDown = values[3],
- unit = values[4],
- result = values[5],
- updateTime = values[6]
+ GetSingleCell(cellIndex).SetInfos(new Info
+ {
+ step = values[0],
+ value = values[1],
+ limitUp = values[2],
+ limitDown = values[3],
+ unit = values[4],
+ result = values[5],
+ updateTime = values[6]
+ });
});
//session.Send("1");
}
@@ -786,7 +803,7 @@
private void ClearAllSnr_Click(object sender, RoutedEventArgs e)
{
- if (parent.executionWrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) == true)
+ if (GetDoorClose(parent.executionWrapper))
{
/// 鍏抽棬浜嗗氨涓嶅厑璁告竻鏉$爜
MsgBoxHelper2.Warn(this.lang("Tr.CantClearSNR"));
@@ -818,7 +835,7 @@
public void TryClearCellSN(int cellIndex)
{
- if (parent.executionWrapper?.GetStationGlobalValue<bool>($"StationState.DoorClose[{this.index}]", 0) == true)
+ if (GetDoorClose(parent.executionWrapper))
{
MsgBoxHelper.Error(Window.GetWindow(this), this.lang("Tr.CantClearSNR"));
return;
@@ -851,10 +868,7 @@
return;
}
-
-
-
- string key = $"StationState.Start[{this.index}]";
+ //string key = $"StationState.Start[{this.index}]";
//if (parent.executionWrapper?.GetStationGlobalValue<bool>(key, 0) == true)
//{
// MsgBoxHelper2.Warn("娴嬭瘯鍚姩涓紝涓嶅厑璁窤bort");
@@ -873,9 +887,9 @@
{
return;
}
- LogHelper.Info("UI", "Abort鎸夐挳鎸変笅", out _);
- ViewControl.Logger.Info("Abort鎸夐挳鎸変笅");
- key = $"StationState.Abort[{this.index}]";
+ LogHelper.Info("UI", $"{title} Abort鎸夐挳鎸変笅", out _);
+ ViewControl.Logger.Info($"{title} Abort鎸夐挳鎸変笅");
+ string key = $"StationState.Abort[{this.index}]";
parent.executionWrapper?.SetStationGlobalValue(key, 0, true);
}
}
diff --git a/Plugin.TestResult/Properties/AssemblyInfo.cs b/Plugin.TestResult/Properties/AssemblyInfo.cs
index eebb8a0..dbda48a 100644
--- a/Plugin.TestResult/Properties/AssemblyInfo.cs
+++ b/Plugin.TestResult/Properties/AssemblyInfo.cs
@@ -50,6 +50,6 @@
//鍙互鎸囧畾鎵�鏈夎繖浜涘�硷紝涔熷彲浠ヤ娇鐢ㄢ�滅敓鎴愬彿鈥濆拰鈥滀慨璁㈠彿鈥濈殑榛樿鍊�
//閫氳繃浣跨敤 "*"锛屽涓嬫墍绀�:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.1.0")]
+[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: PluginClassName("Plugin.TestResult_WPF.ViewControl")]
diff --git a/Plugin.TestResult/Scanner.xaml.cs b/Plugin.TestResult/Scanner.xaml.cs
index 48bf1c5..aeba0b8 100644
--- a/Plugin.TestResult/Scanner.xaml.cs
+++ b/Plugin.TestResult/Scanner.xaml.cs
@@ -158,12 +158,27 @@
{
try
{
- this.targetCellInfo = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, barcode);
+ var targetCellInfo = ScannerParser.GetCellInfoByCode(this.model, this.columns, this.rows, barcode);
if (!TestResultView.nameTables.ContainsKey(targetCellInfo.OvenName))
{
MsgBoxHelper2.Error($"鑰佸寲鐐� [{targetCellInfo.OvenName}] 涓嶅瓨鍦紝璇锋鏌ラ厤缃�");
return;
}
+ var sourceTable = TestResultView.tables[this.ovenIndex];
+ if (sourceTable.title != targetCellInfo.OvenName)
+ {
+ MsgBoxHelper2.Error($"璇峰垏鎹㈣嚦 [{targetCellInfo.OvenName}] 鍖烘壂鐮侊紝褰撳墠涓� [{sourceTable.title}] 鍖猴紒");
+ return;
+ }
+
+ var oven = TestResultView.nameTables[targetCellInfo.OvenName];
+ if (oven.cells.Length < targetCellInfo.Index + 1)
+ {
+ MsgBoxHelper2.Error($"绌翠綅鍙� [{barcode}] 瓒呭嚭绱㈠紩 {targetCellInfo.Index}");
+ return;
+ }
+
+ this.targetCellInfo = targetCellInfo;
positionText.Text = barcode;
//positionText.Focus();
//snrText.Text = "";
@@ -229,13 +244,14 @@
var EnableMes = ParameterManager.GetCommonParameterByName<bool>("EnableMes", false);
if (ParamSetting.CustomerCode == "LIXUN" && EnableMes)
{
- var table = TestResultView.tables[this.ovenIndex];
+ var table = TestResultView.nameTables[targetCellInfo.OvenName];
+ // TestResultView.tables[this.ovenIndex]
string currentPn = table.CbProduct.Text;
/// 妫�鏌ユ牸寮�
if (!SNValidator.ValidateSN(currentPn, snr, out string msg))
{
- TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革細{msg}");
snrText.Text = string.Empty;
snrText.Focus();
@@ -246,7 +262,7 @@
string stationName = ProductManager.GetParameterByProductAndName(currentPn, "MES绔欎綅")?.Value;
if (string.IsNullOrEmpty(stationName))
{
- TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革紝褰撳墠浜у搧[{currentPn}]鏈缃弬鏁癕ES绔欎綅");
snrText.Text = string.Empty;
snrText.Focus();
@@ -256,10 +272,10 @@
/// 妫�鏌N
if (PNUtil.GetPN(ParamSetting.MesAddress, stationName, snr, out string pn, out msg))
{
-
+
if (pn != currentPn)
{
- TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"褰撳墠娴嬭瘯鏂欏彿涓� [{currentPn}]锛屾壂鐮佷骇鍝佹枡鍙蜂负 [{pn}] 涓嶅厑璁告祴璇�");
snrText.Text = string.Empty;
snrText.Focus();
@@ -268,7 +284,7 @@
}
else
{
- TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"妫�鏌ヤ骇鍝佹潯鐮佸紓甯革細{msg}");
snrText.Text = string.Empty;
snrText.Focus();
@@ -280,7 +296,7 @@
{
if (needCheckIn != true)
{
- TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"鏉$爜[{snr}]宸ュ簭涓嶅湪鏈珯锛歿msg}");
snrText.Text = string.Empty;
snrText.Focus();
@@ -289,7 +305,7 @@
}
else
{
- TestResultView.tables[this.ovenIndex].GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
+ table.GetSingleCell(targetCellInfo.Index).LightRed(true, out _);
MsgBoxHelper2.Error($"鏉$爜[{snr}]CheckIn澶辫触锛歿msg}");
snrText.Text = string.Empty;
snrText.Focus();
@@ -399,11 +415,11 @@
}
else
{
- if (ParamSetting.CustomerCode != "LIXUN")
- {
- snrText.Focus();
- return;
- }
+ //if (ParamSetting.CustomerCode != "LIXUN")
+ //{
+ // snrText.Focus();
+ // return;
+ //}
string barcode = positionText.Text;
try
{
@@ -416,10 +432,21 @@
targetCellInfo = null;
return;
}
+
+ var sourceTable = TestResultView.tables[this.ovenIndex];
+ if (sourceTable.title != targetCellInfo.OvenName)
+ {
+ MsgBoxHelper2.Error($"璇峰垏鎹㈣嚦 [{targetCellInfo.OvenName}] 鍖烘壂鐮侊紝褰撳墠涓� [{sourceTable.title}] 鍖猴紒");
+ positionText.Text = string.Empty;
+ positionText.Focus();
+ targetCellInfo = null;
+ return;
+ }
+
var oven = TestResultView.nameTables[targetCellInfo.OvenName];
if (oven.cells.Length < targetCellInfo.Index + 1)
{
- MsgBoxHelper2.Error($"绌翠綅涓嬫爣 [{targetCellInfo.Index}] 瓒呭嚭绱㈠紩");
+ MsgBoxHelper2.Error($"绌翠綅鍙� [{barcode}] 瓒呭嚭绱㈠紩 {targetCellInfo.Index}");
positionText.Text = string.Empty;
positionText.Focus();
targetCellInfo = null;
diff --git a/Plugin.TestResult/SingleCell.xaml.cs b/Plugin.TestResult/SingleCell.xaml.cs
index b9a6ab0..0e7a8b9 100644
--- a/Plugin.TestResult/SingleCell.xaml.cs
+++ b/Plugin.TestResult/SingleCell.xaml.cs
@@ -297,6 +297,17 @@
private string visualTestId;
private Sqlite3Helper helper;
+ private void InitCurrentTestHelper()
+ {
+ if (helper == null)
+ {
+ var now = DateTime.Now;
+ string dateStr = now.ToString("yyyyMMdd");
+ visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}";
+ helper = CheckSqlHelper(dateStr);
+ }
+ }
+
public void SetStatus(string status)
{
Dispatcher.Invoke(() =>
@@ -306,11 +317,8 @@
if (oldStatus != "testing" && status == "testing")
{
UpdateProbeCount(ProbeCount + 1);
- var now = DateTime.Now;
- string dateStr = now.ToString("yyyyMMdd");
- visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}";
- helper = CheckSqlHelper(dateStr);
- InsertARecourd();
+ InitCurrentTestHelper();
+ InsertARecord();
}
if (oldStatus != "ok" && status == "ok")
@@ -325,7 +333,7 @@
});
}
- private void InsertARecourd()
+ private void InsertARecord()
{
try
{
@@ -336,7 +344,7 @@
}
catch (Exception ex)
{
- ViewControl.Logger.Error($"Cell[{title}] SaveToDB Error.", ex);
+ ViewControl.Logger.Error($"Cell[{title}] InsertARecord Error.", ex);
}
}
@@ -457,6 +465,7 @@
try
{
+ InitCurrentTestHelper();
string model = table?.CbProduct?.SelectedItem?.ToString();
sql = $@"INSERT INTO serialData (sn,model,station,position,step,limitDown,limitUp,unit,value,status,finalStatus,time,resultId)
VALUES ('{sn}','{model}','','{this.title}','{info.step}','{info.limitDown}','{info.limitUp}','{info.unit}','{info.value}','{info.result}',
@@ -992,7 +1001,7 @@
/// <param name="filePath"></param>
public void SaveInfoToDB()
{
- Dispatcher.BeginInvoke(new Action(() =>
+ Dispatcher.Invoke(() =>
{
try
{
@@ -1021,7 +1030,7 @@
{
ViewControl.Logger.Error($"Cell[{title}] SaveToDB Error.", ex);
}
- }));
+ });
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
@@ -1093,8 +1102,17 @@
public bool LightGreen(bool on, out string msg)
{
- return S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME,
- $"Oven{table.index + 1}_Cell{index + 1}_Light_OK", on, out msg);
+ string key = $"Oven{table.index + 1}_Cell{index + 1}_Light_OK";
+ bool res = S7Context.WriteData(RunTimeVariablePool.DEFAULT_PLC_NAME, key, on, out msg);
+ if (res)
+ {
+ ViewControl.Logger.Debug($"Set Light [{key}] {on}.");
+ }
+ else
+ {
+ ViewControl.Logger.Debug($"Open Light [{key}] {on} Error.{msg}");
+ }
+ return res;
}
public bool LightRed(bool on, out string msg)
diff --git a/Plugin.TestResult/TestResultView.xaml.cs b/Plugin.TestResult/TestResultView.xaml.cs
index 9182ea0..0d461da 100644
--- a/Plugin.TestResult/TestResultView.xaml.cs
+++ b/Plugin.TestResult/TestResultView.xaml.cs
@@ -2,13 +2,11 @@
using HMI.Core.Manager;
using HMI.Core.Util;
using HMI.UI.Util;
-using NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using Plugin.TestResult_WPF.Model;
using Plugin.TsSupport;
using System;
using System.Collections.Generic;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
@@ -143,26 +141,19 @@
InitializeComponent();
- executionWrapper = new TsExecutionWrapper(); //new TsExecutionWrapper();
- if (executionWrapper is TsExecutionWrapper tsWrapper)
+
+ }
+
+ private void ExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+ {
+ try
{
- tsWrapper.AxApplicationMgr.ExitApplication += this.axApplicationMgr_ExitApplication;
- tsWrapper.AxApplicationMgr.UIMessageEvent += this.axApplicationMgr_UIMessageEvent;
- tsWrapper.AxApplicationMgr.ExecutionClosed += this.axApplicationMgr_ExecutionClosed;
- ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
- host.Child = tsWrapper.AxApplicationMgr;
- ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).EndInit();
+ HandleUIMessage(e.EventCode, Convert.ToInt16(e.NumberData), e.StrData, e.Data);
}
+ catch (Exception ex)
+ {
-
-
- //testApp = TestAppManager.GetAxApplicationMgr();
- //testApp.ExitApplication += this.axApplicationMgr_ExitApplication;
- //testApp.UIMessageEvent += this.axApplicationMgr_UIMessageEvent;
- //testApp.ExecutionClosed += this.axApplicationMgr_ExecutionClosed;
- //((System.ComponentModel.ISupportInitialize)(this.testApp)).BeginInit();//myClient涓虹涓夋柟鎺т欢鍚�
- //host.Child = testApp;
- //((System.ComponentModel.ISupportInitialize)(this.testApp)).EndInit();
+ }
}
private void Refresh()
@@ -217,10 +208,26 @@
/// <summary>
/// 鍚姩娴嬭瘯搴忓垪
/// </summary>
- public void InitTestStandEngine()
+ public void InitTestStandEngine(bool isTap)
{
try
{
+ if (isTap)
+ {
+ executionWrapper = new TapWrapper();
+ }
+ else
+ {
+ executionWrapper = new TsExecutionWrapper();
+ }
+ executionWrapper.UIMessageEvent += ExecutionWrapper_UIMessageEvent;
+
+ if (executionWrapper is TsExecutionWrapper tsWrapper)
+ {
+ ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).BeginInit();
+ host.Child = tsWrapper.AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(tsWrapper.AxApplicationMgr)).EndInit();
+ }
//this.engine = this.testApp.GetEngine();
//this.engine.PersistBreakpoints = false;
//this.testApp.IsEditor = true;
@@ -258,7 +265,7 @@
try
{
executionWrapper?.SetStationGlobalValue<bool>("StationState.StopTest", 0, true, true);
-
+
try
{
executionWrapper?.WaitForExit();
@@ -284,12 +291,14 @@
}
}
+ [Obsolete]
private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
{
//Environment.ExitCode = testApp.ExitCode;
//TSHelper.DoSynchronousGCForCOMObjectDestruction();
}
+ [Obsolete]
private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
{
try
@@ -303,31 +312,23 @@
}
}
- private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+
+ private void HandleUIMessage(int EventCase, int MethodCode, string strData, object xData)
{
try
{
- int EventCase = Convert.ToInt32(e.uiMsg.Event);
- int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
- string strData;
-
if (EventCase != 10014) return;
if (MethodCode == 0)
{
/// 璁剧疆鍙ユ焺
- //this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
- if (executionWrapper is TsExecutionWrapper tsWrapper)
- {
- tsWrapper.context = (SequenceContext)e.uiMsg.ActiveXData;
- }
+ executionWrapper.SetContext(xData);
return;
}
if (MethodCode == 1)
{
/// 鏇存柊鐐夊瓙鐘舵��
- strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
@@ -338,7 +339,6 @@
if (MethodCode == 2)
{
/// 鏇存柊鐐夊瓙鏁伴噺淇℃伅
- strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
@@ -351,7 +351,6 @@
if (MethodCode == 3)
{
/// 鏇存柊鐐夊瓙鏃堕棿淇℃伅
- strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
string startTime = datas_10014[1];
@@ -372,7 +371,6 @@
if (MethodCode == 4)
{
/// 鏇存柊鑰佸寲鐐夊簳閮ㄧ姸鎬佹爮
- strData = e.uiMsg.StringData;
string[] datas_10014 = strData.Split(';');
int ovenIndex = int.Parse(datas_10014[0]);
@@ -383,7 +381,6 @@
if (MethodCode == 5)
{
/// 閲囬泦鐐夋俯搴�
- strData = e.uiMsg.StringData;
string[] datas_10016 = strData.Split(';');
int ovenIndex = int.Parse(datas_10016[0]);
@@ -399,29 +396,28 @@
}
if (MethodCode == 6)
{
- /// 鏇存柊绌翠綅鐘舵��
- strData = e.uiMsg.StringData;
- string[] datas_10015 = strData.Split(';');
- int ovenIndex = int.Parse(datas_10015[0]);
- int cellIndex = int.Parse(datas_10015[1]);
- string status_10015 = datas_10015[2];
- tables[ovenIndex].GetSingleCell(cellIndex).SetStatus(status_10015);
+ Dispatcher.Invoke(() =>
+ {/// 鏇存柊绌翠綅鐘舵��
+ string[] datas_10015 = strData.Split(';');
+ int ovenIndex = int.Parse(datas_10015[0]);
+ int cellIndex = int.Parse(datas_10015[1]);
+ string status_10015 = datas_10015[2];
+ tables[ovenIndex].GetSingleCell(cellIndex).SetStatus(status_10015);
- if (status_10015 == "OK" || status_10015 == "ok")
- {
- tables[ovenIndex].RefreshCount(1, 0);
- }
- else if (status_10015 == "ng" || status_10015 == "NG")
- {
- tables[ovenIndex].RefreshCount(0, 1);
- }
-
+ if (status_10015 == "OK" || status_10015 == "ok")
+ {
+ tables[ovenIndex].RefreshCount(1, 0);
+ }
+ else if (status_10015 == "ng" || status_10015 == "NG")
+ {
+ tables[ovenIndex].RefreshCount(0, 1);
+ }
+ });
return;
}
if (MethodCode == 7)
{
/// 鏇存柊绌翠綅鍙傛暟
- strData = e.uiMsg.StringData;
string[] datas_10015 = strData.Split(';');
int ovenIndex = int.Parse(datas_10015[0]);
int cellIndex = int.Parse(datas_10015[1]);
@@ -446,7 +442,6 @@
if (MethodCode == 10)
{
/// 娓呯┖鐐夊瓙鐨勬俯搴﹀浘琛�
- strData = e.uiMsg.StringData;
int ovenIndex = int.Parse(strData);
tables[ovenIndex].ClearChartData();
return;
@@ -454,7 +449,6 @@
if (MethodCode == 11)
{
/// 娓呴櫎绌翠綅鍙傛暟
- strData = e.uiMsg.StringData;
string[] datas_10015 = strData.Split(';');
int ovenIndex = int.Parse(datas_10015[0]);
int cellIndex = int.Parse(datas_10015[1]);
@@ -465,7 +459,6 @@
if (MethodCode == 12)
{
/// 淇濆瓨鐐変綋娓╁害鏂囦欢
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
string folder = datas[1];
@@ -475,7 +468,6 @@
if (MethodCode == 13)
{
/// 娣诲姞鐢垫祦鏁版嵁
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -487,7 +479,6 @@
if (MethodCode == 14)
{
/// 娓呯┖鐢垫祦鍜岀數鍘嬫暟鎹�
- strData = e.uiMsg.StringData;
int ovenIndex = int.Parse(strData);
tables[ovenIndex].ClearCellData();
//tables[ovenIndex].ClearElectricData();
@@ -499,7 +490,6 @@
if (MethodCode == 15)
{
/// 淇濆瓨鐢垫祦鏁版嵁
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -511,7 +501,6 @@
if (MethodCode == 16)
{
/// 娣诲姞鐢靛帇鍥捐〃鏁版嵁
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -523,7 +512,6 @@
if (MethodCode == 17)
{
/// 淇濆瓨鐢靛帇鏁版嵁
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -535,7 +523,6 @@
if (MethodCode == 18)
{
/// 淇濆瓨绌翠綅娴嬭瘯鏁版嵁鍒癈SV
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -546,7 +533,6 @@
if (MethodCode == 180)
{
/// 淇濆瓨绌翠綅娴嬭瘯鏁版嵁鍒癈SV
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -558,7 +544,6 @@
if (MethodCode == 19)
{
/// 淇濆瓨绌翠綅娴嬭瘯鏁版嵁鍒癝qlite
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -569,7 +554,6 @@
if (MethodCode == 20)
{
/// 娓呯┖鏉$爜
- strData = e.uiMsg.StringData;
int ovenIndex = int.Parse(strData);
tables[ovenIndex].ClearAllSN();
return;
@@ -578,7 +562,6 @@
if (MethodCode == 21)
{
/// 娣诲姞姘存祦鍥捐〃鏁版嵁
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int ovenIndex = int.Parse(datas[0]);
int cellIndex = int.Parse(datas[1]);
@@ -591,7 +574,6 @@
if (MethodCode == 99)
{
- strData = e.uiMsg.StringData;
string[] datas = strData.Split(';');
int index = int.Parse(datas[0]);
if (MsgBoxHelper2.WarnChoose(datas[1], "鎻愮ず") == MessageBoxResult.OK)
@@ -613,6 +595,14 @@
}
}
+ private void axApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+ {
+ int EventCase = Convert.ToInt32(e.uiMsg.Event);
+ int MethodCode = Convert.ToInt16(e.uiMsg.NumericData);
+ string strData = e.uiMsg.StringData;
+ HandleUIMessage(EventCase, MethodCode, strData, e.uiMsg.ActiveXData);
+ }
+
public void SetStartFlag(int index, bool data)
{
string name = tables[index].title;
@@ -620,28 +610,11 @@
string key = $"StationState.Start[{index}]";
executionWrapper?.SetStationGlobalValue<bool>(key, 1, data);
-
- if (data == false)
- {
- key = $"StationState.Scanner[{index}]";
- executionWrapper?.SetStationGlobalValue<bool>(key, 1, false);
- }
- }
-
- public bool? GetStartFlag(int index)
- {
- string key = $"StationState.Start[{index}]";
- return executionWrapper.GetStationGlobalValue<bool>(key, 0);
}
public void ReleaseResource()
{
- if (executionWrapper is TsExecutionWrapper tsWrapper)
- {
- tsWrapper.AxApplicationMgr.ExitApplication -= this.axApplicationMgr_ExitApplication;
- tsWrapper.AxApplicationMgr.UIMessageEvent -= this.axApplicationMgr_UIMessageEvent;
- tsWrapper.AxApplicationMgr.ExecutionClosed -= this.axApplicationMgr_ExecutionClosed;
- }
+ executionWrapper.UIMessageEvent -= ExecutionWrapper_UIMessageEvent;
foreach (var table in tables)
{
diff --git a/Plugin.TestResult/ViewControl.xaml.cs b/Plugin.TestResult/ViewControl.xaml.cs
index d7e2f96..ebff038 100644
--- a/Plugin.TestResult/ViewControl.xaml.cs
+++ b/Plugin.TestResult/ViewControl.xaml.cs
@@ -112,17 +112,62 @@
timer.Elapsed += Timer_Elapsed;
InitializeComponent();
- if (testResultView.executionWrapper is TsExecutionWrapper tsWrapper)
- {
- tsWrapper.AxApplicationMgr.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
- tsWrapper.AxApplicationMgr.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
- tsWrapper.AxApplicationMgr.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
- }
-
//testResultView.testApp.ExitApplication += new EventHandler(this.axApplicationMgr_ExitApplication);
//testResultView.testApp.UIMessageEvent += new _ApplicationMgrEvents_UIMessageEventEventHandler(this.axApplicationMgr_UIMessageEvent);
//testResultView.testApp.ExecutionClosed += new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.axApplicationMgr_ExecutionClosed);
+ }
+
+ private void HandleUIMessage(int EventCase, int MethodCode, string strData, object xData)
+ {
+ try
+ {
+ try
+ {
+ log.Debug($"EventCase: {EventCase}, MethodCode: {MethodCode}, StrData: {strData}");
+ }
+ catch
+ {
+
+ }
+
+ if (EventCase == 8)
+ {
+ IsRunning = false;
+ return;
+ }
+
+ if (EventCase != 10014) return;
+
+ if (MethodCode == 0)
+ {
+ /// 璁剧疆鍙ユ焺
+ this.SequenceContext = (SequenceContext)xData;
+ return;
+ }
+
+
+ if (MethodCode == 8)
+ {
+ /// 鏇存柊MES鐘舵��
+ mesStatus = strData == "1";
+ return;
+ }
+
+ if (MethodCode == 9)
+ {
+ /// 鏇存柊鐢熶骇鐘舵��
+ produceStatus = strData;
+ return;
+ }
+ }
+ catch
+ { }
+ }
+
+ private void ExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+ {
+ HandleUIMessage(e.EventCode, Convert.ToInt16(e.NumberData), e.StrData, e.Data);
}
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
@@ -142,7 +187,6 @@
string path = Path.Combine(BaseFolder, "Count.ini");
testResultView.SetCountIniPath(path);
testResultView.InitMainGrid();
- testResultView.InitTestStandEngine();
path = Path.Combine(BaseFolder, "Scanner.ini");
if (!File.Exists(path))
@@ -174,6 +218,12 @@
testResultView.testSeqFile = string.Empty;
FileName = string.Empty;
}
+ string type = Path.GetExtension(FileName);
+ bool isTap = string.Equals(".tapplan", type, StringComparison.OrdinalIgnoreCase);
+
+ testResultView.InitTestStandEngine(isTap);
+ testResultView.executionWrapper.UIMessageEvent += ExecutionWrapper_UIMessageEvent;
+
RefreshUIConfig();
}
@@ -204,67 +254,6 @@
{
log.Error("RefreshUIConfig Error.", ex);
}
- }
-
- private void axApplicationMgr_ExitApplication(object sender, EventArgs e)
- {
- }
-
- private void axApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
- {
- }
-
- 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;
-
- try
- {
- log.Debug($"EventCase: {EventCase}, MethodCode: {MethodCode}, StrData: {e.uiMsg.StringData}");
- }
- catch
- {
-
- }
-
- if (EventCase == 8)
- {
- IsRunning = false;
- return;
- }
-
- if (EventCase != 10014) return;
-
- if (MethodCode == 0)
- {
- /// 璁剧疆鍙ユ焺
- this.SequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
- return;
- }
-
-
- if (MethodCode == 8)
- {
- /// 鏇存柊MES鐘舵��
- strData = e.uiMsg.StringData;
- mesStatus = strData == "1";
- return;
- }
-
- if (MethodCode == 9)
- {
- /// 鏇存柊鐢熶骇鐘舵��
- strData = e.uiMsg.StringData;
- produceStatus = strData;
- return;
- }
- }
- catch
- { }
}
private bool isLoaded;
diff --git a/Plugin.TsExecution/Plugin.TsExecution.csproj b/Plugin.TsExecution/Plugin.TsExecution.csproj
index ef4aad0..e63a2e4 100644
--- a/Plugin.TsExecution/Plugin.TsExecution.csproj
+++ b/Plugin.TsExecution/Plugin.TsExecution.csproj
@@ -88,6 +88,10 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
</Reference>
+ <Reference Include="NPOI, Version=2.4.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\HMI.ParameterManage\bin\x64\Debug\NPOI.dll</HintPath>
+ </Reference>
<Reference Include="OpenTK, Version=3.3.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\WPFProject\packages\OpenTK.3.3.1\lib\net20\OpenTK.dll</HintPath>
</Reference>
@@ -264,6 +268,10 @@
<Project>{f8b8b6b6-821b-4ff6-b556-9cab840ea57a}</Project>
<Name>HMI.MQUtil</Name>
</ProjectReference>
+ <ProjectReference Include="..\SimpleUtil\HMI.Simple.Util\HMI.Simple.Util.csproj">
+ <Project>{CF5BEBE9-2803-49C3-B773-73D082E0984A}</Project>
+ <Name>HMI.Simple.Util</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
diff --git a/Plugin.TsExecution/Properties/AssemblyInfo.cs b/Plugin.TsExecution/Properties/AssemblyInfo.cs
index 8c79373..87940bc 100644
--- a/Plugin.TsExecution/Properties/AssemblyInfo.cs
+++ b/Plugin.TsExecution/Properties/AssemblyInfo.cs
@@ -32,13 +32,13 @@
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
-[assembly:ThemeInfo(
+[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //涓婚鐗瑰畾璧勬簮璇嶅吀鎵�澶勪綅缃�
- //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
- //鎴栧簲鐢ㄧ▼搴忚祫婧愬瓧鍏镐腑鎵惧埌鏃朵娇鐢�)
+ //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+ //鎴栧簲鐢ㄧ▼搴忚祫婧愬瓧鍏镐腑鎵惧埌鏃朵娇鐢�)
ResourceDictionaryLocation.SourceAssembly //甯歌璧勬簮璇嶅吀鎵�澶勪綅缃�
- //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
- //銆佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚涓撶敤璧勬簮瀛楀吀涓壘鍒版椂浣跨敤)
+ //(鏈湪椤甸潰涓壘鍒拌祫婧愭椂浣跨敤锛�
+ //銆佸簲鐢ㄧ▼搴忔垨浠讳綍涓婚涓撶敤璧勬簮瀛楀吀涓壘鍒版椂浣跨敤)
)]
@@ -49,6 +49,6 @@
// 鐢熸垚鍙�
// 淇鍙�
//
-[assembly: AssemblyVersion("1.0.0.3")]
-[assembly: AssemblyFileVersion("1.0.0.3")]
+[assembly: AssemblyVersion("1.0.0.7")]
+[assembly: AssemblyFileVersion("1.0.0.7")]
[assembly: PluginClassName("Plugin.TsExecution.TsExecution")]
diff --git a/Plugin.TsExecution/ScreenTouch.xaml b/Plugin.TsExecution/ScreenTouch.xaml
index f5ee1f2..fb7d5fb 100644
--- a/Plugin.TsExecution/ScreenTouch.xaml
+++ b/Plugin.TsExecution/ScreenTouch.xaml
@@ -8,7 +8,7 @@
xmlns:dp="clr-namespace:HMI.UI.DpUtil;assembly=HMI.UI"
xmlns:hb="clr-namespace:HMI.Base;assembly=HMI.Base"
d:DesignHeight="450" d:DesignWidth="800">
- <UniformGrid x:Name="uniform" dp:UniformGridHelper.InnerBorder="0.3" Background="LightGray"
- dp:UniformGridHelper.InnerBorderBrush="Transparent">
+ <UniformGrid x:Name="uniform" dp:UniformGridHelper.InnerBorder="0.5"
+ dp:UniformGridHelper.InnerBorderBrush="#37375f">
</UniformGrid>
</hb:NotifyControl>
diff --git a/Plugin.TsExecution/ScreenTouch.xaml.cs b/Plugin.TsExecution/ScreenTouch.xaml.cs
index 431f740..4cf1f19 100644
--- a/Plugin.TsExecution/ScreenTouch.xaml.cs
+++ b/Plugin.TsExecution/ScreenTouch.xaml.cs
@@ -1,4 +1,5 @@
锘縰sing HMI.Base;
+using HMI.UI.DpUtil;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
@@ -108,6 +109,7 @@
children[i] = border;
uniform.Children.Add(border);
}
+ UniformGridHelper.RefreshGridInnerBorder(uniform);
}
public void Refresh(int rows, int columns)
@@ -140,6 +142,25 @@
Values = temp;
}
+ public void DrawNewPoints(int[][] points)
+ {
+ var temp = Values == null ?
+ new ObservableCollection<bool>(new bool[rows * columns]) :
+ new ObservableCollection<bool>(Values);
+ for (int i = 0; i < points.Length; i++)
+ {
+ int[] point = points[i];
+ if (point == null)
+ {
+ continue;
+ }
+ int index = point[1] * columns + point[0];
+ //children[point[0]][point[1]].Background = Brushes.Green;
+ temp[index] = true;
+ }
+ Values = temp;
+ }
+
private void PaintPoints()
{
for (int i = 0; i < Values.Count; i++)
diff --git a/Plugin.TsExecution/SingleControl.xaml b/Plugin.TsExecution/SingleControl.xaml
index 8a31373..16720c0 100644
--- a/Plugin.TsExecution/SingleControl.xaml
+++ b/Plugin.TsExecution/SingleControl.xaml
@@ -125,8 +125,7 @@
</Label>
<Label Content="{Binding Status}" VerticalAlignment="Center" VerticalContentAlignment="Center"
- Padding="0"
- Margin="0"
+ Padding="0" Margin="0"
HorizontalContentAlignment="Center"
Foreground="#FFF"
FontWeight="Bold"
diff --git a/Plugin.TsExecution/SingleControl.xaml.cs b/Plugin.TsExecution/SingleControl.xaml.cs
index 3e3c21a..373fcd4 100644
--- a/Plugin.TsExecution/SingleControl.xaml.cs
+++ b/Plugin.TsExecution/SingleControl.xaml.cs
@@ -1,14 +1,17 @@
锘縰sing 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.Linq;
using System.Runtime.CompilerServices;
using System.Timers;
using System.Windows;
@@ -243,7 +246,7 @@
Interval = 100
};
refreshTimer.Elapsed += RefreshTimer_Elapsed;
- ReadProbeCount();
+ RefreshProbeCount(null);
ReadCounter();
InitializeComponent();
try
@@ -397,37 +400,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",
@@ -456,9 +428,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
{
@@ -488,7 +499,7 @@
{
TsExecution.logger.Error("Write CSV File Failed.", ex);
}
- }));
+ });
}
public void ShowPausePanel()
@@ -534,17 +545,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)
@@ -605,16 +606,59 @@
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;
+
+ //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)
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 4578fdb..9575fb8 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -6,11 +6,13 @@
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.MQUtil;
+using HMI.Simple.Util;
using HMI.UI.Util;
using HMI.Util;
using log4net;
using NationalInstruments.TestStand.Interop.API;
-using NationalInstruments.TestStand.Interop.UI.Ax;
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
using Plugin.TsSupport;
using ScottPlot;
using ScottPlot.Plottables;
@@ -20,8 +22,6 @@
using System.ComponentModel;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
-using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms.DataVisualization.Charting;
@@ -37,24 +37,23 @@
/// <summary>
/// TS 寮曟搸
/// </summary>
- private Engine engine = null;
+ //private Engine engine = null;
+
+ ///// <summary>
+ ///// 娴嬭瘯搴忓垪
+ ///// </summary>
+ //private SequenceFile testSeq = null;
+
+ ///// <summary>
+ ///// 娴嬭瘯妯″瀷搴忓垪
+ ///// </summary>
+ //private SequenceFile modeSeq = null;
+
+ //private Execution execution = null;
private string testSeqFile = string.Empty;
- /// <summary>
- /// 娴嬭瘯搴忓垪
- /// </summary>
- private SequenceFile testSeq = null;
- /// <summary>
- /// 娴嬭瘯妯″瀷搴忓垪
- /// </summary>
- private SequenceFile modeSeq = null;
- public AxApplicationMgr AxApplicationMgr;
- private Execution execution = null;
-
- private SequenceContext sequenceContext = null;
-
- private Chart chart;
+ private ITestExecutionWrapper testExecutionWrapper;
#endregion
public static ILog logger { get; private set; }
@@ -83,7 +82,6 @@
private bool isLoadOK = false;
- private Timer GCTimer;
private int PassAmount = 0;
private int FailAmount = 0;
@@ -109,6 +107,7 @@
foreach (SingleControl socket in tsSockets)
{
socket.RefreshProduct(value);
+ // socket.RefreshProbeCount(value);
}
}
SetTestSeqFile(value);
@@ -182,9 +181,12 @@
get => _enableCanLog;
set
{
- if (WriteConfig("EnableCanLog", value))
+ if (RequirePassword() == true)
{
- Set(ref _enableCanLog, value);
+ if (WriteConfig("EnableCanLog", value))
+ {
+ Set(ref _enableCanLog, value);
+ }
}
}
}
@@ -227,10 +229,13 @@
get => _enableSimpleMode;
set
{
- if (WriteConfig("EnableSimpleMode", value))
+ if (RequirePassword() == true)
{
- Set(ref _enableSimpleMode, value);
- foreach (var cell in tsSockets) cell.SetSimpleUI(value);
+ if (WriteConfig("EnableSimpleMode", value))
+ {
+ Set(ref _enableSimpleMode, value);
+ foreach (var cell in tsSockets) cell.SetSimpleUI(value);
+ }
}
}
}
@@ -241,10 +246,13 @@
get => _ui_showInfoDock;
set
{
- if (WriteConfig("UI_ShowInfoDock", value))
+ if (RequirePassword() == true)
{
- Set(ref _ui_showInfoDock, value);
- detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+ if (WriteConfig("UI_ShowInfoDock", value))
+ {
+ Set(ref _ui_showInfoDock, value);
+ detailPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
+ }
}
}
}
@@ -268,8 +276,8 @@
if (WriteIni("UI_CurrentWorkorder", value))
{
Set(ref currentWorkorder, value);
- engine?.Globals.SetValString("StationState.WorkOrder", 1, value);
- engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+ testExecutionWrapper?.SetStationGlobalValue("StationState.WorkOrder", 1, value);
+ testExecutionWrapper?.CommitToDisk(false);
}
}
}
@@ -280,9 +288,12 @@
get => _DisableScanner;
set
{
- if (WriteConfig("DisableScanner", value))
+ if (RequirePassword() == true)
{
- Set(ref _DisableScanner, value);
+ if (WriteConfig("DisableScanner", value))
+ {
+ Set(ref _DisableScanner, value);
+ }
}
}
}
@@ -297,13 +308,10 @@
public TsExecution()
{
DataContext = this;
- GCTimer = new Timer();
InitializeComponent();
InitChart();
InitTsEngine();
- //鍒濆鍖朤estStand寮曟搸
- this.InitTestStandEngine();
}
public override void SetBaseFolder(string folder)
@@ -373,8 +381,9 @@
{
UserInfo user = UserInfo.User;
CurrentUserCode = user?.Code;
- engine?.Globals.SetValString("StationState.OPID", 1, CurrentUserCode);
- engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
+
+ testExecutionWrapper?.SetStationGlobalValue("StationState.OPID", 1, CurrentUserCode);
+ testExecutionWrapper?.CommitToDisk(false);
}
catch (Exception ex)
{
@@ -443,7 +452,7 @@
Products = ProductManager.GetProducts<ObservableCollection<ProductData>>();
if (Products != null && Products.Count > 0)
{
- string lastModel = engine?.Globals.GetValString("StationState.ProductModel", 1);
+ string lastModel = testExecutionWrapper?.GetStationGlobalValue<string>("StationState.ProductModel", 1);
var tempProduct = Products[0];
if (!string.IsNullOrEmpty(lastModel))
{
@@ -487,25 +496,58 @@
/// </summary>
private void InitTsEngine()
{
- AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
+ if (ParamSetting.EngineType == "Tap")
+ {
+ testExecutionWrapper = new TapWrapper();
+ }
+ else
+ {
+ testExecutionWrapper = new TeststandWrapper();
+ }
-
- //AxApplicationMgr. += AxApplicationMgr_EndExecution;
- AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
-
- AxApplicationMgr.ExitApplication += this.AxApplicationMgr_ExitApplication;
- AxApplicationMgr.UIMessageEvent += this.AxApplicationMgr_UIMessageEvent;
- AxApplicationMgr.ExecutionClosed += this.AxApplicationMgr_ExecutionClosed;
-
- ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
- host.Child = AxApplicationMgr;
- ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+ testExecutionWrapper.EndExecutionEvent += TestExecutionWrapper_EndExecutionEvent;
+ testExecutionWrapper.UIMessageEvent += TestExecutionWrapper_UIMessageEvent;
+ if (testExecutionWrapper is TeststandWrapper tsw)
+ {
+ var AxApplicationMgr = tsw.AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).BeginInit();
+ host.Child = AxApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(AxApplicationMgr)).EndInit();
+ }
+ testExecutionWrapper.Init();
}
- private volatile bool canSwitchModel = false;
- private volatile Action switchAction = null;
+ private void TestExecutionWrapper_UIMessageEvent(object sender, UIMessageEvent e)
+ {
+ try
+ {
+ int eventCode = Convert.ToInt32(e.EventCode);
+ int index = Convert.ToInt16(e.NumberData);//SocketIndex
+ string strData = e.StrData;
- private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
+ try
+ {
+ log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
+ }
+ catch
+ {
+
+ }
+ if (eventCode == 10001)
+ {
+ testExecutionWrapper?.SetContext((SequenceContext)e.Data);
+ tsSockets[index].SequenceFileContext = (SequenceContext)e.Data;
+ return;
+ }
+ HandleUIMessage(eventCode, index, strData);
+ }
+ catch (Exception ex)
+ {
+ log.Warn("Ts Event Error.", ex);
+ }
+ }
+
+ private void TestExecutionWrapper_EndExecutionEvent(object sender, ExecutionEndEvent e)
{
log.Info("AxApplicationMgr_EndExecution");
if (ReleaseSequenceFile())
@@ -520,15 +562,8 @@
}
}
- /// <summary>
- /// 杩涚▼缁撴潫浜嬩欢
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void AxApplicationMgr_ExecutionClosed(object sender, _ApplicationMgrEvents_ExecutionClosedEvent e)
- {
- //ReleaseSequenceFile();
- }
+ private volatile bool canSwitchModel = false;
+ private volatile Action switchAction = null;
private void PluginControl_Loaded(object sender, RoutedEventArgs e)
{
@@ -547,17 +582,6 @@
{
log.Error("TsExecution Loaded Failed.", ex);
MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.UserControlLoadFailed")}: {ex.Message}");
- }
-
- try
- {
- if (Environment.Version.ToString() != this.AxApplicationMgr.GetEngine().DotNetCLRVersion)
- this.GCTimer.Enabled = true;
- }
- catch (Exception ex)
- {
- log.Error("TsExecution GCTimer Start Failed", ex);
- MsgBoxHelper.Error(this, $"{LangUtil.Get("Ts.LoadFailed")}: {ex.Message}");
}
Dispatcher.Invoke(() =>
@@ -653,26 +677,6 @@
}
/// <summary>
- /// 鍒濆鍖朤estStand寮曟搸
- /// </summary>
- private void InitTestStandEngine()
- {
- try
- {
- 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)
- {
- throw new Exception(LangUtil.Get("Ts.InitTestStandEngineFail"), ex);
- }
- }
-
- /// <summary>
/// 璇诲彇Count閰嶇疆鏂囦欢鐨刾ass鍜宖ail鏁�
/// </summary>
/// <param name="pass">鍚堟牸鏁�</param>
@@ -695,7 +699,7 @@
/// <param name="fail"></param>
private void ReadConfig()
{
- ParameterData value;
+ HMI.Core.Entity.ParameterData value;
bool flag = false;
@@ -955,7 +959,7 @@
foreach (var ts in tsSockets)
{
ts?.SequenceFileContext?.StationGlobals.SetValBoolean($"SystemSetting.{name}", 1, value);
- if (ts?.SequenceFileContext?.Sequence != null)
+ if (name == "EnableDebugMode" && ts?.SequenceFileContext?.Sequence != null)
{
ts.SequenceFileContext.Sequence.FailureAction =
value ? FailureActions.FailureAction_None : FailureActions.FailureAction_GotoCleanup;
@@ -1065,7 +1069,7 @@
if (!isLoadOK) return;
try
{
- engine?.Globals.SetValBoolean("StationState.StopTest", 1, false);
+ testExecutionWrapper?.SetStationGlobalValue("StationState.StopTest", 1, false);
}
catch (Exception ex)
{
@@ -1085,9 +1089,10 @@
return;
}
this.testSeqFile = path;
- this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
- this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
- this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+ testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath);
+ //this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
+ //this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+ //this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
IsTesting = true;
}
catch (Exception ex)
@@ -1104,11 +1109,12 @@
//MaskWindow mask = new MaskWindow();
try
{
- engine?.Globals.SetValString("StationState.ProductModel", 1, CurrentProductModel);
- engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
- this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
- this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
- this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
+ testExecutionWrapper?.SetStationGlobalValue("StationState.ProductModel", 1, CurrentProductModel);
+ testExecutionWrapper?.CommitToDisk(false);
+ testExecutionWrapper?.StartSequence(this.testSeqFile, this.tsModelPath);
+ //this.modeSeq = this.engine.GetSequenceFileEx(tsModelPath);
+ //this.testSeq = this.engine.GetSequenceFileEx(this.testSeqFile, 2, TypeConflictHandlerTypes.ConflictHandler_UseGlobalType);
+ //this.execution = this.engine.NewExecution(this.testSeq, "Test UUTs", this.modeSeq, false, 0, null, null, null);
IsTesting = true;
}
catch (Exception ex)
@@ -1143,21 +1149,14 @@
{
try
{
- //if (this.tsSockets.Count > 0)
- //{
- // for (int i = 0; i < tsSockets.Count; i++)
- // {
- // var context = this.tsSockets[i].SequenceFileContext;
- // context?.StationGlobals.SetValBoolean("StationState.StopTest", 1, true);
- // }
- //}
- engine.Globals.SetValBoolean("StationState.StopTest", 1, true);
- if (this.execution == null) return true;
+ testExecutionWrapper.SetStationGlobalValue("StationState.StopTest", 1, true);
+
//bool res = this.execution.WaitForEndEx(-1, true, null, null);
- bool res = this.execution?.WaitForEndEx(-1, true, Type.Missing, null) == true;
- Marshal.ReleaseComObject(this.execution);
- this.execution = null;
+ bool res = this.testExecutionWrapper.WaitForExit();
+ //if (this.execution != null)
+ // Marshal.ReleaseComObject(this.execution);
+ //this.execution = null;
return res;
}
catch (Exception ex)
@@ -1217,22 +1216,229 @@
// }).Info(LangUtil.Get("Ts.SequenceIsStarting"));
}
- /// <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();
- }
-
public void UpdatePositionStatus(int index, string status)
{
this.tsSockets[index].UpdateStatus(status);
+ OnStatusPublished(index, status);
this.UpdateTestCounter();
}
+
+ private void OnStatusPublished(int index, string status)
+ {
+ if (ParamSetting.CustomerCode != "SOUND")
+ {
+ return;
+ }
+ if (status == "Passed" || status == "Failed")
+ {
+ SaveSOUNDExcel(index, status);
+ }
+ }
+
+ private string ConvertStatus(string status)
+ {
+ if (string.Equals(status, "passed", StringComparison.OrdinalIgnoreCase))
+ {
+ return "Pass";
+ }
+ else
+ {
+ return "Fail";
+ }
+ }
+
+ #region 妗戝痉瀹氬埗
+ private ICell CreateCell(ISheet sheet, int r, int c, ICellStyle style)
+ {
+ var row = sheet.GetRow(r);
+ if (row == null)
+ {
+ row = sheet.CreateRow(r);
+ }
+ var cell = row.GetCell(c);
+ if (cell == null)
+ {
+ cell = row.CreateCell(c);
+ }
+ if (style != null)
+ {
+ cell.CellStyle = style;
+ }
+ return cell;
+ }
+
+ private string GetOutputFolder()
+ {
+ var value = ParameterManager.GetCommonParameterByName("SOUND_Output");
+ if (value != null)
+ {
+ return value.Value;
+ }
+ return ParamSetting.DataLogFolder;
+ }
+
+ private void SaveSOUNDExcel(int index, string status)
+ {
+ lock (this)
+ {
+ try
+ {
+ string outputFolder = GetOutputFolder();
+
+ var socket = this.tsSockets[index];
+ DateTime testTime = DateTime.Now;
+ string filePath = Path.Combine(outputFolder, $"{testTime.ToString("yy-MM-dd")}_{CurrentProductModel}.xls");
+ if (!File.Exists(filePath))
+ {
+ Dictionary<string, int> columnMap = new Dictionary<string, int>();
+ HSSFWorkbook workbook = new HSSFWorkbook();
+ ISheet sheet = workbook.CreateSheet("Sheet1");
+
+ ICellStyle border = workbook.CreateCellStyle();
+ border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+ border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+ border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+ border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+
+
+ ICellStyle red = workbook.CreateCellStyle();
+ red.CloneStyleFrom(border);
+ red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
+ red.FillPattern = FillPattern.SolidForeground;
+
+ ICellStyle green = workbook.CreateCellStyle();
+ green.CloneStyleFrom(border);
+ green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index;
+ green.FillPattern = FillPattern.SolidForeground;
+
+ CreateCell(sheet, 1, 0, border);
+ CreateCell(sheet, 1, 1, border);
+ CreateCell(sheet, 1, 2, border);
+ CreateCell(sheet, 1, 3, border);
+ CreateCell(sheet, 1, 4, border);
+
+ CreateCell(sheet, 2, 0, border);
+ CreateCell(sheet, 2, 1, border);
+ CreateCell(sheet, 2, 2, border);
+ CreateCell(sheet, 2, 3, border);
+ CreateCell(sheet, 2, 4, border).SetCellValue("涓婇檺");
+
+ CreateCell(sheet, 3, 0, border).SetCellValue("娴嬭瘯鏃堕棿");
+ CreateCell(sheet, 3, 1, border).SetCellValue("娴嬭瘯浜�");
+ CreateCell(sheet, 3, 2, border).SetCellValue("娴嬭瘯璁惧");
+ CreateCell(sheet, 3, 3, border).SetCellValue("鏉″舰鐮�");
+ CreateCell(sheet, 3, 4, border).SetCellValue("涓嬮檺");
+
+ int column = 5;
+ int row = 4;
+
+ CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*"));
+ CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name);
+ CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName);
+ CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode);
+ CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status));
+
+ foreach (var data in socket.Datasource)
+ {
+ int col = column;
+ if (columnMap.ContainsKey(data.Name))
+ {
+ col = columnMap[data.Name];
+ }
+ else
+ {
+ columnMap[data.Name] = column++;
+ }
+
+ CreateCell(sheet, 1, col, border).SetCellValue(data.Name);
+ CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp);
+ CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown);
+ CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value);
+ }
+ using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
+ {
+ workbook.Write(fs);
+ }
+ }
+ else
+ {
+ using (FileStream fs = File.OpenRead(filePath))
+ {
+ IWorkbook workbook = new HSSFWorkbook(fs);
+ ICellStyle border = workbook.CreateCellStyle();
+ border.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
+ border.BottomBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+ border.TopBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+ border.LeftBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+ border.RightBorderColor = NPOI.HSSF.Util.HSSFColor.Black.Index;
+
+
+ ICellStyle red = workbook.CreateCellStyle();
+ red.CloneStyleFrom(border);
+ red.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
+ red.FillPattern = FillPattern.SolidForeground;
+
+ ICellStyle green = workbook.CreateCellStyle();
+ green.CloneStyleFrom(border);
+ green.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.BrightGreen.Index;
+ green.FillPattern = FillPattern.SolidForeground;
+
+ ISheet sheet = workbook.GetSheet("Sheet1");
+ Dictionary<string, int> columnMap = new Dictionary<string, int>();
+ var titleRow = sheet.GetRow(1);
+ for (int i = 0; i < titleRow.LastCellNum; i++)
+ {
+ if (!string.IsNullOrEmpty(titleRow.GetCell(i).StringCellValue))
+ {
+ columnMap[titleRow.GetCell(i).StringCellValue] = i;
+ }
+ }
+ int row = sheet.LastRowNum + 1;
+ CreateCell(sheet, row, 0, border).SetCellValue(testTime.ToString("*HH:mm:ss*"));
+ CreateCell(sheet, row, 1, border).SetCellValue(UserInfo.User.Name);
+ CreateCell(sheet, row, 2, border).SetCellValue(ParamSetting.StationName);
+ CreateCell(sheet, row, 3, border).SetCellValue(socket.Barcode);
+ CreateCell(sheet, row, 4, status == "Passed" ? green : red).SetCellValue(ConvertStatus(status));
+
+ foreach (var data in socket.Datasource)
+ {
+ int col = titleRow.LastCellNum;
+ if (columnMap.ContainsKey(data.Name))
+ {
+ col = columnMap[data.Name];
+ }
+ else
+ {
+ columnMap[data.Name] = col;
+ }
+
+ CreateCell(sheet, 1, col, border).SetCellValue(data.Name);
+ CreateCell(sheet, 2, col, border).SetCellValue(data.LimitUp);
+ CreateCell(sheet, 3, col, border).SetCellValue(data.LimitDown);
+ CreateCell(sheet, row, col, data.Result == "Failed" ? red : border).SetCellValue(data.Value);
+ }
+ using (FileStream nfs = new FileStream(filePath, FileMode.OpenOrCreate))
+ {
+ workbook.Write(nfs);
+ }
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+ log.Error("SOUND Export Excel Data Error.", ex);
+ }
+ }
+ }
+ #endregion
public void UpdatePositionProcessValue(int index, int value)
{
@@ -1296,9 +1502,11 @@
sqls.Add($@"INSERT INTO serialData (sn,model,station,step,position,limitDown,limitUp,unit,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
('{snr}','{model}','','{data.Name}','{index}','{data.LimitDown}','{data.LimitUp}','{data.Unit}','{data.Value}','{data.Result}','{socket.Status}','{data.ConsumeTime}','{socket.ElapseTime}','{time}')");
}
- sqls.Add($@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES
-('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')");
sqliteHelper.ExecuteBatchSql(sqls);
+
+ var ssql = $@"INSERT INTO testResult (sn,model,station,result,time,position,status) VALUES
+('{snr}','{model}','','{socket.Status}','{time}','{index}','{status}')";
+ sqliteHelper.ExecuteSql(ssql);
}
private void HandleUIMessage(int eventCode, int index, string strData)
@@ -1385,6 +1593,26 @@
this.tsSockets[index].SetTestProcess(ProcessVal);
break;
case 10031://瀵煎嚭CSV
+
+ if (ParamSetting.CustomerCode == "SOUND")
+ {
+ string[] datas = strData.Split(';');
+ this.tsSockets[index].WriteToExcel(datas[0]);
+ if (datas.Length >= 2)
+ {
+ SavePositionDB(index, datas[1]);
+ }
+ else
+ {
+ Dispatcher.Invoke(() =>
+ {
+ var sss = this.tsSockets[index].Status;
+ SavePositionDB(index, sss);
+ });
+ }
+ return;
+ }
+
if (string.IsNullOrEmpty(strData))
{
SaveTemplateCSV(index);
@@ -1400,8 +1628,11 @@
}
else
{
- var sss = this.tsSockets[index].Status;
- SavePositionDB(index, sss);
+ Dispatcher.Invoke(() =>
+ {
+ var sss = this.tsSockets[index].Status;
+ SavePositionDB(index, sss);
+ });
}
}
catch (Exception ex)
@@ -1435,6 +1666,22 @@
points[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
}
this.tsSockets[index].DrawScreenPoints(int.Parse(arr_10035[0]), points);
+ break;
+ case 100350:
+ string[] arr_100350 = strData.Split(';');
+
+ int[][] points_0 = new int[arr_100350.Length - 1][];
+
+ for (int i = 1; i < arr_100350.Length; i++)
+ {
+ if (string.IsNullOrEmpty(arr_100350[i]))
+ {
+ continue;
+ }
+ string[] strs = arr_100350[i].Split(',');
+ points_0[i - 1] = new int[2] { int.Parse(strs[0]), int.Parse(strs[1]) };
+ }
+ this.tsSockets[index].DrawNewScreenPoints(int.Parse(arr_100350[0]), points_0);
break;
case 10036:
this.tsSockets[index].ClearScreenPoint(int.Parse(strData));
@@ -1481,8 +1728,8 @@
{
log?.Info("寮�濮嬭嚜鍔ㄦ崲鍨�");
SelectedProduct = target;
- engine?.Globals.SetValString($"CacheSNR[{index}]", 1, snr);
- engine?.CommitGlobalsToDisk(false);
+ testExecutionWrapper?.SetStationGlobalValue($"CacheSNR[{index}]", 1, snr);
+ testExecutionWrapper?.CommitToDisk(false);
StartClick();
}
catch (Exception ex)
@@ -1498,43 +1745,7 @@
private void ShowAlarm(AlarmText alarm)
{
AlarmShowHelper.ShowAlarm(alarm);
- mSMQHelper.Send("Alarm", $"ATE娴嬭瘯 {alarm.AlarmInfo}");
- }
-
- /// <summary>
- /// TestStand鐢ㄦ埛浜や簰浜嬩欢
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
- {
- try
- {
- int eventCode = Convert.ToInt32(e.uiMsg.Event);
- int index = Convert.ToInt16(e.uiMsg.NumericData);//SocketIndex
- string strData = e.uiMsg.StringData;
-
- try
- {
- log.Debug($"Event: {eventCode}, NumericData: {index}, StringData: {strData}");
- }
- catch
- {
-
- }
- if (eventCode == 10001)
- {
- sequenceContext = (SequenceContext)e.uiMsg.ActiveXData;
-
- tsSockets[index].SequenceFileContext = (SequenceContext)e.uiMsg.ActiveXData;
- return;
- }
- HandleUIMessage(eventCode, index, strData);
- }
- catch (Exception ex)
- {
- log.Warn("Ts Event Error.", ex);
- }
+ mSMQHelper.Send("Alarm", "PC", $"ATE娴嬭瘯 {alarm.AlarmInfo}", 2);
}
private void UpdateTestCounter()
@@ -1557,7 +1768,7 @@
return;
}
string name = product.Name;
- List<ParameterData> parameters = ProductManager.GetParametersByProductName(name);
+ List<HMI.Core.Entity.ParameterData> parameters = ProductManager.GetParametersByProductName(name);
testSeqFile = parameters.FirstOrDefault(p => p.Name == "TestSequence")?.Value?.ToString();
if (AutoExecuteSeq)
{
@@ -1607,32 +1818,13 @@
{
lock (this)
{
- if (this.testSeq == null)
- {
- return true;
- }
//execution.Abort();
int count = 10;
while (count > 0)
{
try
{
- if (this.testSeq == null)
- return true;
-
- if (this.engine?.ReleaseSequenceFileEx(this.testSeq, 4) == true)
- {
- Marshal.ReleaseComObject(this.testSeq);
- this.testSeq = null;
- // GC.Collect();
- }
- if (this.engine?.ReleaseSequenceFileEx(this.modeSeq, 4) == true)
- {
- Marshal.ReleaseComObject(this.modeSeq);
- this.modeSeq = null;
- }
- this.engine?.UnloadAllModules();
- return this.testSeq == null && this.modeSeq == null;
+ return testExecutionWrapper.ReleaseSeqFile();
}
catch (Exception ex)
{
diff --git a/Plugin.TsSupport/ITestExecutionWrapper.cs b/Plugin.TsSupport/ITestExecutionWrapper.cs
index 2a80a38..ccd000b 100644
--- a/Plugin.TsSupport/ITestExecutionWrapper.cs
+++ b/Plugin.TsSupport/ITestExecutionWrapper.cs
@@ -1,5 +1,4 @@
-锘縰sing NationalInstruments.TestStand.Interop.API;
-using System;
+锘縰sing System;
namespace Plugin.TsSupport
{
diff --git a/Plugin.TsSupport/Plugin.TsSupport.csproj b/Plugin.TsSupport/Plugin.TsSupport.csproj
index ec9f306..4b296a0 100644
--- a/Plugin.TsSupport/Plugin.TsSupport.csproj
+++ b/Plugin.TsSupport/Plugin.TsSupport.csproj
@@ -72,6 +72,11 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath>
</Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.dll</HintPath>
+ </Reference>
<Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls, Version=20.0.0.49158, Culture=neutral, PublicKeyToken=ad9244eb3b825cd8, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
@@ -88,6 +93,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ITestExecutionWrapper.cs" />
+ <Compile Include="TapWrapper.cs" />
<Compile Include="TestAppManager.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TeststandWrapper.cs" />
diff --git a/Plugin.TsSupport/TapWrapper.cs b/Plugin.TsSupport/TapWrapper.cs
new file mode 100644
index 0000000..23ef29a
--- /dev/null
+++ b/Plugin.TsSupport/TapWrapper.cs
@@ -0,0 +1,238 @@
+锘縰sing System;
+//using AddInPlugin;
+//using AddInPlugin.Util;
+//using Microsoft.Win32;
+//using OpenTap;
+//using OpenTap.Addin;
+//using OpenTap.Addin.Util;
+//using System.ComponentModel;
+//using System.IO;
+
+namespace Plugin.TsSupport
+{
+
+ public class TapWrapper : ITestExecutionWrapper
+ {
+ public event EventHandler<UIMessageEvent> UIMessageEvent;
+ public event EventHandler<ExecutionEndEvent> EndExecutionEvent;
+
+ public void CommitToDisk(bool option)
+ {
+
+ }
+
+ public T GetFileGlobalValue<T>(string key, int option)
+ {
+ return default(T);
+ }
+
+ public T GetStationGlobalValue<T>(string key, int option)
+ {
+ return default(T);
+ }
+
+ public object Init()
+ {
+ return null;
+ }
+
+ public bool ReleaseSeqFile()
+ {
+ return true;
+ }
+
+ public void SetContext(object context)
+ {
+
+ }
+
+ public void SetFileGlobalValue<T>(string key, int option, T value)
+ {
+
+ }
+
+ public void SetStationGlobalValue<T>(string key, int option, T value, bool inContext = false)
+ {
+
+ }
+
+ public object StartSequence(string filePath, string modelPath)
+ {
+ return null;
+ }
+
+ public bool WaitForExit()
+ {
+ return true;
+ }
+ }
+
+ //public class Net47Getter : IRegGetter
+ //{
+ // public string GetAppPath(string keyPath)
+ // {
+ // using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyPath))
+ // {
+ // if (key == null)
+ // {
+ // throw new Exception("娉ㄥ唽琛ㄤ笉瀛樺湪锛岃鍏堣繍琛屼竴娆$紪杈戝櫒");
+ // }
+
+ // string value = key.GetValue("Location")?.ToString();
+ // if (string.IsNullOrEmpty(value))
+ // {
+ // throw new Exception("娉ㄥ唽琛ㄤ笉瀛樺湪锛岃鍏堣繍琛屼竴娆$紪杈戝櫒");
+ // }
+ // return value;
+ // }
+ // }
+ //}
+
+ //public class TapWrapper : ITestExecutionWrapper, IResultListener
+ //{
+ // TapThread testPlanThread;
+ // TestPlan Plan;
+ // TestPlanRun PlanRun;
+
+ // public event PropertyChangedEventHandler PropertyChanged;
+
+ // public event EventHandler<UIMessageEvent> UIMessageEvent;
+ // public event EventHandler<ExecutionEndEvent> EndExecutionEvent;
+
+ // public string Name { get; set; }
+
+ // public bool IsConnected => true;
+
+ // public object Init()
+ // {
+ // RegUtil.Register(new Net47Getter());
+ // StationGlobalsManager.Register(new DefaultStationGlobalsManager());
+ // VariableResolverFactory.Register(new DefaultVariableResolverFactory());
+ // ResultSettings.Current.Add(this);
+ // return null;
+ // }
+
+ // private void PostUIMsgHandler_OnPostUIMsg(object sender, PostUIMsg e)
+ // {
+ // UIMessageEvent?.Invoke(this, new UIMessageEvent()
+ // {
+ // Origin = e,
+ // EventCode = e.EventCode,
+ // BoolData = e.BoolData,
+ // NumberData = e.NumberData,
+ // StrData = e.StringData
+ // });
+ // }
+
+ // public object StartSequence(string filePath, string modelPath)
+ // {
+ // Plan = TestPlan.Load(filePath);
+ // testPlanThread = TapThread.Start(() =>
+ // {
+ // var res = ResultSettings.Current;
+ // Plan.Execute(ResultSettings.Current, null);
+ // });
+ // return Plan;
+ // }
+
+
+ // public T GetFileGlobalValue<T>(string key, int option)
+ // {
+ // return PlanRun.Resolve<T>(null, $"FileGlobals.{key}");
+ // }
+
+ // public T GetStationGlobalValue<T>(string key, int option)
+ // {
+ // if (PlanRun == null)
+ // {
+ // return StationGlobalsManager.GetValue<T>(key);
+ // }
+ // return PlanRun.Resolve<T>(null, $"StationGlobals.{key}");
+ // }
+
+ // public T GetValue<T>(string key, int option)
+ // {
+ // return default(T);
+ // }
+
+ // public void SetValue<T>(string key, T value, int option)
+ // {
+
+ // }
+
+ // public void SetFileGlobalValue<T>(string key, int option, T value)
+ // {
+ // PlanRun.Update(null, $"FileGlobals.{key}", value);
+ // }
+
+ // public void SetStationGlobalValue<T>(string key, int option, T value, bool inContext = false)
+ // {
+ // if (PlanRun == null)
+ // {
+ // StationGlobalsManager.SetValue(key, value);
+ // }
+ // else
+ // {
+ // PlanRun.Update(null, $"StationGlobals.{key}", value);
+ // }
+ // }
+
+ // public void CommitToDisk(bool option)
+ // {
+ // StationGlobalsManager.WriteToLocal(null);
+ // }
+
+ // public void OnTestPlanRunStart(TestPlanRun planRun)
+ // {
+ // PlanRun = planRun;
+ // }
+
+ // public void OnTestPlanRunCompleted(TestPlanRun planRun, Stream logStream)
+ // {
+
+
+ // }
+
+ // public void OnTestStepRunStart(TestStepRun stepRun)
+ // {
+
+ // }
+
+ // public void OnTestStepRunCompleted(TestStepRun stepRun)
+ // {
+
+ // }
+
+ // public void OnResultPublished(Guid stepRunID, ResultTable result)
+ // {
+
+ // }
+
+ // public void Open()
+ // {
+ // PostUIMsgHandler.OnPostUIMsg += PostUIMsgHandler_OnPostUIMsg;
+ // }
+
+ // public void Close()
+ // {
+ // PostUIMsgHandler.OnPostUIMsg -= PostUIMsgHandler_OnPostUIMsg;
+ // EndExecutionEvent?.Invoke(this, new ExecutionEndEvent());
+ // PlanRun = null;
+ // }
+
+ // public bool WaitForExit()
+ // {
+ // return true;
+ // }
+
+ // public bool ReleaseSeqFile()
+ // {
+ // return true;
+ // }
+
+ // public void SetContext(object context)
+ // {
+
+ // }
+ //}
+}
diff --git a/Plugin.TsSupport/TeststandWrapper.cs b/Plugin.TsSupport/TeststandWrapper.cs
index b3c7f07..ea15087 100644
--- a/Plugin.TsSupport/TeststandWrapper.cs
+++ b/Plugin.TsSupport/TeststandWrapper.cs
@@ -1,7 +1,7 @@
锘縰sing NationalInstruments.TestStand.Interop.API;
using NationalInstruments.TestStand.Interop.UI.Ax;
using System;
-using System.Diagnostics;
+using System.Runtime.InteropServices;
namespace Plugin.TsSupport
{
@@ -213,11 +213,19 @@
public bool ReleaseSeqFile()
{
- if (testSeq != null)
+ if (this.testSeq != null && this.engine?.ReleaseSequenceFileEx(this.testSeq, 4) == true)
{
- return engine?.ReleaseSequenceFileEx(testSeq, 4) == true;
+ Marshal.ReleaseComObject(this.testSeq);
+ this.testSeq = null;
}
- return true;
+
+ if (this.modeSeq != null && this.engine?.ReleaseSequenceFileEx(this.modeSeq, 4) == true)
+ {
+ Marshal.ReleaseComObject(this.modeSeq);
+ this.modeSeq = null;
+ }
+ this.engine?.UnloadAllModules();
+ return this.testSeq == null && this.modeSeq == null;
}
public void SetContext(object context)
diff --git a/Plugin.TsSupport/TsExecutionWrapper.cs b/Plugin.TsSupport/TsExecutionWrapper.cs
index 837bc75..1298dd5 100644
--- a/Plugin.TsSupport/TsExecutionWrapper.cs
+++ b/Plugin.TsSupport/TsExecutionWrapper.cs
@@ -40,23 +40,37 @@
/// </summary>
public AxApplicationMgr AxApplicationMgr { get; private set; }
- public event _ApplicationMgrEvents_EndExecutionEventHandler OnEndExecution;
-
public event EventHandler<UIMessageEvent> UIMessageEvent;
public event EventHandler<ExecutionEndEvent> EndExecutionEvent;
public TsExecutionWrapper()
{
AxApplicationMgr = TestAppManager.GetAxApplicationMgr();
- //AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
+ AxApplicationMgr.EndExecution += AxApplicationMgr_EndExecution;
//AxApplicationMgr.ExitApplication += new EventHandler(this.AxApplicationMgr_ExitApplication);
- //AxApplicationMgr.UIMessageEvent +=
- // new _ApplicationMgrEvents_UIMessageEventEventHandler(this.AxApplicationMgr_UIMessageEvent);
+ AxApplicationMgr.UIMessageEvent += AxApplicationMgr_UIMessageEvent;
//AxApplicationMgr.ExecutionClosed +=
// new _ApplicationMgrEvents_ExecutionClosedEventHandler(this.AxApplicationMgr_ExecutionClosed);
}
#endregion
+
+ private void AxApplicationMgr_EndExecution(object sender, _ApplicationMgrEvents_EndExecutionEvent e)
+ {
+ EndExecutionEvent?.Invoke(this, new ExecutionEndEvent() { Origin = e });
+ }
+
+ private void AxApplicationMgr_UIMessageEvent(object sender, _ApplicationMgrEvents_UIMessageEventEvent e)
+ {
+ UIMessageEvent?.Invoke(this, new UIMessageEvent()
+ {
+ Origin = e,
+ EventCode = Convert.ToInt32(e.uiMsg.Event),
+ NumberData = e.uiMsg.NumericData,
+ Data = e.uiMsg.ActiveXData,
+ StrData = e.uiMsg.StringData
+ });
+ }
public object Init()
{
@@ -208,7 +222,7 @@
public void SetContext(object context)
{
-
+ this.context = (SequenceContext)context;
}
}
}
diff --git a/S7Driver/PLCS7Driver.cs b/S7Driver/PLCS7Driver.cs
index 6b666e3..aa3d531 100644
--- a/S7Driver/PLCS7Driver.cs
+++ b/S7Driver/PLCS7Driver.cs
@@ -61,60 +61,150 @@
client?.Dispose();
}
- public bool Simens_S7_ReadBool(int DB, int StartAdd, int Pos)
+ public bool Simens_S7_ReadBool(int DB, int StartAdd, int Pos, out bool value, out string msg)
{
- var or = client.ReadBool($"DB{DB}.DBX{StartAdd}.{Pos}");
- return or.Content;
+ value = false;
+ msg = null;
+ try
+ {
+ var or = client.ReadBool($"DB{DB}.DBX{StartAdd}.{Pos}");
+ if (!or.IsSuccess)
+ {
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
+ }
+ value = or.Content;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
}
- public void Simens_S7_WriteBool(int DB, int StartAdd, int Pos, bool Val)
+ public bool Simens_S7_WriteBool(int DB, int StartAdd, int Pos, bool Val, out string msg)
{
- var or = client.Write($"DB{DB}.DBX{StartAdd}.{Pos}", Val);
- return;
+ msg = null;
+ try
+ {
+ var or = client.Write($"DB{DB}.DBX{StartAdd}.{Pos}", Val);
+ if (!or.IsSuccess)
+ {
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
}
- public int Simens_S7_ReadInt(int DB, int StartAdd, int Length)
- {
- var or = client.ReadInt16($"DB{DB}.DBW{StartAdd}");
- return or.Content;
- }
-
- public void Simens_S7_WriteInt(int DB, int StartAdd, short Val)
- {
- client.Write($"DB{DB}.DBW{StartAdd}", Val);
- }
-
- public float Simens_S7_ReadReal(int DB, int StartAdd, int Length)
- {
- var or = client.ReadFloat($"DB{DB}.DBW{StartAdd}");
- return or.Content;
- }
-
- public void Simens_S7_WriteReal(int DB, int StartAdd, float Val)
- {
- client.Write($"DB{DB}.DBW{StartAdd}", Val);
- }
-
- public bool ReadShort(string address, out short value, out string errMsg)
+ public bool Simens_S7_ReadInt(int DB, int StartAdd, out int value, out string msg)
{
value = 0;
- errMsg = null;
+ msg = null;
+ try
+ {
+ var or = client.ReadInt16($"DB{DB}.DBW{StartAdd}");
+ if (!or.IsSuccess)
+ {
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
+ }
+ value = or.Content;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
+ }
+
+ public bool Simens_S7_WriteInt(int DB, int StartAdd, short Val, out string msg)
+ {
+ msg = null;
+ try
+ {
+ var or = client.Write($"DB{DB}.DBW{StartAdd}", Val);
+ if (!or.IsSuccess)
+ {
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
+ }
+
+ public bool Simens_S7_ReadReal(int DB, int StartAdd, out float value, out string msg)
+ {
+ value = 0;
+ msg = null;
+ try
+ {
+ var or = client.ReadFloat($"DB{DB}.DBW{StartAdd}");
+ if (!or.IsSuccess)
+ {
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
+ }
+ value = or.Content;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
+ }
+
+ public bool Simens_S7_WriteReal(int DB, int StartAdd, float Val, out string msg)
+ {
+ msg = null;
+ try
+ {
+ var or = client.Write($"DB{DB}.DBW{StartAdd}", Val);
+ if (!or.IsSuccess)
+ {
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ msg = ex.Message;
+ return false;
+ }
+ }
+
+ public bool ReadShort(string address, out short value, out string msg)
+ {
+ value = 0;
+ msg = null;
try
{
var or = client.ReadInt16(address);
- if (or.IsSuccess)
+ if (!or.IsSuccess)
{
- value = or.Content;
+ msg = $"{or.ErrorCode} {or.Message}";
+ return false;
}
- else
- {
- errMsg = or.Message;
- }
- return or.IsSuccess;
+ value = or.Content;
+ return true;
}
catch (Exception e)
{
- errMsg = e.Message;
+ msg = e.Message;
return false;
}
}
diff --git a/S7Driver/Properties/AssemblyInfo.cs b/S7Driver/Properties/AssemblyInfo.cs
index aa2b394..4959d2f 100644
--- a/S7Driver/Properties/AssemblyInfo.cs
+++ b/S7Driver/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@
// 鐢熸垚鍙�
// 淇鍙�
//
-[assembly: AssemblyVersion("1.0.0.4")]
-[assembly: AssemblyFileVersion("1.0.0.4")]
+[assembly: AssemblyVersion("1.0.0.5")]
+[assembly: AssemblyFileVersion("1.0.0.5")]
diff --git a/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs b/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs
index c6bcb1b..34c2ce9 100644
--- a/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/AlarmUtil.cs
@@ -4,19 +4,15 @@
{
public class AlarmUtil
{
- private static string ConcatAlarm(string source, string content)
- {
- return $"{source},{content}";
- }
- public static bool CreateAlarm(string source, string content, out string msg)
+ public static bool CreateAlarm(string source, string content, int level, out string msg)
{
msg = string.Empty;
try
{
using (var helper = new MSMQHelper("HMI_Alarm"))
{
- helper.Send("Alarm", ConcatAlarm(source, content));
+ helper.Send("Alarm", source, content, level);
return true;
}
}
@@ -34,16 +30,16 @@
/// <param name="contents">鎶ヨ鍐呭锛屽悓涓�鏉ユ簮鐨勬姤璀﹀彲浠ュ鏉″悓鏃跺垱寤�</param>
/// <param name="msg">鍒涘缓澶辫触鏃朵负寮傚父淇℃伅</param>
/// <returns>鍒涘缓澶辫触鏃朵负寮傚父淇℃伅</returns>
- public static bool CreateAlarm(string source, string[] contents, out string msg)
+ public static bool CreateAlarm(string source, string[] contents, int[] levels, out string msg)
{
msg = string.Empty;
try
{
using (var helper = new MSMQHelper("HMI_Alarm"))
{
- foreach (string content in contents)
+ for (int i = 0; i < contents.Length; i++)
{
- helper.Send("Alarm", ConcatAlarm(source, content));
+ helper.Send("Alarm", source, contents[i], levels[i]);
}
return true;
}
@@ -54,10 +50,13 @@
return false;
}
}
-
- public static bool CreateAlarm(string content, out string msg)
- {
- return CreateAlarm("PC", content, out msg);
- }
+ //private static string ConcatAlarm(string source, string content)
+ //{
+ // return $"{source},{content}";
+ //}
+ //public static bool CreateAlarm(string content, int level, out string msg)
+ //{
+ // return CreateAlarm("PC", content, level, out msg);
+ //}
}
}
diff --git a/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs b/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs
index 3232d7e..06d9f04 100644
--- a/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs
+++ b/SimpleUtil/HMI.Simple.Util/MSMQHelper.cs
@@ -3,6 +3,15 @@
namespace HMI.Simple.Util
{
+
+ public class MQAlarm
+ {
+ public string Source { get; set; }
+ public string Content { get; set; }
+ public int Level { get; set; }
+ }
+
+
public class MSMQHelper : IDisposable
{
/// <summary>
@@ -40,7 +49,7 @@
// 濡傛灉娑堟伅闃熷垪涓嶅瓨鍦紝鍒欏垱寤烘秷鎭鍨�
this.msgQueue = MessageQueue.Create(this.msmqPath);
}
- this.msgQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
+ this.msgQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(MQAlarm) });
}
catch (Exception ex)
{
@@ -53,11 +62,11 @@
/// </summary>
/// <param name="MessageID">娑堟伅ID</param>
/// <param name="MsgString">瑕佸彂閫佺殑瀛楃涓�</param>
- public void Send(string MessageID, string MsgString)
+ public void Send(string MessageID, string source, string MsgString, int level)
{
try
{
- this.msgQueue.Send(MsgString, MessageID);
+ this.msgQueue.Send(new MQAlarm { Source = source, Content = MsgString, Level = level }, MessageID);
}
catch (Exception ex)
{
@@ -71,12 +80,12 @@
/// <param name="TimeOut">瓒呮椂鏃堕棿(ms)</param>
/// <param name="MessageID">娑堟伅ID</param>
/// <param name="MsgString">娑堟伅鍐呭</param>
- public void Receive(long TimeOut, out string MessageID, out string MsgString)
+ public void Receive(long TimeOut, out string MessageID, out MQAlarm alarm)
{
try
{
MessageID = string.Empty;
- MsgString = string.Empty;
+ alarm = null;
TimeSpan Time = new TimeSpan(TimeOut);
Message MsgReceived = null;
try
@@ -91,7 +100,7 @@
if (MsgReceived != null)
{
MessageID = MsgReceived.Label;
- MsgString = MsgReceived.Body.ToString();
+ alarm = (MQAlarm)MsgReceived.Body;
}
}
catch (Exception ex)
diff --git a/SimpleUtil/HMI.TapApi/HMI.TapApi.csproj b/SimpleUtil/HMI.TapApi/HMI.TapApi.csproj
new file mode 100644
index 0000000..e2ab78f
--- /dev/null
+++ b/SimpleUtil/HMI.TapApi/HMI.TapApi.csproj
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>HMI.TapApi</RootNamespace>
+ <AssemblyName>HMI.TapApi</AssemblyName>
+ <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ProductUtil.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\Project\OpenTapEditor\OpenTap\BasicSteps\Tap.Plugins.BasicSteps.csproj">
+ <Project>{4BCFADC0-54F9-7032-B918-E4DD407CAA76}</Project>
+ <Name>Tap.Plugins.BasicSteps</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\Project\OpenTapEditor\OpenTap\Engine\Tap.Engine.csproj">
+ <Project>{efbd516d-3dc9-9d75-f082-48fbc76715f7}</Project>
+ <Name>Tap.Engine</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\Project\OpenTapEditor\Plugin\AddInPlugin\AddInPlugin.csproj">
+ <Project>{0d150ca1-d6ea-3362-7330-028939e66e1c}</Project>
+ <Name>AddInPlugin</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\HMI.Core\HMI.Core.csproj">
+ <Project>{3e3bf44a-0b69-45c5-9512-528cb48a7106}</Project>
+ <Name>HMI.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\HMI.Simple.Util\HMI.Simple.Util.csproj">
+ <Project>{cf5bebe9-2803-49c3-b773-73d082e0984a}</Project>
+ <Name>HMI.Simple.Util</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\HMI.Util.Base\HMI.Util.Base.csproj">
+ <Project>{d59e25d1-9b27-46a1-8438-92661dd23fae}</Project>
+ <Name>HMI.Util.Base</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
diff --git a/SimpleUtil/HMI.TapApi/ProductUtil.cs b/SimpleUtil/HMI.TapApi/ProductUtil.cs
new file mode 100644
index 0000000..54a0877
--- /dev/null
+++ b/SimpleUtil/HMI.TapApi/ProductUtil.cs
@@ -0,0 +1,164 @@
+锘縰sing HMI.Simple.Util;
+using OpenTap;
+using OpenTap.Addin.Util;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace HMI.TapApi
+{
+ public class ProductUtil
+ {
+ private static void WriteParameterData(object instance, ParameterData data)
+ {
+ TestPlanRun context = (TestPlanRun)instance;
+ string name = $"DUTSetting.{data.Name}";
+ if (data.IsArray)
+ {
+ Type type;
+ if (data.Type == "Bool")
+ {
+ type = typeof(bool);
+ }
+ else if (data.Type == "Int")
+ {
+ type = typeof(int);
+ }
+ else if (data.Type == "Double")
+ {
+ type = typeof(double);
+ }
+ else
+ {
+ type = typeof(string);
+ }
+ string[] arr = data.Value?.Split(',') ?? new string[0];
+ if (arr.Length > 0)
+ {
+ //RuntimeVariable rv;
+ //if (data.Type == "Int")
+ //{
+ // int[] values = arr.Select(a => int.Parse(a)).ToArray();
+ // rv = new RuntimeVariable(context, name, values);
+ //}
+ //if (data.Type == "Double")
+ //{
+ // double[] values = arr.Select(a => double.Parse(a)).ToArray();
+ // rv = new RuntimeVariable(context, name, values);
+ //}
+ //if (data.Type == "Bool")
+ //{
+ // bool[] values = arr.Select(a => bool.Parse(a)).ToArray();
+ // rv = new RuntimeVariable(context, name, values);
+ //}
+ //else
+ //{
+ // rv = new RuntimeVariable(context, name, arr);
+ //}
+
+ if (data.Type == "Int")
+ {
+ int[] values = arr.Select(a => int.Parse(a)).ToArray();
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", values);
+ }
+ if (data.Type == "Double")
+ {
+ double[] values = arr.Select(a => double.Parse(a)).ToArray();
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", values);
+ }
+ if (data.Type == "Bool")
+ {
+ bool[] values = arr.Select(a => bool.Parse(a)).ToArray();
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", values);
+ }
+ else
+ {
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", arr);
+ }
+ }
+ }
+ else
+ {
+ if (data.Type == "Bool")
+ {
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", bool.Parse(data.Value));
+ }
+ else if (data.Type == "Int")
+ {
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", int.Parse(data.Value));
+ }
+ else if (data.Type == "Double")
+ {
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", double.Parse(data.Value));
+ }
+ else
+ {
+ context.Update(null, $"{ConstNames.FileGlobalsName}.{name}", data.Value);
+ }
+ }
+ }
+
+ private static string GetDataFilePath()
+ {
+ string path = ParameterUtil.GetCommonParameterValue("ShareConfig", out _);
+ if (string.IsNullOrEmpty(path))
+ {
+ path = Path.Combine(HMI.Simple.Util.RegUtil.GetLocaltion(), "Config");
+ }
+ return path;
+ }
+
+ /// <summary>
+ /// 鏍规嵁浜у搧鍨嬪彿鍐欓厤缃�
+ /// </summary>
+ /// <param name="model">浜у搧鍨嬪彿</param>
+ /// <param name="instance">TestStand涓婁笅鏂�</param>
+ /// <param name="errMsg">寮傚父淇℃伅</param>
+ /// <returns>鏄惁鎴愬姛</returns>
+ public static bool WriteConfigToContextByModel(string model, object instance, out string errMsg)
+ {
+ errMsg = string.Empty;
+ try
+ {
+ string path = Path.Combine(GetDataFilePath(), "Product", "Parameter", $"Parameter_{model}.data");
+ return WriteConfigToContextByPath(path, instance, out errMsg);
+ }
+ catch (Exception ex)
+ {
+ errMsg = ex.Message;
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁璺緞鍐欓厤缃�
+ /// </summary>
+ /// <param name="path">缁濆璺緞</param>
+ /// <param name="instance">TestStand涓婁笅鏂�</param>
+ /// <param name="errMsg">寮傚父淇℃伅</param>
+ /// <returns>鏄惁鎴愬姛</returns>
+ public static bool WriteConfigToContextByPath(string path, object instance, out string errMsg)
+ {
+ errMsg = string.Empty;
+ try
+ {
+ if (!File.Exists(path))
+ {
+ throw new Exception($"鏈壘鍒拌閰嶇疆[{path}]锛岃妫�鏌�");
+ }
+ List<ParameterData> datas = XmlHelper.DeserializeFromXml<List<ParameterData>>(path);
+ foreach (var data in datas)
+ {
+ WriteParameterData(instance, data);
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ errMsg = ex.Message;
+ return false;
+ }
+ }
+ }
+}
diff --git a/SimpleUtil/HMI.TapApi/Properties/AssemblyInfo.cs b/SimpleUtil/HMI.TapApi/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5ae09f1
--- /dev/null
+++ b/SimpleUtil/HMI.TapApi/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+锘縰sing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 鏈夊叧绋嬪簭闆嗙殑涓�鑸俊鎭敱浠ヤ笅
+// 鎺у埗銆傛洿鏀硅繖浜涚壒鎬у�煎彲淇敼
+// 涓庣▼搴忛泦鍏宠仈鐨勪俊鎭��
+[assembly: AssemblyTitle("HMI.TapApi")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HMI.TapApi")]
+[assembly: AssemblyCopyright("Copyright 漏 2026")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 灏� ComVisible 璁剧疆涓� false 浼氫娇姝ょ▼搴忛泦涓殑绫诲瀷
+//瀵� COM 缁勪欢涓嶅彲瑙併�傚鏋滈渶瑕佷粠 COM 璁块棶姝ょ▼搴忛泦涓殑绫诲瀷
+//璇峰皢姝ょ被鍨嬬殑 ComVisible 鐗规�ц缃负 true銆�
+[assembly: ComVisible(false)]
+
+// 濡傛灉姝ら」鐩悜 COM 鍏紑锛屽垯涓嬪垪 GUID 鐢ㄤ簬绫诲瀷搴撶殑 ID
+[assembly: Guid("eefdf6fe-41ad-4eb0-9ce6-87a07b88f9d7")]
+
+// 绋嬪簭闆嗙殑鐗堟湰淇℃伅鐢变笅鍒楀洓涓�肩粍鎴�:
+//
+// 涓荤増鏈�
+// 娆$増鏈�
+// 鐢熸垚鍙�
+// 淇鍙�
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/StationGlobalsReader/App.xaml b/StationGlobalsReader/App.xaml
new file mode 100644
index 0000000..84d066c
--- /dev/null
+++ b/StationGlobalsReader/App.xaml
@@ -0,0 +1,9 @@
+锘�<Application x:Class="StationGlobalsReader.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:local="clr-namespace:StationGlobalsReader"
+ StartupUri="MainWindow.xaml">
+ <Application.Resources>
+
+ </Application.Resources>
+</Application>
diff --git a/StationGlobalsReader/App.xaml.cs b/StationGlobalsReader/App.xaml.cs
new file mode 100644
index 0000000..2fe9278
--- /dev/null
+++ b/StationGlobalsReader/App.xaml.cs
@@ -0,0 +1,13 @@
+锘縰sing System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace StationGlobalsReader;
+
+/// <summary>
+/// Interaction logic for App.xaml
+/// </summary>
+public partial class App : Application
+{
+}
+
diff --git a/StationGlobalsReader/AssemblyInfo.cs b/StationGlobalsReader/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/StationGlobalsReader/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/StationGlobalsReader/MainWindow.xaml b/StationGlobalsReader/MainWindow.xaml
new file mode 100644
index 0000000..73c26bd
--- /dev/null
+++ b/StationGlobalsReader/MainWindow.xaml
@@ -0,0 +1,29 @@
+锘�<Window x:Class="StationGlobalsReader.MainWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:StationGlobalsReader"
+ mc:Ignorable="d"
+ Title="MainWindow" Height="450" Width="800">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition Height="Auto"/>
+ <RowDefinition/>
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto"/>
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <WindowsFormsHost x:Name="host" Visibility="Collapsed"></WindowsFormsHost>
+
+ <TextBlock Grid.Row="0" Grid.Column="0" Text="StationGlobals."/>
+ <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding PropertyName}"/>
+
+ <TextBlock Grid.Row="1" Grid.Column="0" Text="鍊�"/>
+ <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Tagert}"/>
+
+ <Button Grid.Row="2" Grid.ColumnSpan="2" Click="Button_Click">璇诲彇</Button>
+ </Grid>
+</Window>
diff --git a/StationGlobalsReader/MainWindow.xaml.cs b/StationGlobalsReader/MainWindow.xaml.cs
new file mode 100644
index 0000000..d3fe27f
--- /dev/null
+++ b/StationGlobalsReader/MainWindow.xaml.cs
@@ -0,0 +1,50 @@
+锘縰sing CommunityToolkit.Mvvm.ComponentModel;
+using NationalInstruments.TestStand.Interop.API;
+using NationalInstruments.TestStand.Interop.UI.Ax;
+using System.Windows;
+using System.Windows.Forms.Integration;
+
+namespace StationGlobalsReader;
+
+/// <summary>
+/// Interaction logic for MainWindow.xaml
+/// </summary>
+[ObservableObject]
+public partial class MainWindow : Window
+{
+ public MainWindow()
+ {
+ axApplicationMgr = new AxApplicationMgr();
+ InitializeComponent();
+
+ this.engine = axApplicationMgr.GetEngine();
+ this.engine.PersistBreakpoints = false;
+ this.axApplicationMgr.IsEditor = true;
+ this.axApplicationMgr.LoginOnStart = false;
+ this.axApplicationMgr.Start();
+ ((System.ComponentModel.ISupportInitialize)(axApplicationMgr)).BeginInit();
+ host.Child = axApplicationMgr;
+ ((System.ComponentModel.ISupportInitialize)(axApplicationMgr)).EndInit();
+ }
+ private AxApplicationMgr axApplicationMgr;
+
+ private Engine engine = null;
+
+ [ObservableProperty]
+ private string propertyName;
+
+ [ObservableProperty]
+ private string target;
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ Target = engine.Globals.GetValString($"StationGlobals.{PropertyName}", 0);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/StationGlobalsReader/StationGlobalsReader.csproj b/StationGlobalsReader/StationGlobalsReader.csproj
new file mode 100644
index 0000000..516e0ac
--- /dev/null
+++ b/StationGlobalsReader/StationGlobalsReader.csproj
@@ -0,0 +1,28 @@
+锘�<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>WinExe</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <Nullable>enable</Nullable>
+ <LangVersion>10.0</LangVersion>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UseWPF>true</UseWPF>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
+ <PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Reference Include="NationalInstruments.TestStand.Interop.API">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.API.dll</HintPath>
+ </Reference>
+ <Reference Include="NationalInstruments.TestStand.Interop.UI.AxControls">
+ <HintPath>..\Libs\NationalInstruments.TestStand.Interop.UI.AxControls.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="WindowsFormsIntegration" />
+ </ItemGroup>
+
+</Project>
diff --git a/WPFProject/App.config b/WPFProject/App.config
index fabccd6..0985874 100644
--- a/WPFProject/App.config
+++ b/WPFProject/App.config
@@ -3,7 +3,8 @@
<configSections>
<section name="TestResultConfig" type="System.Configuration.SingleTagSectionHandler" />
</configSections>
- <TestResultConfig Row="2" Column="2" PortStart="6660" PositionColumn="4" PositionCount="20" NameStr="A,B,C,D,E,F,G" CodeParserType="Model" />
+ <TestResultConfig Row="2" Column="2" PortStart="6660" PositionColumn="4" PositionCount="20" NameStr="A,B,C,D,E,F,G"
+ CodeParserType="Model"/>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
diff --git a/WPFProject/BuildCmd.bat b/WPFProject/BuildCmd.bat
index cfde15f..2c58c66 100644
--- a/WPFProject/BuildCmd.bat
+++ b/WPFProject/BuildCmd.bat
@@ -1,15 +1,30 @@
锘縄F "$(ConfigurationName)"=="Release" Confuser.CLI.exe $(TargeDir)..\ConfuserEx\$(TargetFileName).crproj
+
+mkdir "$(TargetDir)OpenTap"
+
+copy "$(TargeDir)HMI.Core.dll" "$(TargetDir)OpenTap"
+copy "$(TargeDir)HMI.Simple.Util.dll" "$(TargetDir)OpenTap"
+copy "$(TargeDir)HMI.Util.Base.dll" "$(TargetDir)OpenTap"
+
move /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
move /y "$(TargeDir)HMI.Base.dll" $(TargeDir)Libs\HMI.Base.dll"
move /y "$(TargeDir)HMI.UI.dll" $(TargeDir)Libs\HMI.UI.dll"
move /y "$(TargeDir)HMI.Util.dll" $(TargeDir)Libs\HMI.Util.dll"
move /y "$(TargeDir)ConnectionUtil.dll" $(TargeDir)Libs\ConnectionUtil.dll"
+move /y "$(TargeDir)HMI.StdControl.dll" $(TargeDir)Libs\HMI.StdControl.dll"
+move /y "$(TargeDir)S7Driver.dll" $(TargeDir)Libs\S7Driver.dll"
+move /y "$(TargeDir)HslCommunication.dll" $(TargeDir)Libs\HslCommunication.dll"
+move /y "$(TargeDir)PLCHelper.dll" $(TargeDir)Libs\PLCHelper.dll"
+move /y "$(TargeDir)ModBusTcpController.dll" $(TargeDir)Libs\ModBusTcpController.dll"
move /y "$(TargeDir)HMI.LogUtil.dll" $(TargeDir)Api\HMI.LogUtil.dll"
move /y "$(TargeDir)HMI.SerialData.Util.dll" $(TargeDir)Api\HMI.SerialData.Util.dll"
move /y "$(TargeDir)HMI.Simple.Util.dll" $(TargeDir)Api\HMI.Simple.Util.dll"
move /y "$(TargeDir)HMI.Util.Base.dll" $(TargeDir)Api\HMI.Util.Base.dll"
+move /y "$(TargeDir)CellStepSender.dll" $(TargeDir)Api\CellStepSender.dll"
+
+mkdir "$(TargetDir)Plugin"
move /y "$(TargeDir)HMI.AlarmInfoManage.dll" $(TargeDir)Plugin\HMI.AlarmInfoManage.dll"
move /y "$(TargeDir)HMI.DataViewer.dll" $(TargeDir)Plugin\HMI.DataViewer.dll"
@@ -30,6 +45,17 @@
move /y "$(TargeDir)Plugin.MaterialOpt.dll" $(TargeDir)Plugin\Plugin.MaterialOpt.dll"
move /y "$(TargeDir)Plugin.DODriverControl.dll" $(TargeDir)Plugin\Plugin.DODriverControl.dll"
move /y "$(TargeDir)Plugin.ModelManage.dll" $(TargeDir)Plugin\Plugin.ModelManage.dll"
+move /y "$(TargeDir)Plugin.CurrentSensorControl.dll" $(TargeDir)Plugin\Plugin.CurrentSensorControl.dll"
+move /y "$(TargeDir)Plugin.TsSupport.dll" $(TargeDir)Plugin\Plugin.TsSupport.dll"
+move /y "$(TargeDir)Plugin.DataViewer.dll" $(TargeDir)Plugin\Plugin.DataViewer.dll"
+move /y "$(TargeDir)Util.ManualDebug.dll" $(TargeDir)Plugin\Util.ManualDebug.dll"
+move /y "$(TargeDir)Plugin.QualityReport.dll" $(TargeDir)Plugin\Plugin.QualityReport.dll"
+move /y "$(TargeDir)Plugin.BurnIn.dll" $(TargeDir)Plugin\Plugin.BurnIn.dll"
+
+move /y "$(TargeDir)AddInPlugin.dll" "$(TargetDir)OpenTap\AddInPlugin.dll"
+move /y "$(TargeDir)OpenTap.dll" "$(TargetDir)OpenTap\OpenTap.dll"
+move /y "$(TargeDir)OpenTap.Plugins.BasicSteps.dll" "$(TargetDir)OpenTap\OpenTap.Plugins.BasicSteps.dll"
+move /y "$(TargeDir)HMI.TapApi.dll" "$(TargetDir)OpenTap\HMI.TapApi.dll"
setlocal enabledelayedexpansion
@@ -46,13 +72,13 @@
)
for /d %%D in ("%source_folder%\*") do (
- if /I not "%%~nxD"=="Api" if /I not "%%~nxD"=="Config" if /I not "%%~nxD"=="Icon" if /I not "%%~nxD"=="Lang" if /I not "%%~nxD"=="Libs" if /I not "%%~nxD"=="Log" if /I not "%%~nxD"=="Plugin" if /I not "%%~nxD"=="TestPlatform.exe.WebView2" (
+ if /I not "%%~nxD"=="Api" if /I not "%%~nxD"=="Config" if /I not "%%~nxD"=="Icon" if /I not "%%~nxD"=="Lang" if /I not "%%~nxD"=="Libs" if /I not "%%~nxD"=="Log" if /I not "%%~nxD"=="Plugin" if /I not "%%~nxD"=="TestPlatform.exe.WebView2" if /I not "%%~nxD"=="OpenTap" (
move /Y "%%D" "%destination_folder%"
)
)
for %%F in ("%source_folder%\*") do (
- if /I not "%%~nxF"=="$(TargetFileName)" if /I not "%%~nxF"=="$(TargetFileName).config" if /I not "%%~nxF"=="$(TargetName).pdb" if /I not "%%~nxF"=="clear.bat" if /I not "%%~nxF"=="瀹夎MSMQ.bat" (
+ if /I not "%%~nxF"=="$(TargetFileName)" if /I not "%%~nxF"=="$(TargetFileName).config" if /I not "%%~nxF"=="$(TargetName).pdb" if /I not "%%~nxF"=="clear.bat" if /I not "%%~nxF"=="瀹夎MSMQ.bat" if /I not "%%~nxF"=="Settings.ini" (
move /Y "%%F" "%destination_folder%"
)
)
diff --git a/WPFProject/Plugin/Here put your plugins.txt b/WPFProject/Plugin/Here put your plugins.txt
deleted file mode 100644
index 5f28270..0000000
--- a/WPFProject/Plugin/Here put your plugins.txt
+++ /dev/null
@@ -1 +0,0 @@
-锘�
\ No newline at end of file
diff --git a/WPFProject/ResourceListener.cs b/WPFProject/ResourceListener.cs
index cbd8f05..3759620 100644
--- a/WPFProject/ResourceListener.cs
+++ b/WPFProject/ResourceListener.cs
@@ -1,10 +1,8 @@
-锘縰sing HMI.Simple.Util;
-using log4net;
+锘縰sing log4net;
using System;
using System.Diagnostics;
using System.Management;
using System.Timers;
-using System.Xml.Linq;
namespace WPFProject
{
@@ -97,11 +95,11 @@
totalCpuRate = totalCpuRate,
totalRemRate = usagePercent
});
- log.Info(info);
- //if (usagePercent > 80)
- //{
- // AlarmUtil.CreateAlarm("App", "鍐呭瓨鍗犵敤杩囬珮锛岃秴80%", out _);
- //}
+ if (usagePercent > 80)
+ {
+ log.Info(info);
+ //AlarmUtil.CreateAlarm("App", "鍐呭瓨鍗犵敤杩囬珮锛岃秴80%", out _);
+ }
}
}
catch (Exception ex)
diff --git a/WPFProject/WPFProject.csproj b/WPFProject/WPFProject.csproj
index 10f5341..4260917 100644
--- a/WPFProject/WPFProject.csproj
+++ b/WPFProject/WPFProject.csproj
@@ -326,9 +326,6 @@
<Resource Include="Icon\t2.png" />
<Resource Include="Icon\t3.png" />
<Resource Include="Icon\t4.png" />
- <Content Include="Plugin\Here put your plugins.txt">
- <CopyToOutputDirectory>Always</CopyToOutputDirectory>
- </Content>
<Resource Include="Resources\Background.png" />
<Resource Include="Resources\JingCeLogo.png" />
<EmbeddedResource Include="Controls\HolderForm.resx">
@@ -449,9 +446,17 @@
<Project>{49db0c9b-b239-4608-a91e-f5ed43afaf96}</Project>
<Name>ModBusTcpController</Name>
</ProjectReference>
+ <ProjectReference Include="..\Plugin.BurnIn\Plugin.BurnIn.csproj">
+ <Project>{7964f444-d2c6-4c11-87f4-0df4faec10b6}</Project>
+ <Name>Plugin.BurnIn</Name>
+ </ProjectReference>
<ProjectReference Include="..\Plugin.DataViewer\Plugin.DataViewer.csproj">
<Project>{dbfe5040-963f-4bbf-93fb-26b3f18fda90}</Project>
<Name>Plugin.DataViewer</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Plugin.QualityReport\Plugin.QualityReport.csproj">
+ <Project>{0fd55872-b9f6-41ad-8d3f-6d7a7d3f1233}</Project>
+ <Name>Plugin.QualityReport</Name>
</ProjectReference>
<ProjectReference Include="..\Plugin.SeqEditor\Plugin.SeqEditor.csproj">
<Project>{1260f995-1ae9-17b6-feb5-c430c1416bec}</Project>
@@ -564,6 +569,13 @@
<PropertyGroup>
<PostBuildEvent>IF "$(ConfigurationName)"=="Release" Confuser.CLI.exe $(TargeDir)..\ConfuserEx\$(TargetFileName).crproj
+
+mkdir "$(TargetDir)OpenTap"
+
+copy "$(TargeDir)HMI.Core.dll" "$(TargetDir)OpenTap"
+copy "$(TargeDir)HMI.Simple.Util.dll" "$(TargetDir)OpenTap"
+copy "$(TargeDir)HMI.Util.Base.dll" "$(TargetDir)OpenTap"
+
move /y "$(TargeDir)HMI.Core.dll" $(TargeDir)Libs\HMI.Core.dll"
move /y "$(TargeDir)HMI.Base.dll" $(TargeDir)Libs\HMI.Base.dll"
move /y "$(TargeDir)HMI.UI.dll" $(TargeDir)Libs\HMI.UI.dll"
@@ -580,6 +592,8 @@
move /y "$(TargeDir)HMI.Simple.Util.dll" $(TargeDir)Api\HMI.Simple.Util.dll"
move /y "$(TargeDir)HMI.Util.Base.dll" $(TargeDir)Api\HMI.Util.Base.dll"
move /y "$(TargeDir)CellStepSender.dll" $(TargeDir)Api\CellStepSender.dll"
+
+mkdir "$(TargetDir)Plugin"
move /y "$(TargeDir)HMI.AlarmInfoManage.dll" $(TargeDir)Plugin\HMI.AlarmInfoManage.dll"
move /y "$(TargeDir)HMI.DataViewer.dll" $(TargeDir)Plugin\HMI.DataViewer.dll"
@@ -604,6 +618,13 @@
move /y "$(TargeDir)Plugin.TsSupport.dll" $(TargeDir)Plugin\Plugin.TsSupport.dll"
move /y "$(TargeDir)Plugin.DataViewer.dll" $(TargeDir)Plugin\Plugin.DataViewer.dll"
move /y "$(TargeDir)Util.ManualDebug.dll" $(TargeDir)Plugin\Util.ManualDebug.dll"
+move /y "$(TargeDir)Plugin.QualityReport.dll" $(TargeDir)Plugin\Plugin.QualityReport.dll"
+move /y "$(TargeDir)Plugin.BurnIn.dll" $(TargeDir)Plugin\Plugin.BurnIn.dll"
+
+move /y "$(TargeDir)AddInPlugin.dll" "$(TargetDir)OpenTap\AddInPlugin.dll"
+move /y "$(TargeDir)OpenTap.dll" "$(TargetDir)OpenTap\OpenTap.dll"
+move /y "$(TargeDir)OpenTap.Plugins.BasicSteps.dll" "$(TargetDir)OpenTap\OpenTap.Plugins.BasicSteps.dll"
+move /y "$(TargeDir)HMI.TapApi.dll" "$(TargetDir)OpenTap\HMI.TapApi.dll"
setlocal enabledelayedexpansion
@@ -620,7 +641,7 @@
)
for /d %25%25D in ("%25source_folder%25\*") do (
- if /I not "%25%25~nxD"=="Api" if /I not "%25%25~nxD"=="Config" if /I not "%25%25~nxD"=="Icon" if /I not "%25%25~nxD"=="Lang" if /I not "%25%25~nxD"=="Libs" if /I not "%25%25~nxD"=="Log" if /I not "%25%25~nxD"=="Plugin" if /I not "%25%25~nxD"=="TestPlatform.exe.WebView2" (
+ if /I not "%25%25~nxD"=="Api" if /I not "%25%25~nxD"=="Config" if /I not "%25%25~nxD"=="Icon" if /I not "%25%25~nxD"=="Lang" if /I not "%25%25~nxD"=="Libs" if /I not "%25%25~nxD"=="Log" if /I not "%25%25~nxD"=="Plugin" if /I not "%25%25~nxD"=="TestPlatform.exe.WebView2" if /I not "%25%25~nxD"=="OpenTap" (
move /Y "%25%25D" "%25destination_folder%25"
)
)
diff --git a/WPFProject/WPFProject.sln b/WPFProject/WPFProject.sln
index 9b2595b..5546767 100644
--- a/WPFProject/WPFProject.sln
+++ b/WPFProject/WPFProject.sln
@@ -85,6 +85,20 @@
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Util.ManualDebug", "..\Util.ManualDebug\Util.ManualDebug.csproj", "{D0944E62-EE52-4ABE-832A-A09D98814DB1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tap.Engine", "..\..\..\Project\OpenTapEditor\OpenTap\Engine\Tap.Engine.csproj", "{EFBD516D-3DC9-9D75-F082-48FBC76715F7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInPlugin", "..\..\..\Project\OpenTapEditor\Plugin\AddInPlugin\AddInPlugin.csproj", "{0D150CA1-D6EA-3362-7330-028939E66E1C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tap.Plugins.BasicSteps", "..\..\..\Project\OpenTapEditor\OpenTap\BasicSteps\Tap.Plugins.BasicSteps.csproj", "{4BCFADC0-54F9-7032-B918-E4DD407CAA76}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.QualityReport", "..\Plugin.QualityReport\Plugin.QualityReport.csproj", "{0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HMI.TapApi", "..\SimpleUtil\HMI.TapApi\HMI.TapApi.csproj", "{EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StationGlobalsReader", "..\StationGlobalsReader\StationGlobalsReader.csproj", "{87F7AD77-45E9-4185-A4F7-13041796E7B6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.BurnIn", "..\Plugin.BurnIn\Plugin.BurnIn.csproj", "{7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -575,6 +589,90 @@
{D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x64.Build.0 = Release|Any CPU
{D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x86.ActiveCfg = Release|x86
{D0944E62-EE52-4ABE-832A-A09D98814DB1}.Release|x86.Build.0 = Release|x86
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Debug|x64.ActiveCfg = Debug|x64
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Debug|x64.Build.0 = Debug|x64
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Debug|x86.Build.0 = Debug|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Release|x64.ActiveCfg = Release|x64
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Release|x64.Build.0 = Release|x64
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Release|x86.ActiveCfg = Release|Any CPU
+ {EFBD516D-3DC9-9D75-F082-48FBC76715F7}.Release|x86.Build.0 = Release|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Debug|x64.ActiveCfg = Debug|x64
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Debug|x64.Build.0 = Debug|x64
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Debug|x86.Build.0 = Debug|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Release|x64.ActiveCfg = Release|x64
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Release|x64.Build.0 = Release|x64
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Release|x86.ActiveCfg = Release|Any CPU
+ {0D150CA1-D6EA-3362-7330-028939E66E1C}.Release|x86.Build.0 = Release|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Debug|x64.ActiveCfg = Debug|x64
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Debug|x64.Build.0 = Debug|x64
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Debug|x86.Build.0 = Debug|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Release|x64.ActiveCfg = Release|x64
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Release|x64.Build.0 = Release|x64
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Release|x86.ActiveCfg = Release|Any CPU
+ {4BCFADC0-54F9-7032-B918-E4DD407CAA76}.Release|x86.Build.0 = Release|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Debug|x64.ActiveCfg = Debug|x64
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Debug|x64.Build.0 = Debug|x64
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Debug|x86.Build.0 = Debug|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Release|x64.ActiveCfg = Release|x64
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Release|x64.Build.0 = Release|x64
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Release|x86.ActiveCfg = Release|Any CPU
+ {0FD55872-B9F6-41AD-8D3F-6D7A7D3F1233}.Release|x86.Build.0 = Release|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Debug|x64.Build.0 = Debug|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Debug|x86.Build.0 = Debug|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Release|x64.ActiveCfg = Release|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Release|x64.Build.0 = Release|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Release|x86.ActiveCfg = Release|Any CPU
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7}.Release|x86.Build.0 = Release|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Debug|x64.Build.0 = Debug|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Debug|x86.Build.0 = Debug|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Release|x64.ActiveCfg = Release|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Release|x64.Build.0 = Release|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Release|x86.ActiveCfg = Release|Any CPU
+ {87F7AD77-45E9-4185-A4F7-13041796E7B6}.Release|x86.Build.0 = Release|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Debug|x64.ActiveCfg = Debug|x64
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Debug|x64.Build.0 = Debug|x64
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Debug|x86.Build.0 = Debug|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Release|x64.ActiveCfg = Release|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Release|x64.Build.0 = Release|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Release|x86.ActiveCfg = Release|Any CPU
+ {7964F444-D2C6-4C11-87F4-0DF4FAEC10B6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -586,6 +684,7 @@
{D59E25D1-9B27-46A1-8438-92661DD23FAE} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{F8B8B6B6-821B-4FF6-B556-9CAB840EA57A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{34FFBAFE-478F-4B6E-95E7-92A949011A9B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
+ {EEFDF6FE-41AD-4EB0-9CE6-87A07B88F9D7} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {784CEA1D-A890-4625-B0C1-72294A6B4803}
--
Gitblit v1.9.1