| | |
| | | using HMI.Core.Manager; |
| | | using HMI.Core.Setting; |
| | | using HMI.Core.Util; |
| | | using HMI.UI.Util; |
| | | using HMI.Util; |
| | | using PLCHelper; |
| | | using Plugin.TestResult; |
| | | using Plugin.TestResult.Util; |
| | | using Plugin.TestResult_WPF.Constant; |
| | | using Plugin.TestResult_WPF.Model; |
| | |
| | | using System.Collections.Generic; |
| | | using System.Collections.ObjectModel; |
| | | using System.ComponentModel; |
| | | using System.Dynamic; |
| | | using System.IO; |
| | | using System.Runtime.CompilerServices; |
| | | using System.Windows; |
| | |
| | | private InfoWindow window; |
| | | private int maxSize; |
| | | |
| | | private DataTable table; |
| | | public DataTable table { get; private set; } |
| | | |
| | | public SingleCell(DataTable table, string title, int index, int maxSize, string iniFile) |
| | | { |
| | |
| | | |
| | | public void SetStatus(string status) |
| | | { |
| | | var oldStatus = this.status; |
| | | this.status = status; |
| | | if (oldStatus != "testing" && status == "testing") |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | UpdateProbeCount(ProbeCount + 1); |
| | | var now = DateTime.Now; |
| | | string dateStr = now.ToString("yyyyMMdd"); |
| | | visualTestId = $"{title}_{now.ToString("yyyyMMddHHmmssfff")}"; |
| | | helper = CheckSqlHelper(dateStr); |
| | | } |
| | | var oldStatus = this.status; |
| | | this.status = status; |
| | | 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(); |
| | | } |
| | | |
| | | if (oldStatus != "ok" && status == "ok") |
| | | { |
| | | SaveInfoToDB(); |
| | | } |
| | | if (oldStatus != "ok" && status == "ok") |
| | | { |
| | | SaveInfoToDB(); |
| | | } |
| | | |
| | | if (oldStatus != "ng" && status == "ng") |
| | | if (oldStatus != "ng" && status == "ng") |
| | | { |
| | | SaveInfoToDB(); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private void InsertARecourd() |
| | | { |
| | | try |
| | | { |
| | | SaveInfoToDB(); |
| | | 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) |
| | | { |
| | | ViewControl.Logger.Error($"Cell[{title}] SaveToDB 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}"; |
| | | //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) |
| | | { |
| | | } |
| | | // CSVPrinter.Print(dir, fileName, title, line); |
| | | // // ReverseCSV(Path.Combine(dir, fileName)); |
| | | //} |
| | | //catch (Exception ex) |
| | | //{ |
| | | //} |
| | | } |
| | | |
| | | public void SendToChart(Info info) |
| | |
| | | allInfos.Add(info); |
| | | SendToChart(info); |
| | | WriteCSV(info); |
| | | if (queue.Count >= maxSize) |
| | | |
| | | /// 目前先不限制数量,后续如果数据过多导致性能问题再考虑限制数量 |
| | | //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) |
| | | { |
| | | queue.TryDequeue(out var first); |
| | | queue.Enqueue(info); |
| | | this.infos = new ObservableCollection<Info>(queue); |
| | | if (window != null) window.UpdateSource(this.infos); |
| | | window.Dispatcher.Invoke(() => |
| | | { |
| | | this.infos.Add(info); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | queue.Enqueue(info); |
| | | if (window != null) |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | window.Dispatcher.Invoke(() => |
| | | { |
| | | this.infos.Add(info); |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | Dispatcher.Invoke(() => |
| | | { |
| | | this.infos.Add(info); |
| | | }); |
| | | } |
| | | this.infos.Add(info); |
| | | }); |
| | | } |
| | | |
| | | Dispatcher.Invoke(() => |
| | |
| | | } |
| | | } |
| | | |
| | | private void NormalCSV(string filePath) |
| | | public void NormalCSV(string filePath) |
| | | { |
| | | try |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | private void ReverseCSV(string filePath) |
| | | public void ReverseCSV_Bak(string filePath) |
| | | { |
| | | try |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | 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) |
| | | { |
| | | ViewControl.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 保存测试数据到CSV |
| | | /// </summary> |
| | |
| | | { |
| | | try |
| | | { |
| | | string model = table?.CbProduct?.SelectedItem?.ToString(); |
| | | var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); |
| | | var sql = $"INSERT INTO testResult (sn,station,position,result,time,resultId) VALUES ('{sn}','','{title}','{this.status}','{timestr}','{visualTestId}');"; |
| | | //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; |
| | |
| | | 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 |
| | |
| | | }; |
| | | if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) |
| | | { |
| | | this.SaveInfoToCSV(sfd.FileName); |
| | | this.NormalCSV(sfd.FileName); |
| | | } |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |