using HMI.Core.Manager; using HMI.Core.Util; using HMI.UI.Util; using HMI.Util; using Plugin.TestResult_WPF.Constant; using Plugin.TestResult_WPF.Model; using System; using System.Collections.Concurrent; using System.Collections.Generic; 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.TestResult_WPF { /// /// SingleCell.xaml 的交互逻辑 /// 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(ref T old, T @new, [CallerMemberName] string propertyName = null) { old = @new; if (propertyName != null) RaisePropertyChanged(propertyName); } #endregion private InfoWindow window; private int maxSize; private static string dataLogPath; private static int ProbeWarn; static SingleCell() { try { var value = ParameterManager.GetCommonParameterByName("TS_DataLogPath"); dataLogPath = value?.Value ?? Path.Combine(PathHelper.ConfigFolder, "DataBoard"); } catch { dataLogPath = Path.Combine(PathHelper.ConfigFolder, "DataBoard"); } try { var value = ParameterManager.GetCommonParameterByName("ProbeWarn"); ProbeWarn = value != null ? int.Parse(value.Value) : 1000; } catch { ProbeWarn = 1000; } } public SingleCell() { DataContext = this; InitializeComponent(); } private DataTable table; 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; this.probeWarn = ProbeWarn; DataContext = this; InitializeComponent(); LoadProbeCount(); } 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 queue = new ConcurrentQueue(); private List allInfos = new List(); private ObservableCollection _infos = new ObservableCollection(); public ObservableCollection infos { get => _infos; set { RaiseAndSetIfchanged(ref _infos, value); RaisePropertyChanged("tooltipContent"); } } private string countIniPath; /// /// 探针寿命 /// 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); } } public void LoadProbeCount() { string temp = IniFileHelper.ReadIniData($"{title}", "ProbeCount", "", countIniPath); if (!string.IsNullOrEmpty(temp)) { int count = Convert.ToInt32(temp); ProbeCount = count; } } private void UpdateProbeCount(int count) { ProbeCount = count; IniFileHelper.WriteIniData($"{title}", "ProbeCount", ProbeCount.ToString(), countIniPath); if (window != null) window.UpdateProbeCount(ProbeCount); } private void UserControl_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if (window == null) { window = new InfoWindow(title, infos, electricChart, vChart, ProbeCount); 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; } public void SetStatus(string status) { var oldStatus = this.status; this.status = status; if (oldStatus != "testing" && status == "testing") { UpdateProbeCount(ProbeCount + 1); } } public void SetInfos(Info info) { allInfos.Add(info); if (queue.Count >= maxSize) { queue.TryDequeue(out var first); queue.Enqueue(info); this.infos = new ObservableCollection(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); }); } return; } } public void ClearInfo() { allInfos.Clear(); queue = new ConcurrentQueue(); var list = new ObservableCollection(queue); this.infos = list; if (window != null) window.UpdateSource(this.infos); } private Chart electricChart = new Chart("电流曲线(A)", false, 20) { Height = 150 }; public void AddElectricData(double data) { electricChart.AddData(data); } public void ClearElectricData() { electricChart.Clear(); } private Chart vChart = new Chart("电压曲线(V)", false, 20) { Height = 150 }; public void AddVData(double data) { vChart.AddData(data); } public void ClearVData() { vChart.Clear(); } public void SaveElectricDataToCSV(string filePath) { try { List datas = electricChart?.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 = "电流数据(A)"; 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 datas = vChart?.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 = "电压数据(V)"; 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()); } } /// /// 保存测试数据到CSV /// /// public void SaveInfoToCSV(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 = "测试项,测试值,下限,上限,单位,结果,测试时间"; 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) { ViewControl.Logger.Error($"Cell[{title}] SaveInfoToCSV Error.", ex); } } private SqliteHelper CheckSqlHelper() { string today = DateTime.Now.ToString("yyyyMMdd"); string dbPath = Path.Combine(dataLogPath, $"Data_{today}.db"); if (!File.Exists(dbPath)) { SqliteHelper.CreateDatabase(dbPath); } var 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, offset TEXT, value TEXT, status TEXT, finalStatus TEXT, consumeTime TEXT, totalConsumeTime TEXT, time DATETIME NOT NULL);"); 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);"); return sqliteHelper; } /// /// 保存测试数据到Sqlite /// /// public void SaveInfoToDB() { try { using (var helper = CheckSqlHelper()) { List sqls = new List(); 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) { ViewControl.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; default: break; } } } }