using HMI.Core.Util; using HMI.UI.Util; using HMI.Util; using Plugin.TestResult; using Plugin.TestResult_WPF.Model; using Plugin.TestResult_WPF.Util; using SuperSocket.SocketBase.Protocol; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; namespace Plugin.TestResult_WPF { /// /// DataTable.xaml 的交互逻辑 /// 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(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 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); } } private static CommonCodeParser codeParser = new CommonCodeParser(); private readonly int index; private readonly int cellCount; private readonly string chartTitle; private readonly TestResultView parent; private BaseConfig config; private Chart chart; private Chart multiChart; private SingleCell[] cells; private TcpServer tcpServer; private string CountIniPath; // 平均温度 public List tempratures = new List(); public Dictionary> detailTempratures = new Dictionary>(); 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 = config.MainChartTitle; DataContext = this; InitializeComponent(); mainGrid.Columns = config.PositionColumn; this.chart = new Chart(this.chartTitle, false, config.MaxSize, config.RefreshInterval); this.multiChart = new Chart(config.DetailChartTitle, true, config.MaxSize, config.RefreshInterval) { 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 cell = new SingleCell(title, i, config.CellListMaxSize, countIniPath); mainGrid.Children.Add(cell); cells[i] = cell; } ReadCount(); } 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.AddData(t); } public void SetTemperature(string name, double t) { List list; if (detailTempratures.ContainsKey(name)) { list = detailTempratures[name]; } else { list = new List(); detailTempratures.Add(name, list); } list.Add(t); multiChart.AddData(name, t); } public void SetStatus(string status) { infoTable.status = status; } 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 SetConsumeTime(double consumeTime) { infoTable.consumeTime = consumeTime; } 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) { ClearChartData(); parent.SetStartFlag(this.index, true); } private void ScanWindow_Click(object sender, RoutedEventArgs e) { if (scanner != null) { scanner.Activate(); } else { scanner = new Scanner(this.lang("Tr.ScanTitle", title)) { Tag = title }; scanner.FinishBarcode += Scanner_FinishBarcode; scanner.Closed += Scanner_Closed; scanner.Show(); } } private void Scanner_Closed(object sender, EventArgs e) { scanner = null; } private void Scanner_FinishBarcode(object sender, BarcodeEventArg e) { if (parent.SequenceContext == null) return; CellInfo cellInfo = codeParser.GetCellInfoByCode(e.positionCode); string paramName = $"StationState.StartScanner_{title}"; parent.engine.Globals.SetValBoolean(paramName, 0, true); string positionCode = e.positionCode, snrCode = e.snrCode; //TODO 需要增加条码校验功能 //将读到的条码写入到SN中 int dutNo = Convert.ToInt16(positionCode.Split('-')[2]) - 1; dutNo = this.index * this.cellCount + dutNo; string LookupStr = $"StationState.SN[{dutNo}]"; ViewControl.Logger.Info($"PositionCode: [{e.positionCode}], SNR: [{e.snrCode}], LookUpStr: [{LookupStr}]"); parent.engine.Globals.SetValString(LookupStr, 0, snrCode); parent.engine.CommitGlobalsToDisk(promptOnSaveConflicts: false); string code = parent.engine.Globals.GetValString(LookupStr, 0); parent.nameTables[cellInfo.OvenName].GetSingleCell(cellInfo.Index).SetStatus("hadCode"); } /// /// 清空两个图表数据 /// public void ClearChartData() { chart.Clear(); multiChart.Clear(); tempratures.Clear(); detailTempratures.Clear(); } /// /// 启动Tcp服务器 /// private void StartTcpServer() { try { if (tcpServer == null) { tcpServer = new TcpServer(); tcpServer.NewRequestReceived += TcpServer_NewRequestReceived; if (!tcpServer.Setup(config.PortStart + index)) { 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(config.PortStart + index)) { 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; } } /// /// 更新Tcp服务器状态 /// /// /// private void ChangeTcpServerStatus(string status, string info) { Dispatcher.Invoke(() => { TcpServerStatus = status; TcpServerInfo = info; }); } /// /// 停止Tcp服务器 /// private void StopTcpServer() { try { tcpServer?.Stop(); tcpServer = null; } catch (Exception ex) { } } /// /// 释放资源 /// public void RelaseResource() { StopTcpServer(); } /// /// Tcp消息处理 /// /// /// private void TcpServer_NewRequestReceived(TcpSession session, StringRequestInfo requestInfo) { string msg = requestInfo.Body; ViewControl.Logger.Info($"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(','); //string step = datas_10015[2]; //string result = datas_10015[3]; GetSingleCell(cellIndex).SetInfos(new Info { step = values[0], value = values[1], result = values[2], range = values[3], condition = values[4], updateTime = values[5] }); //session.Send("1"); } public void RefreshCount(int ok, int ng) { infoTable.UpdateNumber(infoTable.okCount + ok, infoTable.ngCount + ng); IniFileHelper.WriteIniData($"Oven_{index}", "Pass", infoTable.okCount.ToString(), this.CountIniPath); IniFileHelper.WriteIniData($"Oven_{index}", "Fail", infoTable.ngCount.ToString(), this.CountIniPath); } /// /// 读取保存的数据 /// 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 } } /// /// 计数清零 /// 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) + ",平均值"; 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 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, ""); } } public void ClearElectricData() { foreach (var cell in cells) { cell.ClearElectricData(); } } private void Button_Click_1(object sender, RoutedEventArgs e) { ScannerSetting setting = new ScannerSetting() { Owner = Window.GetWindow(this) }; setting.Open(true, this.title); } private void ClearAllSnr_Click(object sender, RoutedEventArgs e) { if (MsgBoxHelper.WarnMessage(Window.GetWindow(this), LangUtil.Get("Tr.MakeSureClearAllSNR")) == MessageBoxResult.OK) { try { for (int i = 0; i < this.cellCount; i++) { int dutNo = this.index * this.cellCount + i; string LookupStr = $"StationState.SN[{dutNo}]"; parent.engine.Globals.SetValString(LookupStr, 0, ""); GetSingleCell(i).SetStatus("waiting"); } ToastHelper.Success(LangUtil.Get("App.DeleteSuccess")); } catch (Exception ex) { ViewControl.Logger.Error("ClearAllSnr_Click Error.", ex); MsgBoxHelper.Error(Window.GetWindow(this), ex.Message); } } } } }