313 lines
14 KiB
C#
313 lines
14 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
using BMS_D1000H.BMSConstData;
|
|
using BMS_D1000H.DataStructs;
|
|
using BMS_D1000H.Utils.Functions;
|
|
|
|
namespace BMS_D1000H.Functions
|
|
{
|
|
class csModbusDataProcess
|
|
{
|
|
#region Recv System Data
|
|
public static DeviceDataSystem ModBusSystemData_Reg(DeviceDataSystem aMainData, int base_addr, byte[] bdata, int len)
|
|
{
|
|
DeviceDataSystem sData = aMainData;
|
|
if (bdata == null || bdata.Length == 0) return sData;
|
|
|
|
try
|
|
{
|
|
int i = 0;
|
|
for (int j = 0; j < len; j++)
|
|
{
|
|
if (i + 1 >= bdata.Length) break;
|
|
short val = ConvertTo.TwoByteToShort(bdata[i], bdata[i + 1], true);
|
|
int reg = base_addr + j;
|
|
|
|
ParseSystemRegister(ref sData, reg, val);
|
|
|
|
i += 2;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("ModBusSystemData_Reg Parse Error: " + ex.Message);
|
|
}
|
|
|
|
return sData;
|
|
}
|
|
|
|
private static bool ParseSystemRegister(ref DeviceDataSystem sData, int reg, short val)
|
|
{
|
|
// 기본 상태 및 모듈 통계 데이터 (0 ~ 44)
|
|
if (reg <= 44)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 0: sData.BatVoltage = val; return true;
|
|
case 1: sData.Current = val; return true;
|
|
case 2: sData.AverageCurrent = val; return true;
|
|
case 3: sData.RelativeStateOfCharge = val; return true;
|
|
case 10: sData.MaxTemp = val; return true;
|
|
case 11: sData.MinTemp = val; return true;
|
|
case 12: sData.AvgTemp = val; return true;
|
|
case 13: sData.MaxCell = val; return true;
|
|
case 14: sData.MinCell = val; return true;
|
|
case 15: sData.AvgCell = val; return true;
|
|
case 16: sData.ModuleQuantity = val; return true;
|
|
case 17: sData.HistoryDelete = val; return true;
|
|
case 20: sData.Warning = val; return true;
|
|
case 21: sData.Protection = val; return true;
|
|
case 22: sData.TrayCommState = val; return true;
|
|
case 41: sData.AlarmStatus = val; return true;
|
|
case 44: sData.OpStatus = val; return true;
|
|
}
|
|
}
|
|
// 파라미터 임계치 정보 (60 ~ 89)
|
|
else if (reg >= 60 && reg <= 89)
|
|
{
|
|
return ParseSystemParams(ref sData, reg, val);
|
|
}
|
|
// 네트워크 및 트랩 IP 설정 (120 ~ 147)
|
|
else if (reg >= 120 && reg <= 147)
|
|
{
|
|
return ParseSystemNetConfig(ref sData, reg, val);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool ParseSystemParams(ref DeviceDataSystem sData, int reg, short val)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 60: sData.param.voltage.CUV_Warning = val; return true;
|
|
case 61: sData.param.voltage.CUV_Threshold = val; return true;
|
|
case 62: sData.param.voltage.CUV_Recovery = val; return true;
|
|
case 63: sData.param.voltage.SUV_Warning = val; return true;
|
|
case 64: sData.param.voltage.SUV_Threshold = val; return true;
|
|
case 65: sData.param.voltage.SUV_Recovery = val; return true;
|
|
case 66: sData.param.voltage.COV_Warning = val; return true;
|
|
case 67: sData.param.voltage.COV_Threshold = val; return true;
|
|
case 68: sData.param.voltage.COV_Recovery = val; return true;
|
|
case 69: sData.param.voltage.SOV_Warning = val; return true;
|
|
case 70: sData.param.voltage.SOV_Threshold = val; return true;
|
|
case 71: sData.param.voltage.SOV_Recovery = val; return true;
|
|
|
|
case 72: sData.param.current.OC_Chg_Threshold = val; return true;
|
|
case 73: sData.param.current.OC_Chg_Warning = val; return true;
|
|
case 74: sData.param.current.OC_Chg_Recovery = val; return true;
|
|
case 75: sData.param.current.OC_Chg_Time = val; return true;
|
|
case 76: sData.param.current.OC_Dsg_Threshold = val; return true;
|
|
case 77: sData.param.current.OC_Dsg_Warning = val; return true;
|
|
case 78: sData.param.current.OC_Dsg_Recovery = val; return true;
|
|
case 79: sData.param.current.OC_Dsg_Time = val; return true;
|
|
|
|
case 80: sData.param.temperature.OT_Chg_Threshold = val; return true;
|
|
case 81: sData.param.temperature.OT_Chg_Warning = val; return true;
|
|
case 82: sData.param.temperature.OT_Chg_Recovery = val; return true;
|
|
case 83: sData.param.temperature.OT_Chg_Time = val; return true;
|
|
case 84: sData.param.temperature.OT_Dsg_Threshold = val; return true;
|
|
case 85: sData.param.temperature.OT_Dsg_Warning = val; return true;
|
|
case 86: sData.param.temperature.OT_Dsg_Recovery = val; return true;
|
|
case 87: sData.param.temperature.OT_Dsg_Time = val; return true;
|
|
|
|
case 88: sData.param.soc.Low_SOC_Warning = val; return true;
|
|
case 89: sData.param.soc.Low_SOC_Recovery = val; return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static bool ParseSystemNetConfig(ref DeviceDataSystem sData, int reg, short val)
|
|
{
|
|
if (reg >= 120 && reg <= 123) { sData.netconfig.ip_addr.addr[reg - 120] = val; return true; }
|
|
if (reg >= 124 && reg <= 127) { sData.netconfig.subnet_mask.addr[reg - 124] = val; return true; }
|
|
if (reg >= 128 && reg <= 131) { sData.netconfig.gateway_addr.addr[reg - 128] = val; return true; }
|
|
|
|
if (reg >= 132 && reg <= 147)
|
|
{
|
|
int trapIdx = (reg - 132) / 4;
|
|
int addrIdx = (reg - 132) % 4;
|
|
sData.netconfig.trap[trapIdx].addr[addrIdx] = val;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
#endregion
|
|
|
|
#region Recv Tray Data
|
|
public static DeviceDataTray ModBusData_Reg(int base_addr, byte[] bdata, int len)
|
|
{
|
|
DeviceDataTray tData = new DeviceDataTray();
|
|
tData.CellVoltage = new short[SystemID.MAX_TRAY_CELL_SIZE];
|
|
tData.CellTemperature = new short[SystemID.MAX_TRAY_TEMP_SIZE];
|
|
|
|
if (bdata == null || bdata.Length == 0) return tData;
|
|
|
|
try
|
|
{
|
|
int i = 0;
|
|
for (int j = 0; j < len; j++)
|
|
{
|
|
if (i + 1 >= bdata.Length) break;
|
|
short val = ConvertTo.TwoByteToShort(bdata[i], bdata[i + 1], true);
|
|
int reg = base_addr + j;
|
|
|
|
ParseTrayRegister(ref tData, reg, val);
|
|
|
|
i += 2;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("ModBusData_Reg Parse Error: " + ex.Message);
|
|
}
|
|
|
|
return tData;
|
|
}
|
|
|
|
private static void ParseTrayRegister(ref DeviceDataTray tData, int reg, short val)
|
|
{
|
|
// 기본 상태 및 Cell / Temp 데이터
|
|
if (reg == 0) tData.BatVoltage = val;
|
|
else if (reg == 1) tData.Current = val;
|
|
else if (reg == 2) tData.AverageCurrent = val;
|
|
else if (reg >= 3 && reg <= 17)
|
|
{
|
|
int cellIdx = reg - 3;
|
|
if (cellIdx < tData.CellVoltage.Length) tData.CellVoltage[cellIdx] = val;
|
|
}
|
|
else if (reg >= 18 && reg <= 23)
|
|
{
|
|
int tempIdx = reg - 18;
|
|
if (tempIdx < tData.CellTemperature.Length) tData.CellTemperature[tempIdx] = val;
|
|
}
|
|
else if (reg >= 26 && reg <= 29)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 26: tData.RelativeStateOfCharge = val; break;
|
|
case 27: tData.RemainingCapacity = val; break;
|
|
case 28: tData.StateOfHealth = val; break;
|
|
case 29: tData.CycleCount = val; break;
|
|
}
|
|
}
|
|
else if (reg == 31) tData.FullChargeCapacity = val;
|
|
else if (reg == 32) tData.DesignCapacity = val;
|
|
else if (reg >= 37 && reg <= 40)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 37: tData.MaxCellVoltage = val; break;
|
|
case 38: tData.MinCellVoltage = val; break;
|
|
case 39: tData.AvgCellVoltage = val; break;
|
|
case 40: tData.DiffCellVoltage = val; break;
|
|
}
|
|
}
|
|
else if (reg >= 41 && reg <= 45)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 41: tData.AlarmStatus = val; break;
|
|
case 42: tData.Warning = val; break;
|
|
case 43: tData.Protection = val; break;
|
|
case 44: tData.OpStatus = val; break;
|
|
case 45: tData.Commfail = val; break;
|
|
}
|
|
}
|
|
else if (reg >= 46 && reg <= 48)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 46: tData.CellBalanceData = val; break;
|
|
case 47: tData.CellBalanceAvg = val; break;
|
|
case 48: tData.CellBalanceFlag = val; break;
|
|
}
|
|
}
|
|
else if (reg >= 52 && reg <= 58)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 52: tData.MaxCellNo = val; break;
|
|
case 53: tData.MinCellNo = val; break;
|
|
case 54: tData.MaxTemp = val; break;
|
|
case 55: tData.MinTemp = val; break;
|
|
case 56: tData.MaxTempNo = val; break;
|
|
case 57: tData.MinTempNo = val; break;
|
|
case 58: tData.AvgTemp = val; break;
|
|
}
|
|
}
|
|
else if (reg >= 60 && reg <= 89)
|
|
{
|
|
ParseTrayParams(ref tData, reg, val);
|
|
}
|
|
else if (reg >= 90 && reg <= 101)
|
|
{
|
|
ParseTrayProtections(ref tData, reg, val);
|
|
}
|
|
}
|
|
|
|
private static void ParseTrayParams(ref DeviceDataTray tData, int reg, short val)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 60: tData.param.voltage.CUV_Warning = val; break;
|
|
case 61: tData.param.voltage.CUV_Threshold = val; break;
|
|
case 62: tData.param.voltage.CUV_Recovery = val; break;
|
|
case 63: tData.param.voltage.SUV_Warning = val; break;
|
|
case 64: tData.param.voltage.SUV_Threshold = val; break;
|
|
case 65: tData.param.voltage.SUV_Recovery = val; break;
|
|
case 66: tData.param.voltage.COV_Warning = val; break;
|
|
case 67: tData.param.voltage.COV_Threshold = val; break;
|
|
case 68: tData.param.voltage.COV_Recovery = val; break;
|
|
case 69: tData.param.voltage.SOV_Warning = val; break;
|
|
case 70: tData.param.voltage.SOV_Threshold = val; break;
|
|
case 71: tData.param.voltage.SOV_Recovery = val; break;
|
|
|
|
case 72: tData.param.current.OC_Chg_Threshold = val; break;
|
|
case 73: tData.param.current.OC_Chg_Warning = val; break;
|
|
case 74: tData.param.current.OC_Chg_Recovery = val; break;
|
|
case 75: tData.param.current.OC_Chg_Time = val; break;
|
|
case 76: tData.param.current.OC_Dsg_Threshold = val; break;
|
|
case 77: tData.param.current.OC_Dsg_Warning = val; break;
|
|
case 78: tData.param.current.OC_Dsg_Recovery = val; break;
|
|
case 79: tData.param.current.OC_Dsg_Time = val; break;
|
|
|
|
case 80: tData.param.temperature.OT_Chg_Threshold = val; break;
|
|
case 81: tData.param.temperature.OT_Chg_Warning = val; break;
|
|
case 82: tData.param.temperature.OT_Chg_Recovery = val; break;
|
|
case 83: tData.param.temperature.OT_Chg_Time = val; break;
|
|
case 84: tData.param.temperature.OT_Dsg_Threshold = val; break;
|
|
case 85: tData.param.temperature.OT_Dsg_Warning = val; break;
|
|
case 86: tData.param.temperature.OT_Dsg_Recovery = val; break;
|
|
case 87: tData.param.temperature.OT_Dsg_Time = val; break;
|
|
|
|
case 88: tData.param.soc.Low_SOC_Warning = val; break;
|
|
case 89: tData.param.soc.Low_SOC_Recovery = val; break;
|
|
}
|
|
}
|
|
|
|
private static void ParseTrayProtections(ref DeviceDataTray tData, int reg, short val)
|
|
{
|
|
switch (reg)
|
|
{
|
|
case 90: tData.cov_protection_cell = val; break;
|
|
case 91: tData.cov_warning_cell = val; break;
|
|
case 92: tData.cuv_protection_cell = val; break;
|
|
case 93: tData.cuv_warning_cell = val; break;
|
|
case 94: tData.otd_warning_temp = val; break;
|
|
case 95: tData.otd_protection_temp = val; break;
|
|
case 96: tData.otc_warning_temp = val; break;
|
|
case 97: tData.otc_protection_temp = val; break;
|
|
case 98: tData.ltd_warning_temp = val; break;
|
|
case 99: tData.ltd_protection_temp = val; break;
|
|
case 100: tData.ltc_warning_temp = val; break;
|
|
case 101: tData.ltc_protection_temp = val; break;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|