Files
LFP_48V_LCD_SW/BMS_D1000/Functions/csModbusDataProcess.cs
2026-08-11 16:20:44 +09:00

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
}
}