using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Linq; using System.Windows.Forms; using System.IO; using DevExpress.XtraWaitForm; using DevExpress.XtraSplashScreen; using DevExpress.XtraCharts; using System.Data.SQLite; using LFP_Manager.DataStructure; using LFP_Manager.Function; using LFP_Manager.Utils; namespace LFP_Manager.Controls { public partial class ucHistroy : DevExpress.XtraEditors.XtraUserControl { #region VARIABLES CommConfig Config; DataTable dtHistory; Series seriesVolt; Series seriesCurr; Series seriesTemp; Series seriesSoc; LineSeriesView currLineView; LineSeriesView tempLineView; LineSeriesView socLineView; SecondaryAxisY currAxisY; SecondaryAxisY tempAxisY; SecondaryAxisY socAxisY; #endregion #region CONSTRUCTOR public ucHistroy() { InitializeComponent(); dtHistory = new DataTable(); InitChart(); gridSearchResult.CellFormatting += gridSearchResult_CellFormatting; } public void SetCommCofig(CommConfig aConfig) { Config = aConfig; } private void InitChart() { chartVI.Series.Clear(); chartVI.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False; if (chartVI.Titles.Count > 0) chartVI.Titles[0].Visibility = DevExpress.Utils.DefaultBoolean.False; //-------------------- Series Volt -----------------------// seriesVolt = new Series(String.Format("Volt"), ViewType.Line) { DataSource = dtHistory, CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}V", // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "create_date", ValueScaleType = ScaleType.Numerical, }; seriesVolt.ValueDataMembers.AddRange(new string[] { String.Format("module_voltage") }); chartVI.Series.Add(seriesVolt); //-------------------- Series Current -----------------------// seriesCurr = new Series(String.Format("Curr"), ViewType.Line) { DataSource = dtHistory, CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}A", // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "create_date", ValueScaleType = ScaleType.Numerical, }; seriesCurr.ValueDataMembers.AddRange(new string[] { String.Format("module_current") }); chartVI.Series.Add(seriesCurr); //-------------------- Series Temperature -----------------------// seriesTemp = new Series(String.Format("Temp"), ViewType.Line) { DataSource = dtHistory, CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}C", // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "create_date", ValueScaleType = ScaleType.Numerical, }; seriesTemp.ValueDataMembers.AddRange(new string[] { String.Format("temperature_01") }); chartVI.Series.Add(seriesTemp); //-------------------- Series SOC -----------------------// seriesSoc = new Series(String.Format("SOC"), ViewType.Line) { DataSource = dtHistory, CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}%", // Specify data members to bind the series. ValueScaleType = ScaleType.Numerical, ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "create_date", }; seriesSoc.ValueDataMembers.AddRange(new string[] { String.Format("module_soc") }); chartVI.Series.Add(seriesSoc); XYDiagram diagram = (XYDiagram)chartVI.Diagram; diagram.AxisX.DateTimeScaleOptions.AggregateFunction = AggregateFunction.Sum; diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Second; diagram.AxisX.VisualRange.Auto = true; diagram.AxisX.VisualRange.AutoSideMargins = false; diagram.AxisX.VisualRange.SideMarginsValue = 0; diagram.AxisX.VisualRange.StartSideMargin = 0; diagram.AxisX.VisualRange.EndSideMargin = 0; diagram.AxisX.Title.Text = "Date Time (hh:mm:ss)"; diagram.AxisX.Title.Visibility = DevExpress.Utils.DefaultBoolean.False; diagram.AxisX.Title.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular); diagram.AxisX.Label.TextPattern = "{A:HH:mm:ss}"; // Axis Y - Voltage diagram.AxisY.VisualRange.Auto = false; diagram.AxisY.VisualRange.AutoSideMargins = false; diagram.AxisY.VisualRange.StartSideMargin = 0; diagram.AxisY.VisualRange.EndSideMargin = 0; diagram.AxisY.VisualRange.MaxValue = 60.0; diagram.AxisY.VisualRange.MinValue = 40.0; diagram.AxisY.WholeRange.MaxValue = 60.0; diagram.AxisY.WholeRange.MinValue = 40.0; diagram.AxisY.Title.Text = "Voltage (V)"; diagram.AxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True; diagram.AxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); chartVI.Diagram.Assign(diagram); // Axis Y - Current currAxisY = new SecondaryAxisY("Current Y-Axis"); ((XYDiagram)chartVI.Diagram).SecondaryAxesY.Add(currAxisY); currAxisY.VisualRange.Auto = false; currAxisY.VisualRange.AutoSideMargins = false; currAxisY.VisualRange.StartSideMargin = 0; currAxisY.VisualRange.EndSideMargin = 0; currAxisY.VisualRange.MaxValue = 300.0; currAxisY.VisualRange.MinValue = -300.0; currAxisY.WholeRange.MaxValue = 300.0; currAxisY.WholeRange.MinValue = -300.0; currAxisY.Visibility = DevExpress.Utils.DefaultBoolean.True; currAxisY.Title.Text = "Current (A)"; currAxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); currAxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True; currLineView = new LineSeriesView(); currLineView = (LineSeriesView)seriesCurr.View; currLineView.AxisY = currAxisY; currLineView.LineMarkerOptions.BorderVisible = false; currLineView.LineMarkerOptions.Color = Color.Red; currLineView.LineStyle.Thickness = 2; currLineView.MarkerVisibility = DevExpress.Utils.DefaultBoolean.False; currLineView.Shadow.Visible = false; // Axis Y - Temperature tempAxisY = new SecondaryAxisY("Temperature Y-Axis"); ((XYDiagram)chartVI.Diagram).SecondaryAxesY.Add(tempAxisY); tempAxisY.VisualRange.Auto = false; tempAxisY.VisualRange.AutoSideMargins = false; tempAxisY.VisualRange.StartSideMargin = 0; tempAxisY.VisualRange.EndSideMargin = 0; tempAxisY.VisualRange.MaxValue = 80.0; tempAxisY.VisualRange.MinValue = -30.0; tempAxisY.WholeRange.MaxValue = 80.0; tempAxisY.WholeRange.MinValue = -30.0; tempAxisY.Visibility = DevExpress.Utils.DefaultBoolean.True; tempAxisY.Title.Text = "Temperature (C)"; tempAxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); tempAxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True; tempLineView = new LineSeriesView(); tempLineView = (LineSeriesView)seriesTemp.View; tempLineView.AxisY = tempAxisY; tempLineView.LineMarkerOptions.BorderVisible = false; tempLineView.LineMarkerOptions.Color = Color.Red; tempLineView.LineStyle.Thickness = 2; tempLineView.MarkerVisibility = DevExpress.Utils.DefaultBoolean.False; tempLineView.Shadow.Visible = false; // Axis Y - SOC socAxisY = new SecondaryAxisY("SOC Y-Axis"); ((XYDiagram)chartVI.Diagram).SecondaryAxesY.Add(socAxisY); socAxisY.VisualRange.Auto = false; socAxisY.VisualRange.AutoSideMargins = false; socAxisY.VisualRange.StartSideMargin = 0; socAxisY.VisualRange.EndSideMargin = 0; socAxisY.VisualRange.MaxValue = 105.0; socAxisY.VisualRange.MinValue = -5.0; socAxisY.WholeRange.MaxValue = 105; socAxisY.WholeRange.MinValue = -5.0; socAxisY.Visibility = DevExpress.Utils.DefaultBoolean.True; socAxisY.Title.Text = "SOC (%)"; socAxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); socAxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.True; socLineView = new LineSeriesView(); socLineView = (LineSeriesView)seriesSoc.View; socLineView.AxisY = socAxisY; socLineView.LineMarkerOptions.BorderVisible = false; socLineView.LineMarkerOptions.Color = Color.Red; socLineView.LineStyle.Thickness = 2; socLineView.MarkerVisibility = DevExpress.Utils.DefaultBoolean.False; socLineView.Shadow.Visible = false; } #endregion #region UPDATE DATA private void UpdateChart(DataTable dt) { chartVI.Series.Clear(); InitChart(); } #endregion #region SQL QUARY EXCUTE private void quaryExcute(string quary) { string dbFilename = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + csDbConstData.DataBase.FileName; // Open database string strConn = @"Data Source=" + dbFilename; using (var connection = new SQLiteConnection(strConn)) { connection.Open(); try { DataTable aT = new DataTable(); DbWaitForm.ShowWaitForm(); csDbUtils.BeginTran(connection); // Update data using (SQLiteCommand command = connection.CreateCommand()) { //sSQL = "insert into TrendTable ( TrendStamp, TagName, TagValue) Values ( " + IntToStr(stamp) + "," + name + "," + value + ");"; command.CommandText = quary; try { SQLiteDataReader reader = command.ExecuteReader(); aT.Load(reader); } catch (Exception) { } } csDbUtils.CommitTran(connection); dtHistory = aT; //RealGridView.DataSource = dt; DbWaitForm.CloseWaitForm(); } catch (Exception ex) { MessageBox.Show(ex.Message, "Result", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { connection.Close(); } } } #endregion #region BUTTON EVENT private void btnSearch_Click(object sender, EventArgs e) { DateTime start = dtpStart.Value; DateTime mid; DateTime end = dtpEnd.Value; TimeSpan span = end - start; int sDay = start.DayOfYear; int eDay = end.DayOfYear; dtHistory.Clear(); int total_days = eDay - sDay; DataTable[] dDt = new DataTable[total_days + 1]; string quary = ""; try { if (total_days == 0) { quary = String.Format(" where create_date > '{0:yyyy-MM-dd HH:mm:ss}'", start); quary += String.Format(" and create_date < '{0:yyyy-MM-dd HH:mm:ss}'", end); dDt[0] = csDbUtils.BmsDataSelectToDataTable(Config, start, quary); if (dDt[0] == null) MessageBox.Show("No data", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); else { dtHistory = dDt[0]; dtHistory.TableName = "THistory"; gridSearchResult.DataSource = dtHistory; //gridSearchResult.(); } } else { DataTable bDt = new DataTable(); for (int i = 0; i < (total_days + 1); i++) { //dDt[i] = new DataTable(); if (i == 0) { quary = String.Format(" where create_date > '{0:yyyy-MM-dd HH:mm:ss}'", start); dDt[i] = csDbUtils.BmsDataSelectToDataTable(Config, start, quary); } else if (i == total_days) { quary = String.Format(" where create_date < '{0:yyyy-MM-dd HH:mm:ss}'", end); dDt[i] = csDbUtils.BmsDataSelectToDataTable(Config, end, quary); } else { quary = ""; mid = start.AddDays(i); dDt[i] = csDbUtils.BmsDataSelectToDataTable(Config, mid, quary); } if (dDt[i] != null) bDt.Merge(dDt[i]); } if (bDt == null) MessageBox.Show("No data", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); else { dtHistory = bDt; dtHistory.TableName = String.Format("THistory_{0:yyMMdd_HHmmss}", DateTime.Now); gridSearchResult.DataSource = dtHistory; UpdateChart(dtHistory); //gridSearchResult.(); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void btnExportExcel_Click(object sender, EventArgs e) { SaveFileDialog sDialog = new SaveFileDialog(); sDialog.Title = "Select save file"; sDialog.DefaultExt = "xlsx"; sDialog.Filter = "Excel files 2003 (*.xls)|*.xls|All files (*.*)|*.*"; if (sDialog.ShowDialog() == DialogResult.OK) { string filename = sDialog.FileName; try { csExcelExport.ExportToExcelExt(dtHistory, filename); MessageBox.Show("Complete Export Excel File", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } #endregion #region GRID FORMATTING private void gridSearchResult_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.Value == null || e.Value == DBNull.Value || e.RowIndex < 0) return; string colName = gridSearchResult.Columns[e.ColumnIndex].Name; if (colName == "op_status") { if (short.TryParse(e.Value.ToString(), out short val)) { e.Value = GetOpStatusDisplayText(val); e.FormattingApplied = true; } } else if (colName == "alarm_status") { if (short.TryParse(e.Value.ToString(), out short val)) { e.Value = GetAlarmStatusDisplayText(val); e.FormattingApplied = true; } } else if (colName == "warning") { if (short.TryParse(e.Value.ToString(), out short val)) { e.Value = GetWarningDisplayText(val); e.FormattingApplied = true; } } else if (colName == "fault") { if (short.TryParse(e.Value.ToString(), out short val)) { e.Value = GetFaultDisplayText(val); e.FormattingApplied = true; } } else if (colName == "error_code") { if (short.TryParse(e.Value.ToString(), out short val)) { e.Value = GetErrorCodeDisplayText(val); e.FormattingApplied = true; } } } private string GetOpStatusDisplayText(short val) { switch ((ushort)val) { case 0x0000: return "STANDBY (0x0000)"; case 0x0001: return "CHARGING (0x0001)"; case 0x0002: return "DISCHARGING (0x0002)"; case 0x0003: return "FLOATING (0x0003)"; case 0x0004: return "TRIP (0x0004)"; case 0x0008: return "CHG-LIMIT (0x0008)"; case 0x0032: return "POWER-ON (0x0032)"; case 0x8000: return "STANDBY-HEAT (0x8000)"; case 0x8001: return "CHARGING-HEAT (0x8001)"; case 0x8002: return "DISCHARGING-HEAT (0x8002)"; case 0x8004: return "TRIP-HEAT (0x8004)"; case 0x8008: return "CHG-LIMIT-HEAT (0x8008)"; default: return string.Format("UNKNOWN (0x{0:X4})", (ushort)val); } } private string GetAlarmStatusDisplayText(short val) { switch (val) { case 0: return "NORMAL (0)"; case 1: return "WARNING (1)"; case 2: return "FAULT (2)"; case 3: return "WARMING UP (3)"; default: return string.Format("UNKNOWN ({0})", val); } } private string GetWarningDisplayText(short val) { if (val == 0) return "0x0000"; List list = new List(); bool[] b = csUtils.Int16ToBitArray(val); if (b[0]) list.Add("HighTemp"); if (b[1]) list.Add("LowTemp"); if (b[2]) list.Add("PackOV"); if (b[3]) list.Add("PackUV"); if (b[4]) list.Add("CellOV"); if (b[5]) list.Add("CellUV"); if (b[6]) list.Add("ChaOC"); if (b[7]) list.Add("DchOC"); if (b[8]) list.Add("PcbHighTemp"); if (b[9]) list.Add("CvDiff"); if (b[11]) list.Add("LowSOC"); string str = list.Count > 0 ? string.Join(", ", list) : ""; return string.IsNullOrEmpty(str) ? string.Format("0x{0:X4}", (ushort)val) : string.Format("0x{0:X4} ({1})", (ushort)val, str); } private string GetFaultDisplayText(short val) { if (val == 0) return "0x0000"; List list = new List(); bool[] b = csUtils.Int16ToBitArray(val); if (b[0]) list.Add("HighTemp"); if (b[1]) list.Add("LowTemp"); if (b[2]) list.Add("PackOV"); if (b[3]) list.Add("PackUV"); if (b[4]) list.Add("CellOV"); if (b[5]) list.Add("CellUV"); if (b[6]) list.Add("ChaOC"); if (b[7]) list.Add("DchOC"); if (b[8]) list.Add("PcbHighTemp"); if (b[9]) list.Add("ShortCircuit"); string str = list.Count > 0 ? string.Join(", ", list) : ""; return string.IsNullOrEmpty(str) ? string.Format("0x{0:X4}", (ushort)val) : string.Format("0x{0:X4} ({1})", (ushort)val, str); } private string GetErrorCodeDisplayText(short val) { if (val == 0) return "0x0000"; List list = new List(); bool[] b = csUtils.Int16ToBitArray(val); if (b[0]) list.Add("VoltError"); if (b[1]) list.Add("TempError"); if (b[2]) list.Add("CurrCheckError"); if (b[3]) list.Add("CellUnbalance"); if (b[14]) list.Add("AntiTheftGyro"); string str = list.Count > 0 ? string.Join(", ", list) : ""; return string.IsNullOrEmpty(str) ? string.Format("0x{0:X4}", (ushort)val) : string.Format("0x{0:X4} ({1})", (ushort)val, str); } #endregion } }