From e3868d4d61ded0e76fc8fe3fdacdd9e6d9113cf1 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期一, 13 十月 2025 08:50:15 +0800
Subject: [PATCH] 优化HMI;
---
HMI.ParameterManage/ParameterModal.xaml.cs | 7
HMI.ParameterManage/ParameterManage.xaml.cs | 2
Plugin.DataBoard/Libs/Static/test.html | 244 +++++++++++++++
HMI.ParameterManage/Model/XmlModel.cs | 3
Plugin.DataBoard/DataBoard.xaml.cs | 413 +++++++++++++++++----------
HMI.ParameterManage/ParameterModal.xaml | 3
SimpleUtil/HMI.Simple.Util/ParameterUtil.cs | 18
HMI.ParameterManage/SettingModal.xaml.cs | 2
HMI.ParameterManage/Properties/AssemblyInfo.cs | 2
Plugin.TsExecution/TsExecution.xaml.cs | 85 ++---
SimpleUtil/HMI.Simple.Util/ProductUtil.cs | 18 +
HMI.UnitTest/MainWindow.xaml.cs | 91 ++++++
12 files changed, 663 insertions(+), 225 deletions(-)
diff --git a/HMI.ParameterManage/Model/XmlModel.cs b/HMI.ParameterManage/Model/XmlModel.cs
index 16503c0..9f0f984 100644
--- a/HMI.ParameterManage/Model/XmlModel.cs
+++ b/HMI.ParameterManage/Model/XmlModel.cs
@@ -53,6 +53,8 @@
}
}
+ public List<string> groups { get; private set; }
+
public bool ValidateProductName(object value, out string msg)
{
msg = null;
@@ -98,6 +100,7 @@
}
parameters = parameters ?? new ObservableCollection<ParameterData>();
Parameters = parameters;
+ groups = Parameters.Where(p => !string.IsNullOrEmpty(p.PGroup)).Select(p => p.PGroup).Distinct().ToList();
}
public void SaveOrUpdateData(ProductData data)
diff --git a/HMI.ParameterManage/ParameterManage.xaml.cs b/HMI.ParameterManage/ParameterManage.xaml.cs
index 398bd8b..52ed3f5 100644
--- a/HMI.ParameterManage/ParameterManage.xaml.cs
+++ b/HMI.ParameterManage/ParameterManage.xaml.cs
@@ -101,7 +101,7 @@
Title = data == null ? this.lang("Pm.Parameter.Add") : this.lang("Pm.Parameter.Edit"),
Owner = Window.GetWindow(this),
};
- if (win.Open(Model.SelectedProduct.Name, data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }) == true)
+ if (win.Open(Model.SelectedProduct.Name, data ?? new ParameterData { ProductName = Model.SelectedProduct.Name }, Model.groups) == true)
{
Model.LoadParameters();
}
diff --git a/HMI.ParameterManage/ParameterModal.xaml b/HMI.ParameterManage/ParameterModal.xaml
index 2e316cb..c93342f 100644
--- a/HMI.ParameterManage/ParameterModal.xaml
+++ b/HMI.ParameterManage/ParameterModal.xaml
@@ -83,7 +83,8 @@
<pu:FormGroup x:Name="FgPGroup" Style="{StaticResource InputFormGroupStyle}"
Header="{DynamicResource Pm.Parameter.Group}"
dp:FormGroupHelper.IsRequired="False" GroupName="MyFormGroup">
- <TextBox x:Name="TbPGroup" Style="{StaticResource EditorTextBoxStyle}" />
+ <!--<TextBox x:Name="TbPGroup" Style="{StaticResource EditorTextBoxStyle}" />-->
+ <ComboBox x:Name="CbGroup" IsEditable="True" Style="{StaticResource FormComboxStyle}"/>
</pu:FormGroup>
</StackPanel>
</Grid>
diff --git a/HMI.ParameterManage/ParameterModal.xaml.cs b/HMI.ParameterManage/ParameterModal.xaml.cs
index 854380e..ab9f77a 100644
--- a/HMI.ParameterManage/ParameterModal.xaml.cs
+++ b/HMI.ParameterManage/ParameterModal.xaml.cs
@@ -84,22 +84,23 @@
Data.Unit = TbUnit.Text;
Data.Description = TbDescription.Text;
Data.ProductName = TbProductName.Text;
- Data.PGroup = TbPGroup.Text;
+ Data.PGroup = CbGroup.Text;
}
return flag;
}
- public bool? Open(string productName, ParameterData data)
+ public bool? Open(string productName, ParameterData data, List<string> groups)
{
Data = data;
TbName.Text = Data.Name;
CbType.SelectedValue = Data.Type;
+ CbGroup.ItemsSource = groups;
UpdateWindow(Data.Type);
UpdateForm(Data);
TbUnit.Text = Data.Unit;
TbProductName.Text = productName;
TbDescription.Text = Data.Description;
- TbPGroup.Text = Data.PGroup;
+ CbGroup.Text = Data.PGroup;
return this.ShowDialog();
}
diff --git a/HMI.ParameterManage/Properties/AssemblyInfo.cs b/HMI.ParameterManage/Properties/AssemblyInfo.cs
index a661fe3..c4d7356 100644
--- a/HMI.ParameterManage/Properties/AssemblyInfo.cs
+++ b/HMI.ParameterManage/Properties/AssemblyInfo.cs
@@ -49,4 +49,4 @@
// 淇鍙�
//
[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.2")]
+[assembly: AssemblyFileVersion("1.0.0.3")]
diff --git a/HMI.ParameterManage/SettingModal.xaml.cs b/HMI.ParameterManage/SettingModal.xaml.cs
index 20925c9..98f2993 100644
--- a/HMI.ParameterManage/SettingModal.xaml.cs
+++ b/HMI.ParameterManage/SettingModal.xaml.cs
@@ -102,7 +102,7 @@
return flag;
}
- public bool? Open(ParameterData data, ObservableCollection<ParameterData> datasource,List<string> groups)
+ public bool? Open(ParameterData data, ObservableCollection<ParameterData> datasource, List<string> groups)
{
Datasource = datasource;
Data = data;
diff --git a/HMI.UnitTest/MainWindow.xaml.cs b/HMI.UnitTest/MainWindow.xaml.cs
index a267a28..6378bc8 100644
--- a/HMI.UnitTest/MainWindow.xaml.cs
+++ b/HMI.UnitTest/MainWindow.xaml.cs
@@ -8,10 +8,10 @@
using Plugin.TestResult_WPF;
using Plugin.TsExecution;
using System;
+using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
-
namespace UnitTest
{
/// <summary>
@@ -25,6 +25,7 @@
ProductModelHelper.GetModelBySNR("cc123", out string model, out string msg);
LangUtil.Load();
InitializeComponent();
+ RebuildDb();
//page.Children.Add(new UserControl1());
}
@@ -32,6 +33,94 @@
PipeClient2 client;
+ public string Conv(object obj)
+ {
+ if (obj == null || obj is DBNull)
+ {
+ return "NULL";
+ }
+ if (obj is DateTime dt)
+ {
+ return $"'{dt.ToString("yyyy-MM-dd HH:mm:ss")}'";
+ }
+ return $"'{obj.ToString()}'";
+ }
+
+
+ public void RebuildDb()
+ {
+ string folder = "C:\\Workspace\\VisualStudio\\WPFProject\\WPFProject\\bin\\x64\\Debug\\Config\\DataBoard";
+ var startDate = DateTime.Parse("2025-10-01");
+ var endDate = startDate.AddDays(1);
+ SqliteHelper sourceHelper = new SqliteHelper("C:\\Workspace\\VisualStudio\\WPFProject\\WPFProject\\bin\\x64\\Debug\\Config\\DataBoard\\DataLog.db");
+
+ while (endDate < DateTime.Parse("2025-10-12"))
+ {
+ string targetFile = Path.Combine(folder, $"Data_{startDate.ToString("yyyyMMdd")}.db");
+ SqliteHelper targetHelper = null;
+ if (!File.Exists(targetFile))
+ {
+ SqliteHelper.CreateDatabase(targetFile);
+ targetHelper = new SqliteHelper(targetFile);
+ targetHelper.ExecuteSql(@"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,
+ time DATETIME NOT NULL);");
+ targetHelper.ExecuteSql(@"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,
+ time DATETIME NOT NULL);");
+
+ string sql = $@"SELECT sn,model,station,step,position,limitDown,limitUp,unit,offset,value,status,
+finalStatus,consumeTime,totalConsumeTime,time
+FROM serialData WHERE time>='{startDate.ToString("yyyy-MM-dd")}' AND time < '{endDate.ToString("yyyy-MM-dd")}';";
+
+ var dt = sourceHelper.GetDataTable(sql);
+ foreach (System.Data.DataRow dr in dt.Rows)
+ {
+ targetHelper.ExecuteSql($@"INSERT INTO serialData
+(sn,model,station,step,position,limitDown,limitUp,unit,offset,value,status,finalStatus,consumeTime,totalConsumeTime,time) VALUES
+({Conv(dr["sn"])}, {Conv(dr["model"])}, {Conv(dr["station"])}, {Conv(dr["step"])}, {Conv(dr["position"])}, {Conv(dr["limitDown"])}, {Conv(dr["limitUP"])},
+{Conv(dr["unit"])}, {Conv(dr["offset"])}, {Conv(dr["value"])}, {Conv(dr["status"])}, {Conv(dr["finalStatus"])}, {Conv(dr["consumeTime"])},
+{Conv(dr["totalConsumeTime"])}, {Conv(dr["time"])})");
+ }
+ sql = $@"SELECT sn,model,station,position,status,result,time FROM testResult WHERE time>='{startDate.ToString("yyyy-MM-dd")}'
+AND time < '{endDate.ToString("yyyy-MM-dd")}';";
+
+ dt = sourceHelper.GetDataTable(sql);
+ foreach (System.Data.DataRow dr in dt.Rows)
+ {
+ targetHelper.ExecuteSql($@"INSERT INTO testResult
+(sn,model,station,position,status,result,time) VALUES
+({Conv(dr["sn"])}, {Conv(dr["model"])}, {Conv(dr["station"])}, {Conv(dr["position"])}, {Conv(dr["status"])}, {Conv(dr["result"])}, {Conv(dr["time"])})");
+ }
+
+ targetHelper.Dispose();
+ startDate = startDate.AddDays(1);
+ endDate = endDate.AddDays(1);
+ }
+ }
+ sourceHelper.Dispose();
+ }
+
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
diff --git a/Plugin.DataBoard/DataBoard.xaml.cs b/Plugin.DataBoard/DataBoard.xaml.cs
index 57aa86f..7e66211 100644
--- a/Plugin.DataBoard/DataBoard.xaml.cs
+++ b/Plugin.DataBoard/DataBoard.xaml.cs
@@ -10,6 +10,7 @@
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -76,14 +77,37 @@
}
}
+ public static string[] GetDbFiles(string folderPath, DateTime startTime, DateTime endTime)
+ {
+ if (!Directory.Exists(folderPath))
+ {
+ return new string[0];
+ }
+ string startName = $"Data_{startTime.ToString("yyyyMMdd")}";
+ string endName = $"Data_{endTime.ToString("yyyyMMdd")}";
+ var oldFiles = Directory.GetFiles(folderPath, "Data_*.db");
+ oldFiles = oldFiles.Where(file =>
+ {
+ var fileName = Path.GetFileNameWithoutExtension(file);
+ bool flag = true;
+ if (startTime != null) flag &= (string.Compare(fileName, startName) == 1 || fileName == startName);
+ if (endTime != null) flag &= (string.Compare(endName, fileName) == 1 || fileName == endName);
+ return flag;
+ }).ToArray();
+
+ return oldFiles;
+ }
+
+
private List<SerialData> SelectSerialDataByTime(DateTime start, DateTime end)
{
- string[] files = DbFileHelper.GetDbFiles(BaseFolder, start, end);
+ var s1 = DateTime.Now;
+ string[] files = GetDbFiles(BaseFolder, start, end);
if (files == null || files.Length <= 0)
{
return new List<SerialData>();
}
- string sql = $"SELECT * FROM serialData WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}';";
+ string sql = $"SELECT * FROM serialData WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' ORDER BY time DESC;";
DataTable dt = new DataTable();
foreach (string file in files)
@@ -93,12 +117,16 @@
dt.Merge(helper.GetDataTable(sql));
}
}
- return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
+ var s2 = DateTime.Now;
+ log.Info($"SelectSerialDataByTime Cast: {(s2 - s1).TotalMilliseconds}");
+ var data = BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
+ log.Info($"Bean Cast: {(DateTime.Now - s2).TotalMilliseconds}");
+ return data;
}
private List<SerialData> SelectResultDataByTime(DateTime start, DateTime end)
{
- string[] files = DbFileHelper.GetDbFiles(BaseFolder, start, end);
+ string[] files = GetDbFiles(BaseFolder, start, end);
if (files == null || files.Length <= 0)
{
return new List<SerialData>();
@@ -110,7 +138,8 @@
{
using (SqliteHelper helper = new SqliteHelper(file))
{
- dt.Merge(helper.GetDataTable(sql));
+ var temp = helper.GetDataTable(sql);
+ dt.Merge(temp);
}
}
return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
@@ -137,81 +166,135 @@
webview2.CoreWebView2?.ExecuteScriptAsync($"resize({width},{height})");
}
+ //private void RefreshChart0(DateTime start, DateTime end)
+ //{
+ // dtp00.SelectedDateTime = start;
+ // dtp01.SelectedDateTime = end;
+ // Task.Run(() =>
+ // {
+ // try
+ // {
+ // var st = DateTime.Now;
+ // List<SerialData> datas = SelectSerialDataByTime(start, end);
+ // log.Info($"0 Select Data cast: {(DateTime.Now-st).TotalMilliseconds}");
+
+ // datas.OrderByDescending(e => e.time);
+ // int all = 0, output = 0;
+ // HashSet<string> snCache = new HashSet<string>();
+ // foreach (var data in datas)
+ // {
+ // if (snCache.Contains(data.sn)) continue;
+ // snCache.Add(data.sn);
+ // all++;
+ // if (data.status == "Passed") output++;
+ // }
+ // var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
+ // Dispatcher.BeginInvoke(new Action(() =>
+ // {
+ // webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
+ // }));
+ // }
+ // catch (Exception ex)
+ // {
+ // log.Error("RefreshChart0 Error.", ex);
+ // ToastHelper.Error("琛�1鍒锋柊澶辫触锛�");
+ // }
+ // });
+ //}
+
private void RefreshChart0(DateTime start, DateTime end)
{
- try
+ dtp00.SelectedDateTime = start;
+ dtp01.SelectedDateTime = end;
+ Task.Run(() =>
{
- dtp00.SelectedDateTime = start;
- dtp01.SelectedDateTime = end;
- List<SerialData> datas = SelectSerialDataByTime(start, end);
-
- datas.OrderByDescending(e => e.time);
- int all = 0, output = 0;
- HashSet<string> snCache = new HashSet<string>();
- foreach (var data in datas)
+ try
{
- if (snCache.Contains(data.sn)) continue;
- snCache.Add(data.sn);
- all++;
- if (data.status == "Passed") output++;
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('鍔犺浇涓紝璇风◢鍚�...')");
+ }));
+ List<SerialData> datas = SelectResultDataByTime(start, end);
+ datas.OrderByDescending(e => e.time);
+ int all = 0, output = 0;
+ HashSet<string> snCache = new HashSet<string>();
+ foreach (var data in datas)
+ {
+ if (snCache.Contains(data.sn)) continue;
+ snCache.Add(data.sn);
+ all++;
+ if (data.result == "Passed") output++;
+ }
+ var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
+ }));
}
- var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
-
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
- }
- catch (Exception ex)
- {
- log.Error("RefreshChart0 Error.", ex);
- ToastHelper.Error("琛�1鍒锋柊澶辫触锛�");
- }
+ catch (Exception ex)
+ {
+ log.Error("RefreshChart0 Error.", ex);
+ ToastHelper.Error("琛�1鍒锋柊澶辫触锛�");
+ }
+ });
}
private void RefreshChart1(DateTime start, DateTime end)
{
- try
+ dtp10.SelectedDateTime = start;
+ dtp11.SelectedDateTime = end;
+ Task.Run(() =>
{
- dtp10.SelectedDateTime = start;
- dtp11.SelectedDateTime = end;
- List<SerialData> datas = SelectResultDataByTime(start, end);
+ try
+ {
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('鍔犺浇涓紝璇风◢鍚�...')");
+ }));
+ List<SerialData> datas = SelectResultDataByTime(start, end);
- datas = datas.OrderByDescending(e => e.time).ToList();
- Dictionary<string, int?> pieData = new Dictionary<string, int?> {
+ datas = datas.OrderByDescending(e => e.time).ToList();
+ Dictionary<string, int?> pieData = new Dictionary<string, int?> {
{ "Passed",0},
{ "Failed",0},
//{ "Action",0},
//{ "Wait",0},
};
- //if (datas == null || datas.Count <= 0)
- //{
- // pieData = new Dictionary<string, int?> {
- // { "Passed",null},
- // { "Failed",null},
- //};
- //}
+ //if (datas == null || datas.Count <= 0)
+ //{
+ // pieData = new Dictionary<string, int?> {
+ // { "Passed",null},
+ // { "Failed",null},
+ //};
+ //}
- HashSet<string> snCache = new HashSet<string>();
- foreach (var data in datas)
- {
- if (snCache.Contains(data.sn)) continue;
- snCache.Add(data.sn);
- if (pieData.ContainsKey(data.result))
+ HashSet<string> snCache = new HashSet<string>();
+ foreach (var data in datas)
{
- pieData[data.result]++;
+ if (snCache.Contains(data.sn)) continue;
+ snCache.Add(data.sn);
+ if (pieData.ContainsKey(data.result))
+ {
+ pieData[data.result]++;
+ }
}
+ string res = "[";
+ foreach (var key in pieData.Keys)
+ {
+ res += $"{{name:'{key}',value:{pieData[key]}}},";
+ }
+ res += "]";
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
+ }));
}
- string res = "[";
- foreach (var key in pieData.Keys)
+ catch (Exception ex)
{
- res += $"{{name:'{key}',value:{pieData[key]}}},";
+ log.Error("RefreshChart1 Error.", ex);
+ ToastHelper.Error("琛�2鍒锋柊澶辫触锛�");
}
- res += "]";
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
- }
- catch (Exception ex)
- {
- log.Error("RefreshChart1 Error.", ex);
- ToastHelper.Error("琛�2鍒锋柊澶辫触锛�");
- }
+ });
}
//private void RefreshChart2(DateTime start, DateTime end)
@@ -282,129 +365,147 @@
private void RefreshChart2(DateTime start, DateTime end)
{
- try
+ dtp20.SelectedDateTime = start;
+ dtp21.SelectedDateTime = end;
+ Task.Run(() =>
{
- dtp20.SelectedDateTime = start;
- dtp21.SelectedDateTime = end;
- List<SerialData> datas = SelectResultDataByTime(start, end);
-
- var groups =
- datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
-
- Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
-
- foreach (var group in groups)
+ try
{
- Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
- double all = 0, oneTimePass = 0, passed = 0;
- var groupDatas = group.ToList();
- groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
-
- foreach (var data in groupDatas)
+ Dispatcher.BeginInvoke(new Action(() =>
{
- if (!snStatusCache.ContainsKey(data.sn))
+ webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('鍔犺浇涓紝璇风◢鍚�...')");
+ }));
+ List<SerialData> datas = SelectResultDataByTime(start, end);
+
+ var groups =
+ datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
+
+ Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
+
+ foreach (var group in groups)
+ {
+ Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
+ double all = 0, oneTimePass = 0, passed = 0;
+ var groupDatas = group.ToList();
+ groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
+
+ foreach (var data in groupDatas)
{
- snStatusCache.Add(data.sn, data.result);
- all++;
- if (data.result == "Passed")
+ if (!snStatusCache.ContainsKey(data.sn))
{
- passed++;
- oneTimePass++;
+ snStatusCache.Add(data.sn, data.result);
+ all++;
+ if (data.result == "Passed")
+ {
+ passed++;
+ oneTimePass++;
+ }
+ }
+ else
+ {
+ if (snStatusCache[data.sn] == "Passed")
+ {
+ if (oneTimePass > 0) oneTimePass--;
+ snStatusCache[data.sn] = "NoOnePass";
+ }
}
}
- else
+ res.Add(group.Key, new PassRateData
{
- if (snStatusCache[data.sn] == "Passed")
- {
- if (oneTimePass > 0) oneTimePass--;
- snStatusCache[data.sn] = "NoOnePass";
- }
- }
+ time = group.Key,
+ onePassRate = oneTimePass / all * 100,
+ passRate = passed / all * 100,
+ });
}
- res.Add(group.Key, new PassRateData
+
+ string fields = "[", vals0 = "[", vals1 = "[";
+ foreach (var key in res.Keys)
{
- time = group.Key,
- onePassRate = oneTimePass / all * 100,
- passRate = passed / all * 100,
- });
+ 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})");
+ }));
}
-
-
-
- string fields = "[", vals0 = "[", vals1 = "[";
- foreach (var key in res.Keys)
+ catch (Exception ex)
{
- fields += $"'{key}',";
- vals0 += $"{res[key].onePassRate},";
- vals1 += $"{res[key].passRate},";
+ log.Error("RefreshChart2 Error.", ex);
+ ToastHelper.Error("琛�3鍒锋柊澶辫触锛�");
}
- fields += "]";
- vals0 += "]";
- vals1 += "]";
- var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
- }
- catch (Exception ex)
- {
- log.Error("RefreshChart2 Error.", ex);
- ToastHelper.Error("琛�3鍒锋柊澶辫触锛�");
- }
+ });
}
private void RefreshChart3(DateTime start, DateTime end)
{
- try
+ dtp30.SelectedDateTime = start;
+ dtp31.SelectedDateTime = end;
+ Task.Run(() =>
{
- dtp30.SelectedDateTime = start;
- dtp31.SelectedDateTime = end;
- List<SerialData> datas = SelectSerialDataByTime(start, end);
-
- datas = datas.OrderByDescending(e => e.time).ToList();
-
-
-
- Dictionary<string, SimpleData> pieData = new Dictionary<string, SimpleData>();
- List<SimpleData> datasource = new List<SimpleData>();
- //HashSet<string> snCache = new HashSet<string>();
-
- foreach (var data in datas)
+ try
{
- //if (snCache.Contains(data.sn)) continue;
- if (data.status != "Failed") continue;
- if (pieData.ContainsKey(data.step))
+ Dispatcher.BeginInvoke(new Action(() =>
{
- pieData[data.step].Value++;
- }
- else
+ webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('鍔犺浇涓紝璇风◢鍚�...')");
+ }));
+ var st = DateTime.Now;
+ List<SerialData> datas = SelectSerialDataByTime(start, end);
+ var s2 = DateTime.Now;
+ log.Info($"RefreshChart3 Data Cast {(s2 - st).TotalMilliseconds}");
+
+ Dictionary<string, SimpleData> pieData = new Dictionary<string, SimpleData>();
+ List<SimpleData> datasource = new List<SimpleData>();
+ //HashSet<string> snCache = new HashSet<string>();
+
+ foreach (var data in datas)
{
- pieData[data.step] = new SimpleData
+ //if (snCache.Contains(data.sn)) continue;
+ if (data.status != "Failed") continue;
+ if (pieData.ContainsKey(data.step))
{
- Name = data.step,
- Value = 1
- };
- datasource.Add(pieData[data.step]);
+ pieData[data.step].Value++;
+ }
+ else
+ {
+ pieData[data.step] = new SimpleData
+ {
+ Name = data.step,
+ Value = 1
+ };
+ datasource.Add(pieData[data.step]);
+ }
}
- }
- datasource = datasource.OrderByDescending(e => e.Value).ToList();
- if (datasource.Count > 10)
- {
- datasource = datasource.Take(10).ToList();
- }
+ datasource = datasource.OrderByDescending(e => e.Value).ToList();
+ if (datasource.Count > 10)
+ {
+ datasource = datasource.Take(10).ToList();
+ }
+ 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}])");
+ }));
}
-
- webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
- }
- catch (Exception ex)
- {
- log.Error("RefreshChart3 Error.", ex);
- ToastHelper.Error("琛�4鍒锋柊澶辫触锛�");
- }
+ catch (Exception ex)
+ {
+ log.Error("RefreshChart3 Error.", ex);
+ ToastHelper.Error("琛�4鍒锋柊澶辫触锛�");
+ }
+ });
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
diff --git a/Plugin.DataBoard/Libs/Static/test.html b/Plugin.DataBoard/Libs/Static/test.html
index 9b2e204..2989317 100644
--- a/Plugin.DataBoard/Libs/Static/test.html
+++ b/Plugin.DataBoard/Libs/Static/test.html
@@ -6,6 +6,140 @@
<head>
<title>Simple Surface</title>
<meta charset="utf-8">
+ <style type="text/css">
+ /* 瀵� loading 鏁翠綋甯冨眬*/
+ .loading-wrapper {
+ padding: 16px;
+ background-color: rgba(0, 0, 0, 0.8);
+ border-radius: 10px;
+ color: #fff;
+ text-align: center;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-evenly;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ background: rgba(0, 0, 0, 0.5);
+ }
+
+
+ /* loading 鍔ㄧ敾鍥惧儚鐖剁骇鐨勫竷灞� */
+ .loading-view {
+ height: 40px;
+ position: relative;
+ }
+
+ .loading-msg {
+ font-size: 14px;
+ margin: 8px 0 0 0;
+ position: relative;
+ }
+
+ .container1,
+ .container2 {
+ width: 40px;
+ height: 40px;
+ position: absolute;
+ /* border: 1px solid #ff0000; */
+ top: 0;
+ left: 50%;
+ margin-left: -20px;
+ position: absolute;
+ }
+
+ .container2 {
+ transform: rotate(45deg);
+ }
+
+ /* 绗�1绉嶅姩鐢诲拰绗簩绉嶇殑鐩稿悓閮ㄥ垎锛屽叾涓殑 animation 涔熺浉鍚� */
+ .circle,
+ .bounce {
+ width: 10px;
+ height: 10px;
+ background-color: #fff;
+ border-radius: 50%;
+ /* 璁剧疆灏忕悆鍔ㄧ敾 */
+ animation: loading 1.2s both infinite;
+ }
+
+ .circle {
+ position: absolute;
+ }
+
+ /* 璁剧疆灏忕悆鐨勭浉瀵逛綅缃� */
+ .circle1 {
+ top: 0;
+ left: 0;
+ }
+
+ .circle2 {
+ top: 0;
+ right: 0;
+ }
+
+ .circle3 {
+ bottom: 0;
+ right: 0;
+ }
+
+ .circle4 {
+ bottom: 0;
+ left: 0;
+ }
+
+ /* 璁剧疆寤舵椂 */
+ .container1 .circle1 {
+ animation-delay: 0s;
+ }
+
+ .container2 .circle1 {
+ animation-delay: 0.2s;
+ }
+
+ .container1 .circle2 {
+ animation-delay: 0.3s;
+ }
+
+ .container2 .circle2 {
+ animation-delay: 0.4s;
+ }
+
+ .container1 .circle3 {
+ animation-delay: 0.5s;
+ }
+
+ .container2 .circle3 {
+ animation-delay: 0.6s;
+ }
+
+ .container1 .circle4 {
+ animation-delay: 0.7s;
+ }
+
+ .container2 .circle5 {
+ animation-delay: 0.8s;
+ }
+
+ @keyframes loading {
+ 0% {
+ transform: scale(0);
+ }
+
+ 40% {
+ transform: scale(1);
+ }
+
+ 80% {
+ transform: scale(0);
+ }
+
+ 100% {
+ transform: scale(0);
+ }
+ }
+ </style>
<script src="echarts.min.js"></script>
<script type="text/javascript">
const color = ['#22448b'];
@@ -37,12 +171,15 @@
.chart {
height: 100%;
width: 25%;
+ position: relative;
}
</style>
</head>
<body>
<div id="container">
- <div id="chart0" class="chart"></div>
+ <div id="chart0" class="chart">
+
+ </div>
<div id="chart1" class="chart"></div>
<div id="chart2" class="chart"></div>
<div id="chart3" class="chart"></div>
@@ -75,9 +212,33 @@
}
]
};
- var chart0 = echarts.init(dom0);
+ var chart0 = null;
+ function loading0(msg) {
+ if (chart0 != null) {
+ chart0.dispose();
+ chart0 = null;
+ }
+ dom0.innerHTML = `<div class="loading-wrapper">
+ <div class="loading-view">
+ <div class="container1">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ <div class="container2">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ </div>
+ <h2 class="loading-msg">${msg}</h2>
+</div>`
+ }
function drawChart0(fields, data) {
+ chart0 = echarts.init(dom0);
opt0.xAxis.data = fields;
opt0.series[0].data = data;
chart0.setOption(opt0);
@@ -125,9 +286,33 @@
}
]
};
- var chart1 = echarts.init(dom1);
+ var chart1 = null;
+ function loading1(msg) {
+ if (chart1 != null) {
+ chart1.dispose();
+ chart1 = null;
+ }
+ dom1.innerHTML = `<div class="loading-wrapper">
+ <div class="loading-view">
+ <div class="container1">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ <div class="container2">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ </div>
+ <h2 class="loading-msg">${msg}</h2>
+</div>`
+ }
function drawChart1(data) {
+ chart1 = echarts.init(dom1);
opt1.series[0].data = data;
chart1.setOption(opt1);
}
@@ -175,9 +360,33 @@
}
]
};
- var chart2 = echarts.init(dom2);
+ var chart2 = null;
+ function loading2(msg) {
+ if (chart2 != null) {
+ chart2.dispose();
+ chart2 = null;
+ }
+ dom2.innerHTML = `<div class="loading-wrapper">
+ <div class="loading-view">
+ <div class="container1">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ <div class="container2">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ </div>
+ <h2 class="loading-msg">${msg}</h2>
+</div>`
+ }
function drawChart2(label, names, data0, data1) {
+ chart2 = echarts.init(dom2)
opt2.xAxis.data = label;
opt2.series[0].name = names[0];
opt2.series[0].data = data0;
@@ -242,9 +451,34 @@
}
]
};
- var chart3 = echarts.init(dom3);
+ var chart3 = null;
+
+ function loading3(msg) {
+ if (chart3 != null) {
+ chart3.dispose();
+ chart3 = null;
+ }
+ dom3.innerHTML = `<div class="loading-wrapper">
+ <div class="loading-view">
+ <div class="container1">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ <div class="container2">
+ <div class="circle circle1"></div>
+ <div class="circle circle2"></div>
+ <div class="circle circle3"></div>
+ <div class="circle circle4"></div>
+ </div>
+ </div>
+ <h2 class="loading-msg">${msg}</h2>
+</div>`
+ }
function drawChart3(label, data) {
+ chart3 = echarts.init(dom3);
opt3.yAxis.data = label;
opt3.series[0].data = data;
chart3.setOption(opt3);
diff --git a/Plugin.TsExecution/TsExecution.xaml.cs b/Plugin.TsExecution/TsExecution.xaml.cs
index 83c45f0..11614c4 100644
--- a/Plugin.TsExecution/TsExecution.xaml.cs
+++ b/Plugin.TsExecution/TsExecution.xaml.cs
@@ -263,6 +263,7 @@
}
}
+ private string tsModelPath;
private string dataLogPath;
private SqliteHelper sqliteHelper;
@@ -284,23 +285,25 @@
base.SetBaseFolder(folder);
}
- public override void InitFinish()
+ private void CheckSqlHelper()
{
- this.ReadCount(out int pass, out int fail);
- this.DisplayCount(pass, fail);
- InitProducts();
- ReadConfig();
- if (!File.Exists(dataLogPath))
+ string today = DateTime.Now.ToString("yyyyMMdd");
+ string dbPath = Path.Combine(dataLogPath, $"Data_{today}.db");
+ if (!File.Exists(dbPath))
{
- SqliteHelper.CreateDatabase(dataLogPath);
+ SqliteHelper.CreateDatabase(dbPath);
}
- sqliteHelper = new SqliteHelper(dataLogPath);
- sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS serialData (
+ if (sqliteHelper == null || sqliteHelper.DataBaseFile != dbPath)
+ {
+ sqliteHelper?.Dispose();
+ sqliteHelper = new SqliteHelper(dbPath);
+ sqliteHelper.ExecuteSql(@"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,
@@ -311,48 +314,25 @@
consumeTime TEXT,
totalConsumeTime TEXT,
time DATETIME NOT NULL);");
- sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS testResult (
+ sqliteHelper.ExecuteSql(@"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,
time DATETIME NOT NULL);");
- try
- {
- sqliteHelper.ExecuteSql("alter table serialData add column 'model' TEXT default NULL;");
}
- catch
- {
+ }
- }
-
- try
- {
- sqliteHelper.ExecuteSql("alter table serialData add column 'position' TEXT default NULL;");
- }
- catch
- {
-
- }
- try
- {
- sqliteHelper.ExecuteSql("alter table testResult add column 'position' TEXT default NULL;");
- }
- catch
- {
-
- }
-
- try
- {
- sqliteHelper.ExecuteSql("alter table testResult add column 'status' TEXT default NULL;");
- }
- catch
- {
-
- }
-
+ public override void InitFinish()
+ {
+ this.ReadCount(out int pass, out int fail);
+ this.DisplayCount(pass, fail);
+ InitProducts();
+ ReadConfig();
+ CheckSqlHelper();
base.InitFinish();
}
@@ -865,8 +845,21 @@
}
catch
{
- dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard", "DataLog.db");
+ dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard");
}
+
+ try
+ {
+
+ value = ParameterManager.GetCommonParameterByName("TsModelPath");
+ tsModelPath = value.Value;
+ }
+ catch
+ {
+ //@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq"
+ tsModelPath = @"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq";
+ }
+
//Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableMes", "true", CountIniPath));
//EnableCanLog = Convert.ToBoolean(IniFileHelper.ReadIniData("Config", "EnableCanLog", "true", CountIniPath));
@@ -1001,8 +994,7 @@
{
engine?.Globals.SetValString("StationState.ProductModel", 1, SelectedProduct?.Name);
engine?.CommitGlobalsToDisk(promptOnSaveConflicts: false);
- //this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Program Files\National Instruments\TestStand 2020\Components\Models\TestStandModels\ParallelModel.seq");
- this.modeSeq = this.engine.GetSequenceFileEx(@"C:\Users\Public\Documents\National Instruments\TestStand 2020 (64-bit)\Components\Models\ParallelModel.seq");
+ 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;
@@ -1180,6 +1172,7 @@
public void SavePositionDB(int index, string status)
{
+ CheckSqlHelper();
var socket = this.tsSockets[index];
var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string snr = socket.Barcode;
diff --git a/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs b/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
index 25b24ae..ae461c2 100644
--- a/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/ParameterUtil.cs
@@ -9,11 +9,11 @@
public class ParameterUtil
{
/// <summary>
- ///
+ /// 鏍规嵁璺緞鍜屽弬鏁板悕鑾峰彇鍙傛暟鍊�
/// </summary>
- /// <param name="path"></param>
- /// <param name="name"></param>
- /// <returns></returns>
+ /// <param name="path">璺緞</param>
+ /// <param name="name">鍙傛暟鍚�</param>
+ /// <returns>鍙傛暟鍊�</returns>
public static string GetCommonParameterValue(string path, string name)
{
if (!File.Exists(path)) return null;
@@ -26,8 +26,8 @@
/// <summary>
/// 鑾峰彇HMI閲岄厤缃殑鍙傛暟
/// </summary>
- /// <param name="name"></param>
- /// <returns></returns>
+ /// <param name="name">鍙傛暟鍚�</param>
+ /// <returns>鍙傛暟鍊�</returns>
public static string GetCommonParameterValue(string name, out string errMsg)
{
errMsg = string.Empty;
@@ -101,8 +101,10 @@
/// <summary>
/// 灏嗗弬鏁板啓杩汦ngine鐨凷tationGlobals.StationState
/// </summary>
- /// <param name="name"></param>
- /// <returns></returns>
+ /// <param name="xmlPath">缁濆璺緞</param>
+ /// <param name="instance">TestStand涓婁笅鏂�</param>
+ /// <param name="errMsg">寮傚父淇℃伅</param>
+ /// <returns>鏄惁鎴愬姛</returns>
public static bool WriteConfigToContext(string xmlPath, object instance, out string errMsg)
{
errMsg = string.Empty;
diff --git a/SimpleUtil/HMI.Simple.Util/ProductUtil.cs b/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
index aab00f6..a6969e3 100644
--- a/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
+++ b/SimpleUtil/HMI.Simple.Util/ProductUtil.cs
@@ -28,13 +28,20 @@
}
}
+ /// <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 dir = RegUtil.GetLocaltion();
- string path = Path.Combine(dir, "Config", "Product","Parameter", $"Parameter_{model}.data");
+ string path = Path.Combine(dir, "Config", "Product", "Parameter", $"Parameter_{model}.data");
return WriteConfigToContextByPath(path, instance, out errMsg);
}
catch (Exception ex)
@@ -44,6 +51,13 @@
}
}
+ /// <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;
@@ -51,7 +65,7 @@
{
if (!File.Exists(path))
{
- throw new Exception("鏈壘鍒拌閰嶇疆锛岃妫�鏌�");
+ throw new Exception($"鏈壘鍒拌閰嶇疆[{path}]锛岃妫�鏌�");
}
List<ParameterData> datas = XmlHelper.DeserializeFromXml<List<ParameterData>>(path);
foreach (var data in datas)
--
Gitblit v1.9.1