| | |
| | | } |
| | | } |
| | | |
| | | public List<string> groups { get; private set; } |
| | | |
| | | public bool ValidateProductName(object value, out string msg) |
| | | { |
| | | msg = null; |
| | |
| | | } |
| | | 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) |
| | |
| | | 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(); |
| | | } |
| | |
| | | <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> |
| | |
| | | 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(); |
| | | } |
| | | |
| | |
| | | // 修订号 |
| | | // |
| | | [assembly: AssemblyVersion("1.0.0.0")] |
| | | [assembly: AssemblyFileVersion("1.0.0.2")] |
| | | [assembly: AssemblyFileVersion("1.0.0.3")] |
| | |
| | | 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> |
| | |
| | | ProductModelHelper.GetModelBySNR("cc123", out string model, out string msg); |
| | | LangUtil.Load(); |
| | | InitializeComponent(); |
| | | RebuildDb(); |
| | | //page.Children.Add(new UserControl1()); |
| | | } |
| | | |
| | |
| | | |
| | | 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(() => |
| | |
| | | using System.Drawing; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Threading.Tasks; |
| | | using System.Windows; |
| | | using System.Windows.Controls; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | 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) |
| | |
| | | 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>(); |
| | |
| | | { |
| | | using (SqliteHelper helper = new SqliteHelper(file)) |
| | | { |
| | | dt.Merge(helper.GetDataTable(sql)); |
| | | var temp = helper.GetDataTable(sql); |
| | | dt.Merge(temp); |
| | | } |
| | | } |
| | | return BeanUtil.ReadBeanFromDataTable<SerialData>(dt); |
| | |
| | | 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; |
| | | List<SerialData> datas = SelectSerialDataByTime(start, end); |
| | | |
| | | Task.Run(() => |
| | | { |
| | | try |
| | | { |
| | | 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>(); |
| | |
| | | if (snCache.Contains(data.sn)) continue; |
| | | snCache.Add(data.sn); |
| | | all++; |
| | | if (data.status == "Passed") output++; |
| | | 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}])"); |
| | | })); |
| | | } |
| | | 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(() => |
| | | { |
| | | try |
| | | { |
| | | Dispatcher.BeginInvoke(new Action(() => |
| | | { |
| | | webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('加载中,请稍后...')"); |
| | | })); |
| | | List<SerialData> datas = SelectResultDataByTime(start, end); |
| | | |
| | | datas = datas.OrderByDescending(e => e.time).ToList(); |
| | |
| | | res += $"{{name:'{key}',value:{pieData[key]}}},"; |
| | | } |
| | | res += "]"; |
| | | Dispatcher.BeginInvoke(new Action(() => |
| | | { |
| | | webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})"); |
| | | })); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("RefreshChart1 Error.", ex); |
| | | ToastHelper.Error("表2刷新失败!"); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | //private void RefreshChart2(DateTime start, DateTime end) |
| | |
| | | |
| | | private void RefreshChart2(DateTime start, DateTime end) |
| | | { |
| | | try |
| | | { |
| | | dtp20.SelectedDateTime = start; |
| | | dtp21.SelectedDateTime = end; |
| | | Task.Run(() => |
| | | { |
| | | try |
| | | { |
| | | Dispatcher.BeginInvoke(new Action(() => |
| | | { |
| | | webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('加载中,请稍后...')"); |
| | | })); |
| | | List<SerialData> datas = SelectResultDataByTime(start, end); |
| | | |
| | | var groups = |
| | |
| | | }); |
| | | } |
| | | |
| | | |
| | | |
| | | string fields = "[", vals0 = "[", vals1 = "["; |
| | | foreach (var key in res.Keys) |
| | | { |
| | |
| | | vals0 += "]"; |
| | | vals1 += "]"; |
| | | var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']"; |
| | | Dispatcher.BeginInvoke(new Action(() => |
| | | { |
| | | 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(() => |
| | | { |
| | | try |
| | | { |
| | | Dispatcher.BeginInvoke(new Action(() => |
| | | { |
| | | webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('加载中,请稍后...')"); |
| | | })); |
| | | var st = DateTime.Now; |
| | | List<SerialData> datas = SelectSerialDataByTime(start, end); |
| | | |
| | | datas = datas.OrderByDescending(e => e.time).ToList(); |
| | | |
| | | |
| | | 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>(); |
| | |
| | | { |
| | | 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},"; |
| | | } |
| | | |
| | | Dispatcher.BeginInvoke(new Action(() => |
| | | { |
| | | webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])"); |
| | | })); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | log.Error("RefreshChart3 Error.", ex); |
| | | ToastHelper.Error("表4刷新失败!"); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) |
| | |
| | | <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']; |
| | |
| | | .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> |
| | |
| | | } |
| | | ] |
| | | }; |
| | | 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); |
| | |
| | | } |
| | | ] |
| | | }; |
| | | 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); |
| | | } |
| | |
| | | } |
| | | ] |
| | | }; |
| | | 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; |
| | |
| | | } |
| | | ] |
| | | }; |
| | | 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); |
| | |
| | | } |
| | | } |
| | | |
| | | private string tsModelPath; |
| | | private string dataLogPath; |
| | | private SqliteHelper sqliteHelper; |
| | | |
| | |
| | | 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); |
| | | 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, |
| | |
| | | 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 |
| | | public override void InitFinish() |
| | | { |
| | | 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 |
| | | { |
| | | |
| | | } |
| | | |
| | | this.ReadCount(out int pass, out int fail); |
| | | this.DisplayCount(pass, fail); |
| | | InitProducts(); |
| | | ReadConfig(); |
| | | CheckSqlHelper(); |
| | | base.InitFinish(); |
| | | } |
| | | |
| | |
| | | } |
| | | 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)); |
| | |
| | | { |
| | | 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; |
| | |
| | | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | /// <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; |
| | |
| | | /// <summary> |
| | | /// 将参数写进Engine的StationGlobals.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; |
| | |
| | | } |
| | | } |
| | | |
| | | /// <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; |
| | |
| | | } |
| | | } |
| | | |
| | | /// <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; |
| | |
| | | { |
| | | if (!File.Exists(path)) |
| | | { |
| | | throw new Exception("未找到该配置,请检查"); |
| | | throw new Exception($"未找到该配置[{path}],请检查"); |
| | | } |
| | | List<ParameterData> datas = XmlHelper.DeserializeFromXml<List<ParameterData>>(path); |
| | | foreach (var data in datas) |