347 lines
12 KiB
C#
347 lines
12 KiB
C#
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("chg_wait", 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 < csConstData.SystemInfo.MAX_MODULE_CELL_SIZE; 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 = 56) + Data(56) + CRC(2) = 61 bytes
|
|
if (data.Length >= 61 && data[1] == 0x03 && data[2] == 56)
|
|
{
|
|
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;
|
|
short rawStatus = shorts[pos++];
|
|
hRow["status"] = (int)(rawStatus & 0x7FFF);
|
|
hRow["chg_wait"] = ((rawStatus & 0x8000) != 0) ? 1 : 0;
|
|
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 (3 registers = 6 temps)
|
|
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 (15 cells)
|
|
for (int i = 0; i < csConstData.SystemInfo.MAX_MODULE_CELL_SIZE; 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] = 0x1C; // Number of Register L (28 registers = 56 bytes)
|
|
|
|
crc = csSerialCommFunction.GetCRC(sdata, 6);
|
|
|
|
sdata[6] = crc[1]; // CRCH
|
|
sdata[7] = crc[0]; // CRCL
|
|
|
|
OnSendUartData?.Invoke(addr, sdata, true);
|
|
}
|
|
|
|
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) & 0x7FFF;
|
|
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;
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|