using DevExpress.XtraCharts; using LFP_Manager.DataStructure; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Threading; namespace LFP_Manager.Controls { public partial class ucMainStatus : DevExpress.XtraEditors.XtraUserControl { private delegate void CanIJust(); private List _valueList; private Thread _thread; private CanIJust _doIt; private Random _ran; private int _interval; private CommConfig Config; private DeviceSystemData SystemData; private DataTable dtVI; private DateTime OldTime; Series seriesVolt; Series seriesCurr; Series seriesTemp; Series seriesSoc; LineSeriesView currLineView; LineSeriesView tempLineView; LineSeriesView socLineView; SecondaryAxisY currAxisY; SecondaryAxisY tempAxisY; SecondaryAxisY socAxisY; private double TotalVoltage; private double TotalCurrent; private double TotalTemperature; private double TotalSoc; private bool active = false; private bool ThreadEnd = false; private int logTimeSec = 5; public ucMainStatus() { InitializeComponent(); InitDataTableVolt(); InitChart(); } public void SimStart() { _valueList = new List(); _ran = new Random(); _interval = 500; GoBoy(); } private void GoBoy() { _doIt += new CanIJust(AddData); _thread = new Thread(new ThreadStart(ComeOnYouThread)); _thread.Start(); } public void Start(CommConfig aConfig, ref DeviceSystemData aSystemData) { Config = aConfig; SystemData = aSystemData; reloadChart(); _interval = 200; _doIt += new CanIJust(AddData); ThreadEnd = false; _thread = new Thread(new ThreadStart(ComeOnYouThread)); _thread.Start(); active = true; tmrDisplay.Start(); } public void Stop() { active = false; tmrDisplay.Stop(); ThreadEnd = true; if (_thread != null) { if (_thread.IsAlive) _thread.Abort(); } } public void UpdateData(ref DeviceSystemData aSystemData) { if (active) { SystemData = aSystemData; TotalVoltage = (double)SystemData.ValueData.voltageOfPack / 10; TotalCurrent = (double)SystemData.ValueData.current / 10; TotalSoc = (double)SystemData.ValueData.rSOC / 10; TotalTemperature = (double)SystemData.AvgData.maxTemp / 10; } } private void InitDataTableVolt() { dtVI = new DataTable(); dtVI.Columns.Add("DateTime", typeof(DateTime)); dtVI.Columns.Add(String.Format("Volt"), typeof(double)); dtVI.Columns.Add(String.Format("Curr"), typeof(double)); dtVI.Columns.Add(String.Format("Temp"), typeof(double)); dtVI.Columns.Add(String.Format("SOC"), typeof(double)); // Add data rows to the table. DataRow row = null; row = dtVI.NewRow(); row["DateTime"] = DateTime.Now; row[String.Format("Volt")] = 0; row[String.Format("Curr")] = 0; row[String.Format("Temp")] = 0; row[String.Format("SOC")] = 0; dtVI.Rows.Add(row); } private void InitChart() { chartVI.Series.Clear(); chartVI.Legend.Visibility = DevExpress.Utils.DefaultBoolean.False; chartVI.Titles[0].Visibility = DevExpress.Utils.DefaultBoolean.False; //-------------------- Series VOLT -----------------------// seriesVolt = new Series(String.Format("Volt"), ViewType.Line) { DataSource = dtVI, //seriesVolt.Label.PointOptions.PointView = PointView.Values; //seriesVolt.Label.PointOptions.ValueNumericOptions.Format = NumericFormat.Number; //seriesVolt.Label.PointOptions.ValueNumericOptions.Precision = 1; CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}V", //seriesVolt.CrosshairLabelPattern = "{S} {A:hh:mm:ss} : {V:F1}V"; // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "DateTime", ValueScaleType = ScaleType.Numerical }; seriesVolt.ValueDataMembers.AddRange(new string[] { String.Format("Volt") }); chartVI.Series.Add(seriesVolt); //-------------------- Series CURR -----------------------// seriesCurr = new Series(String.Format("Curr"), ViewType.Line) { DataSource = dtVI, //seriesCurr.Label.PointOptions.PointView = PointView.Values; //seriesCurr.Label.PointOptions.ValueNumericOptions.Format = NumericFormat.Number; //seriesCurr.Label.PointOptions.ValueNumericOptions.Precision = 1; CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}A", //seriesCurr.CrosshairLabelPattern = "{S} {A:hh:mm:ss} : {V:F1}A"; // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "DateTime", ValueScaleType = ScaleType.Numerical }; seriesCurr.ValueDataMembers.AddRange(new string[] { String.Format("Curr") }); chartVI.Series.Add(seriesCurr); //-------------------- Series TEMP -----------------------// seriesTemp = new Series(String.Format("Temp"), ViewType.Line) { DataSource = dtVI, //seriesTemp.Label.PointOptions.PointView = PointView.Values; //seriesTemp.Label.PointOptions.ValueNumericOptions.Format = NumericFormat.Number; //seriesTemp.Label.PointOptions.ValueNumericOptions.Precision = 1; CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}C", //seriesTemp.CrosshairLabelPattern = "{S} {A:hh:mm:ss} : {V:F1}A"; // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "DateTime", ValueScaleType = ScaleType.Numerical }; seriesTemp.ValueDataMembers.AddRange(new string[] { String.Format("Temp") }); chartVI.Series.Add(seriesTemp); //-------------------- Series SOC -----------------------// seriesSoc = new Series(String.Format("SOC"), ViewType.Line) { DataSource = dtVI, //seriesSoc.Label.PointOptions.PointView = PointView.Values; //seriesSoc.Label.PointOptions.ValueNumericOptions.Format = NumericFormat.Number; //seriesSoc.Label.PointOptions.ValueNumericOptions.Precision = 1; CrosshairLabelVisibility = DevExpress.Utils.DefaultBoolean.True, CrosshairLabelPattern = "{S} : {V:F1}%", //seriesTemp.CrosshairLabelPattern = "{S} {A:hh:mm:ss} : {V:F1}A"; // Specify data members to bind the series. ArgumentScaleType = ScaleType.DateTime, ArgumentDataMember = "DateTime", ValueScaleType = ScaleType.Numerical }; seriesSoc.ValueDataMembers.AddRange(new string[] { String.Format("SOC") }); chartVI.Series.Add(seriesSoc); XYDiagram diagram = (XYDiagram)chartVI.Diagram; //diagram.AxisX.DateTimeScaleOptions.AggregateFunction = AggregateFunction.Sum; //diagram.AxisX.DateTimeScaleOptions.GridAlignment = DateTimeGridAlignment.Minute; //diagram.AxisX.DateTimeScaleOptions.MeasureUnit = DateTimeMeasureUnit.Second; 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.DateTimeOptions.Format = DevExpress.XtraCharts.DateTimeFormat.Custom; //diagram.AxisX.Label.DateTimeOptions.FormatString = "HH:mm:ss"; diagram.AxisY.WholeRange.MaxValue = 60.0; diagram.AxisY.WholeRange.MinValue = 40.0; diagram.AxisY.WholeRange.Auto = false; diagram.AxisY.WholeRange.AlwaysShowZeroLevel = true; diagram.AxisY.VisualRange.MaxValue = 60.0; diagram.AxisY.VisualRange.MinValue = 40.0; diagram.AxisY.VisualRange.Auto = false; //diagram.AxisY.GridSpacing = 1; diagram.AxisY.Title.Text = "Voltage (V)"; diagram.AxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.False; diagram.AxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); chartVI.Diagram.Assign(diagram); currAxisY = new SecondaryAxisY("Current Y-Axis"); ((XYDiagram)chartVI.Diagram).SecondaryAxesY.Add(currAxisY); //currAxisY.GridSpacing = 10D; //currAxisY.GridSpacingAuto = false; currAxisY.WholeRange.MinValue = "-300"; currAxisY.WholeRange.MaxValue = "300"; currAxisY.WholeRange.Auto = false; currAxisY.WholeRange.AlwaysShowZeroLevel = true; currAxisY.Visibility = DevExpress.Utils.DefaultBoolean.False; currAxisY.Title.Text = "Current (A)"; currAxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); currAxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.False; 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; tempAxisY = new SecondaryAxisY("Temperature Y-Axis"); ((XYDiagram)chartVI.Diagram).SecondaryAxesY.Add(tempAxisY); //tempAxisY.GridSpacing = 5D; //tempAxisY.GridSpacingAuto = false; tempAxisY.WholeRange.MinValue = "-25.0"; tempAxisY.WholeRange.MaxValue = "80.0"; tempAxisY.WholeRange.Auto = false; tempAxisY.WholeRange.AlwaysShowZeroLevel = true; tempAxisY.Visibility = DevExpress.Utils.DefaultBoolean.False; tempAxisY.Title.Text = "Temperature (C)"; tempAxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); tempAxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.False; 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; // SOC AxisY socAxisY = new SecondaryAxisY("SOC Y-Axis"); ((XYDiagram)chartVI.Diagram).SecondaryAxesY.Add(socAxisY); //socAxisY.GridSpacing = 10D; //socAxisY.GridSpacingAuto = false; socAxisY.WholeRange.MinValue = "-2.0"; socAxisY.WholeRange.MaxValue = "102.0"; socAxisY.WholeRange.Auto = false; socAxisY.WholeRange.AlwaysShowZeroLevel = true; socAxisY.Visibility = DevExpress.Utils.DefaultBoolean.False; socAxisY.Title.Text = "SOC (%)"; socAxisY.Title.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Regular); socAxisY.Title.Visibility = DevExpress.Utils.DefaultBoolean.False; 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; } private void reloadChart() { chartVI.Series.Clear(); //for (int i = 0; i < mQty; i++) //{ chartVI.Series.Add(seriesVolt); //} //for (int i = 0; i < mQty; i++) //{ chartVI.Series.Add(seriesCurr); //} //for (int i = 0; i < mQty; i++) //{ chartVI.Series.Add(seriesTemp); //} //for (int i = 0; i < mQty; i++) //{ chartVI.Series.Add(seriesSoc); //} } private void ComeOnYouThread() { while (ThreadEnd == false) { try { chartVI.Invoke(_doIt); Thread.Sleep(_interval); } catch (Exception) { } } } public void SetLogTime(int aSec) { logTimeSec = aSec; } private void AddData() { DateTime now = DateTime.Now; TimeSpan dTime = now - OldTime; //if (OldTime.Second != now.Second) if ((dTime.Seconds >= logTimeSec) && ((now.Second % logTimeSec) == 0)) { if (dtVI.Rows.Count > 1000) { dtVI.Rows.RemoveAt(0); } // Add data rows to the table. DataRow row = null; row = dtVI.NewRow(); row["DateTime"] = DateTime.Now; row[String.Format("Volt")] = TotalVoltage; row[String.Format("Curr")] = TotalCurrent; row[String.Format("Temp")] = TotalTemperature; row[String.Format("SOC")] = TotalSoc; dtVI.Rows.Add(row); OldTime = now; } } private void tmrDisplay_Tick(object sender, EventArgs e) { DisplayTotalValue(); DisplayStatusAndAlarm(); } private void DisplayTotalValue() { if (active) { dgTotalVoltage.Text = String.Format("{0:0.0}", TotalVoltage); dgTotalCurrent.Text = String.Format("{0:0.0}", TotalCurrent); dgTotalTemp.Text = String.Format("{0:0.0}", TotalTemperature); dgTotalSOC.Text = String.Format("{0:0.0}", TotalSoc); chartVI.Invalidate(); } } private void DisplayStatusAndAlarm() { if (SystemData.CommFail == false) { // Operating Status if (SystemData.StatusData.status == 0) { lbStatus.Text = "STANDBY"; lbStatus.ForeColor = System.Drawing.Color.Black; } else if (SystemData.StatusData.status == 1) { lbStatus.Text = "CHARGING"; lbStatus.ForeColor = System.Drawing.Color.Blue; } else if (SystemData.StatusData.status == 2) { lbStatus.Text = "DISCHARGING"; lbStatus.ForeColor = System.Drawing.Color.Magenta; } else if (SystemData.StatusData.status == 3) { lbStatus.Text = "FLOATING"; lbStatus.ForeColor = System.Drawing.Color.Black; } else { lbStatus.Text = "UNKNOWN"; lbStatus.ForeColor = System.Drawing.Color.Black; } // Alarm Display if (SystemData.StatusData.alarm == 0) { lbAlarm.Text = "NORMAL"; lbAlarm.ForeColor = System.Drawing.Color.Green; } else if (SystemData.StatusData.alarm == 1) { lbAlarm.Text = "WARNING"; lbAlarm.ForeColor = System.Drawing.Color.Orange; } else if (SystemData.StatusData.alarm == 2) { lbAlarm.Text = "FAULT"; lbAlarm.ForeColor = System.Drawing.Color.Red; } else if (SystemData.StatusData.alarm == 3) { lbAlarm.Text = "WARMING UP"; lbAlarm.ForeColor = System.Drawing.Color.Green; } else { lbAlarm.Text = "UNKNOWN"; lbAlarm.ForeColor = System.Drawing.Color.Red; } } else { lbStatus.Text = "OFF LINE"; lbStatus.ForeColor = System.Drawing.Color.Red; lbAlarm.Text = "OFF LINE"; lbAlarm.ForeColor = System.Drawing.Color.Red; } } } }