using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Linq; using System.Windows.Forms; using DevExpress.XtraEditors; using LFP_Manager.DataStructure; using static LFP_Manager.Forms.fmxParamConfig; using LFP_Manager.Function; using DevExpress.Pdf.Native; using DevExpress.XtraGrid.Columns; namespace LFP_Manager.Forms { public partial class fmxHistory : DevExpress.XtraEditors.XtraForm { #region DELEGATE public delegate void UpdateEvent(object sendor); public delegate void CmdEvent(int sId, int mode, int index, int flag, ref DeviceParamData aParam, ref DeviceCalibration aCalib); #endregion #region VARIABLES private int SystemId = 0; private byte[] rData = null; private ushort curr_addr = 0; private int hist_no = 0; private bool bms_history_req = false; private bool bms_history_stop = false; private DataTable BmsHistoryTable = null; private DevExpress.XtraGrid.Columns.GridColumn[] TpCol; private DevExpress.XtraGrid.Columns.GridColumn[] CvCol; public event AutoTxSetEnvent OnAutoTxSet = null; public event SendDataUartEvent OnSendUartData = null; public event UpdateEvent OnUpdate = null; public event CmdEvent OnCommand = null; #endregion #region CONTRUCTORS //public fmxHistory() //{ // InitializeComponent(); //} public fmxHistory(CommConfig aConfig, int systemId) { InitializeComponent(); CreateColomnInGridView(); ucHistroy1.SetCommCofig(aConfig); SystemId = systemId; CreateHistoryColomn(ref BmsHistoryTable); } #endregion #region INITIALIZE COMPONENT private void CreateColomnInGridView() { //TpCol = new DevExpress.XtraGrid.Columns.GridColumn[6]; //for (int i = 0; i < TpCol.Length; i++) //{ // TpCol[i] = new DevExpress.XtraGrid.Columns.GridColumn(); // TpCol[i].Name = string.Format("gcTemp_{0:00}", i + 1); // TpCol[i].Caption = string.Format("gcTemp_{0:00}", i + 1); // TpCol[i].FieldName = string.Format("temp_{0:00}", i + 1); // TpCol[i].DisplayFormat.FormatString = "0.0"; // gvBmsHistory.Columns.Add(TpCol[i]); //} //CvCol = new DevExpress.XtraGrid.Columns.GridColumn[16]; //for (int i = 0; i < CvCol.Length; i++) //{ // CvCol[i] = new DevExpress.XtraGrid.Columns.GridColumn(); // CvCol[i].FieldName = string.Format("cell_v_{0:00}", i + 1); // CvCol[i].DisplayFormat.FormatString = "0.000"; // gvBmsHistory.Columns.Add(CvCol[i]); //} } private void CreateHistoryColomn(ref DataTable hDT) { hDT = new DataTable(); hDT.Columns.Add("no", typeof(int)); hDT.Columns.Add("datetime", typeof(string)); hDT.Columns.Add("status", typeof(int)); hDT.Columns.Add("warning", typeof(short)); hDT.Columns.Add("protect", typeof(short)); hDT.Columns.Add("error", typeof(short)); hDT.Columns.Add("voltage", typeof(float)); hDT.Columns.Add("current", typeof(float)); hDT.Columns.Add("SOC", typeof(float)); hDT.Columns.Add("SOH", typeof(float)); for (int i = 0; i < 6; i++) { hDT.Columns.Add(string.Format("temp_{0:00}", i + 1), typeof(float)); } for (int i = 0; i < 16; i++) { hDT.Columns.Add(string.Format("cell_v_{0:00}", i + 1), typeof(float)); } gcBmsHistory.DataSource = hDT; } #endregion #region PUBLIC FUNCTIONS private short[] ByteArrTo2Short(byte[] bytes) { short[] result = null; if (bytes != null) { int len = bytes[2]; result = new short[len / 2]; for (int i = 0; i < result.Length; i++) { result[i] = (short)((bytes[3 + (i * 2) + 0] << 8) + bytes[3 + (i * 2) + 1]); } } return result; } public void RecvUardData(byte[] data) { if (bms_history_req == false || data == null) return; // BMS History response packet: Addr(1) + Func(1) + ByteCount(1 = 58) + Data(58) + CRC(2) = 63 bytes if (data.Length >= 63 && data[1] == 0x03 && data[2] == 58) { try { rData = data; DataRow hRow = BmsHistoryTable.NewRow(); short[] shorts = ByteArrTo2Short(data); int pos = 0; int yy, MM, dd, HH, mm, ss; Int32 iDateTime = (rData[3 + 2] << 24) | (rData[3 + 3] << 16) | (rData[3 + 0] << 8) | (rData[3 + 1] << 0); //Int32 iDateTime = (Int32)((shorts[pos + 1] << 16) | (shorts[pos + 0] << 0)); yy = (iDateTime >> 26) & 0x003F; MM = (iDateTime >> 22) & 0x000F; dd = (iDateTime >> 17) & 0x001F; HH = (iDateTime >> 12) & 0x001F; mm = (iDateTime >> 6) & 0x003F; ss = (iDateTime >> 0) & 0x003F; hRow["no"] = hist_no; string stDateTime = string.Format("20{0:00}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}" , yy , MM , dd , HH , mm , ss ); if (DateTime.TryParse(stDateTime, out DateTime aDateTime)) { stDateTime = aDateTime.ToString("yyyy-MM-dd HH:mm:ss"); } hRow["datetime"] = stDateTime; pos = 2; hRow["status"] = shorts[pos++]; hRow["warning"] = shorts[pos++]; hRow["protect"] = shorts[pos++]; hRow["error"] = shorts[pos++]; hRow["voltage"] = string.Format("{0:0.00}", Convert.ToDouble(shorts[pos++]) / 100); hRow["current"] = string.Format("{0:0.00}", Convert.ToDouble(shorts[pos++]) / 100); hRow["SOC"] = string.Format("{0:0.0}", Convert.ToDouble(shorts[pos++]) / 1); // Temperature for (int i = 0; i < 3; i++) { hRow[string.Format("temp_{0:00}", (i * 2) + 1)] = Convert.ToDouble((byte)(shorts[pos] >> 8)); hRow[string.Format("temp_{0:00}", (i * 2) + 2)] = Convert.ToDouble((byte)(shorts[pos++] >> 0)); } // Cell Voltage for (int i = 0; i < 16; i++) { hRow[string.Format("cell_v_{0:00}", i + 1)] = Convert.ToDouble(shorts[pos++]) / 1000; } hRow["SOH"] = string.Format("{0:0.0}", Convert.ToDouble(shorts[pos++]) / 1); BmsHistoryTable.Rows.Add(hRow); } catch (Exception e) { MessageBox.Show(e.Message); } gvBmsHistory.BestFitColumns(); gvBmsHistory.ClearSelection(); if (bms_history_stop == false) { hist_no++; curr_addr += 0x20; RequestHistoryData(curr_addr); } } } #endregion #region BUTTON EVENT private void btnClose_Click(object sender, EventArgs e) { if (bms_history_req) { bms_history_req = false; bms_history_stop = true; OnAutoTxSet?.Invoke(true); } Close(); } #endregion private void btnBmsHistoryReq_Click(object sender, EventArgs e) { if (bms_history_req == false) { OnAutoTxSet?.Invoke(false); bms_history_req = true; bms_history_stop = false; btnBmsHistoryReq.Text = "Stop"; BmsHistoryTable.Rows.Clear(); hist_no = 1; curr_addr = 0x0200; RequestHistoryData(curr_addr); } else { bms_history_req = false; bms_history_stop = true; OnAutoTxSet?.Invoke(true); btnBmsHistoryReq.Text = "Request"; } } private void RequestHistoryData(ushort haddr) { byte[] crc; ushort addr = haddr; // Normal mode --> Bootloader mode byte[] sdata = new byte[8]; sdata[0] = (byte)SystemId; // Dev Address sdata[1] = 0x03; // Function Code sdata[2] = (byte)(addr >> 8); // Address H sdata[3] = (byte)(addr >> 0); // Address L sdata[4] = 0x00; // Number of Register H sdata[5] = 0x1D; // Number of Register L crc = csSerialCommFunction.GetCRC(sdata, 6); sdata[6] = crc[1]; // CRCH sdata[7] = crc[0]; // CRCL OnSendUartData?.Invoke(addr, sdata, false); } private void gvBmsHistory_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e) { if (e.Value == null || e.Value == DBNull.Value) return; if (e.Column.FieldName == "status") { int status = Convert.ToInt32(e.Value); switch ((ushort)status) { case 0x0000: e.DisplayText = "STANDBY (0x0000)"; break; case 0x0001: e.DisplayText = "CHARGING (0x0001)"; break; case 0x0002: e.DisplayText = "DISCHARGING (0x0002)"; break; case 0x0003: e.DisplayText = "FLOATING (0x0003)"; break; case 0x0004: e.DisplayText = "TRIP (0x0004)"; break; case 0x0008: e.DisplayText = "CHG-LIMIT (0x0008)"; break; case 0x0032: e.DisplayText = "POWER-ON (0x0032)"; break; case 0x8000: e.DisplayText = "STANDBY-HEAT (0x8000)"; break; case 0x8001: e.DisplayText = "CHARGING-HEAT (0x8001)"; break; case 0x8002: e.DisplayText = "DISCHARGING-HEAT (0x8002)"; break; case 0x8004: e.DisplayText = "TRIP-HEAT (0x8004)"; break; case 0x8008: e.DisplayText = "CHG-LIMIT-HEAT (0x8008)"; break; default: e.DisplayText = string.Format("UNKNOWN (0x{0:X4})", status); break; } } else if (e.Column.FieldName == "warning" || e.Column.FieldName == "protect" || e.Column.FieldName == "fault" || e.Column.FieldName == "error") { if (short.TryParse(e.Value.ToString(), out short val)) { e.DisplayText = string.Format("0x{0:X4}", (ushort)val); } } } 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(BmsHistoryTable, filename); MessageBox.Show("Complete Export Excel File", "Result", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } }