초기 커밋.
This commit is contained in:
54
LFP_Manager/Function/CsCryptoHelper.cs
Normal file
54
LFP_Manager/Function/CsCryptoHelper.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class CsCryptoHelper
|
||||
{
|
||||
// 고정 키 및 IV (보안상 실제 사용 시 안전하게 관리 필요)
|
||||
private static readonly string key = "1234567890123456"; // 16글자 = 128bit
|
||||
private static readonly string iv = "6543210987654321"; // 16글자 = 128bit
|
||||
|
||||
public static string Encrypt(string plainText)
|
||||
{
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = Encoding.UTF8.GetBytes(key);
|
||||
aesAlg.IV = Encoding.UTF8.GetBytes(iv);
|
||||
|
||||
ICryptoTransform encryptor = aesAlg.CreateEncryptor();
|
||||
|
||||
using (MemoryStream msEncrypt = new MemoryStream())
|
||||
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
|
||||
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
|
||||
{
|
||||
swEncrypt.Write(plainText);
|
||||
swEncrypt.Close();
|
||||
return Convert.ToBase64String(msEncrypt.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string Decrypt(string cipherText)
|
||||
{
|
||||
using (Aes aesAlg = Aes.Create())
|
||||
{
|
||||
aesAlg.Key = Encoding.UTF8.GetBytes(key);
|
||||
aesAlg.IV = Encoding.UTF8.GetBytes(iv);
|
||||
|
||||
ICryptoTransform decryptor = aesAlg.CreateDecryptor();
|
||||
|
||||
byte[] buffer = Convert.FromBase64String(cipherText);
|
||||
|
||||
using (MemoryStream msDecrypt = new MemoryStream(buffer))
|
||||
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
|
||||
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
|
||||
{
|
||||
return srDecrypt.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
281
LFP_Manager/Function/CsMakeDataFunction124050.cs
Normal file
281
LFP_Manager/Function/CsMakeDataFunction124050.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
using System;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class csMakeDataFunction124050
|
||||
{
|
||||
private static DeviceSystemData MakeAlarmTripData(int id, short ndata, DeviceSystemData rSystemData)
|
||||
{
|
||||
bool[] aData = csUtils.Int16ToBitArray(ndata);
|
||||
short bFault = rSystemData.StatusData.protection;
|
||||
short bWarning = rSystemData.StatusData.warning;
|
||||
int i = 0;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case 0: // Warning
|
||||
if (aData[i++]) bWarning |= (1 << 2); // Bit 0 : Over voltage warning
|
||||
else bWarning &= ~(1 << 2);
|
||||
if (aData[i++]) bWarning |= (1 << 4); // Bit 1 : Cell Over voltage warning
|
||||
else bWarning &= ~(1 << 4);
|
||||
if (aData[i++]) bWarning |= (1 << 3); // Bit 2 : Low voltage warning
|
||||
else bWarning &= ~(1 << 3);
|
||||
if (aData[i++]) bWarning |= (1 << 5); // Bit 3 : Low cell voltage warning
|
||||
else bWarning &= ~(1 << 5);
|
||||
if (aData[i++]) bWarning |= (1 << 6); // Bit 4 : Charge over current warning
|
||||
else bWarning &= ~(1 << 6);
|
||||
if (aData[i++]) bWarning |= (1 << 7); // Bit 5 : Discharge over current warning
|
||||
else bWarning &= ~(1 << 7);
|
||||
i++; // 06 Abnormal balancing current
|
||||
i++; // 07 Reserved
|
||||
if ((aData[8]) || (aData[9])) bWarning |= (1 << 0); // Bit 8 : Charge over temperature warning, Bit 9 : Discharge over temperature warning
|
||||
else bWarning &= ~(1 << 0);
|
||||
i++; // 08
|
||||
i++; // 09
|
||||
if ((aData[10]) || (aData[11])) bWarning |= (1 << 1); // Bit 10 : Charge low temperature warning, Bit 11 : Discharge low temperature warning
|
||||
else bWarning &= ~(1 << 1);
|
||||
i++; // 10
|
||||
i++; // 11
|
||||
if (aData[i++]) bWarning |= (1 << 11); // 12 : Low capacity warning
|
||||
else bWarning &= ~(1 << 11);
|
||||
i++; // 13
|
||||
if (aData[i++]) bWarning |= (1 << 9); // 14 Cell Voltage Difference Warning
|
||||
else bWarning &= ~(1 << 9);
|
||||
break;
|
||||
case 1: // Status Code 2
|
||||
if (aData[i++]) bFault |= (1 << 2); // Bit 0 : Over voltage warning
|
||||
else bFault &= ~(1 << 2);
|
||||
if (aData[i++]) bFault |= (1 << 4); // Bit 1 : Cell Over voltage warning
|
||||
else bFault &= ~(1 << 4);
|
||||
if (aData[i++]) bFault |= (1 << 3); // Bit 2 : Low voltage warning
|
||||
else bFault &= ~(1 << 3);
|
||||
if (aData[i++]) bFault |= (1 << 5); // Bit 3 : Low cell voltage warning
|
||||
else bFault &= ~(1 << 5);
|
||||
if (aData[i++]) bFault |= (1 << 6); // Bit 4 : Charge over current warning
|
||||
else bFault &= ~(1 << 6);
|
||||
if (aData[i++]) bFault |= (1 << 7); // Bit 5 : Discharge over current warning
|
||||
else bFault &= ~(1 << 7);
|
||||
i++; // 06 Abnormal balancing current
|
||||
i++; // 07 Reserved
|
||||
if ((aData[8]) || (aData[9])) bFault |= (1 << 0); // Bit 8 : Charge over temperature warning, Bit 9 : Discharge over temperature warning
|
||||
else bFault &= ~(1 << 0);
|
||||
i++; // 08
|
||||
i++; // 09
|
||||
if ((aData[10]) || (aData[11])) bFault |= (1 << 1); // Bit 10 : Charge low temperature warning, Bit 11 : Discharge low temperature warning
|
||||
else bFault &= ~(1 << 1);
|
||||
i++; // 10
|
||||
i++; // 11
|
||||
i++; // 12
|
||||
i++; // 13
|
||||
if (aData[i++]) bFault |= (1 << 9); // 14 Cell Voltage Difference Warning
|
||||
else bFault &= ~(1 << 9);
|
||||
break;
|
||||
}
|
||||
|
||||
rSystemData.StatusData.protection = bFault;
|
||||
rSystemData.StatusData.warning = bWarning;
|
||||
|
||||
return rSystemData;
|
||||
}
|
||||
|
||||
public static void SetSnmpData(int index, object sdata, ref DeviceSystemData aSystemData)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1: aSystemData.ValueData.voltageOfPack = (short)(Convert.ToDouble(sdata) / 10); break; // voltageOfPack - 0.01V
|
||||
case 2: aSystemData.ValueData.current = (short)(Convert.ToDouble(sdata) - 10000); break; // current - 0.1A, Offset: 10000
|
||||
case 3: // Cell Voltage #1
|
||||
case 4: // Cell Voltage #2
|
||||
case 5: // Cell Voltage #3
|
||||
case 6: // Cell Voltage #4
|
||||
case 7: // Cell Voltage #5
|
||||
case 8: // Cell Voltage #6
|
||||
case 9: // Cell Voltage #7
|
||||
case 10: // Cell Voltage #8
|
||||
case 11: // Cell Voltage #9
|
||||
case 12: // Cell Voltage #10
|
||||
case 13: // Cell Voltage #11
|
||||
case 14: // Cell Voltage #12
|
||||
case 15: // Cell Voltage #13
|
||||
case 16: // Cell Voltage #14
|
||||
case 17: // Cell Voltage #15
|
||||
case 18: // Cell Voltage #16
|
||||
case 19: // Cell Voltage #17
|
||||
case 20: // Cell Voltage #18
|
||||
case 21: // Cell Voltage #19
|
||||
case 22: // Cell Voltage #20
|
||||
case 23: // Cell Voltage #21
|
||||
case 24: // Cell Voltage #22
|
||||
case 25: // Cell Voltage #23
|
||||
case 26: // Cell Voltage #24
|
||||
case 27: // Cell Voltage #25
|
||||
case 28: // Cell Voltage #26
|
||||
case 29: // Cell Voltage #27
|
||||
case 30: // Cell Voltage #28
|
||||
case 31: // Cell Voltage #29
|
||||
case 32: // Cell Voltage #30
|
||||
case 33: // Cell Voltage #31
|
||||
case 34: // Cell Voltage #32
|
||||
case 35: // Cell Voltage #33
|
||||
case 36: // Cell Voltage #34
|
||||
case 37: // Cell Voltage #35
|
||||
case 38: // Cell Voltage #36
|
||||
case 39: // Cell Voltage #37
|
||||
case 40: // Cell Voltage #38
|
||||
case 41: // Cell Voltage #39
|
||||
aSystemData.ValueData.CellVoltage[index - 3] = (ushort)(Convert.ToDouble(sdata) / 1);
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref aSystemData, 39);
|
||||
break; // Cell Voltage #16
|
||||
|
||||
case 43: aSystemData.ValueData.Ext1Temperature = (short)(Convert.ToDouble(sdata) * 10); break; // Temp of PCB - C
|
||||
case 44: aSystemData.ValueData.Ext2Temperature = (short)(Convert.ToDouble(sdata) * 10); break; // Temp of Ambient - C
|
||||
case 45: aSystemData.AvgData.maxTemp = (short)(Convert.ToDouble(sdata) * 10); break; // Max. Temp
|
||||
|
||||
case 46: aSystemData.ValueData.remainingCapacity = (short)(Convert.ToDouble(sdata) * 1); break; // Remaining Capacity
|
||||
|
||||
case 47: aSystemData.ValueData.stateOfHealth = (short)(Convert.ToDouble(sdata) / 10); break; // stateOfHealth
|
||||
case 48: aSystemData.ValueData.rSOC = (short)(Convert.ToDouble(sdata) / 10); break; // Relatvie State Of Charge
|
||||
|
||||
case 49: aSystemData.StatusData.status = (short)(Convert.ToDouble(sdata) / 1); break; // Status
|
||||
case 50: aSystemData.StatusData.warning = MakeSnmpWarningData((short)Convert.ToDouble(sdata)); break; // warning
|
||||
case 51: aSystemData.StatusData.protection = MakeSnmpTripData((short)Convert.ToDouble(sdata)); break; // Protection
|
||||
case 52: // FaultAndStatus
|
||||
aSystemData.StatusData.faultAndStatus = (short)(Convert.ToDouble(sdata) / 1);
|
||||
//aSystemData.StatusData.status = (short)(((short)Convert.ToDouble(sdata) >> 8) & 0x0003);
|
||||
MakeAlarm(ref aSystemData);
|
||||
break;
|
||||
case 53: aSystemData.ValueData.cycleCount = (short)(Convert.ToDouble(sdata) / 1); break; // cycleCount
|
||||
|
||||
case 54: // Temperature #1
|
||||
case 55: // Temperature #2
|
||||
case 56: // Temperature #3
|
||||
case 57: // Temperature #4
|
||||
case 58: // Temperature #5
|
||||
case 59: // Temperature #6
|
||||
case 60: // Temperature #7
|
||||
case 61: // Temperature #8
|
||||
aSystemData.ValueData.CellTemperature[index - 54] = (short)(Convert.ToDouble(sdata) * 10);
|
||||
csUtils.MakeMaxAvgMinTemperature(ref aSystemData, 8);
|
||||
break; // Temperature #12
|
||||
|
||||
case 68: aSystemData.cellQty = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number
|
||||
case 69: aSystemData.ValueData.designedCapacity = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number
|
||||
case 70: break; // Average Temperature
|
||||
case 71: aSystemData.ValueData.MaxBattChargeCurr = (short)(Convert.ToDouble(sdata) * 1); break; // Max. Charge Current - A
|
||||
case 72: aSystemData.ntcQty = (short)(Convert.ToDouble(sdata) * 1); break; // NTC Number
|
||||
|
||||
case 74: aSystemData.BmsDateTime.year = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Year
|
||||
case 75: aSystemData.BmsDateTime.month = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Month
|
||||
case 76: aSystemData.BmsDateTime.day = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Day
|
||||
case 77: aSystemData.BmsDateTime.hour = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Hour
|
||||
case 78: aSystemData.BmsDateTime.minute = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Minute
|
||||
case 79:
|
||||
aSystemData.BmsDateTime.second = (short)(Convert.ToDouble(sdata) * 1); // BMS DateTime - Second
|
||||
aSystemData.BmsDateTime.DateTimeStr = string.Format("{0:0000}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}"
|
||||
, aSystemData.BmsDateTime.year
|
||||
, aSystemData.BmsDateTime.month
|
||||
, aSystemData.BmsDateTime.day
|
||||
, aSystemData.BmsDateTime.hour
|
||||
, aSystemData.BmsDateTime.minute
|
||||
, aSystemData.BmsDateTime.second
|
||||
);
|
||||
break;
|
||||
|
||||
case 81: aSystemData.FloatVoltage = (int)Convert.ToDouble(sdata); break; // Float Voltage - 0.01V
|
||||
case 82: aSystemData.BoostVoltage = (int)Convert.ToDouble(sdata); break; // Boost Voltage - 0.01V
|
||||
|
||||
case 83: aSystemData.MinChargeTemp = (int)Convert.ToDouble(sdata); break; // Min. Charge Temp - C
|
||||
case 84: aSystemData.MaxChargeTemp = (int)Convert.ToDouble(sdata); break; // Max. Charge Temp - C
|
||||
|
||||
case 90: aSystemData.Information.ModelName = (string)sdata; break; // Model - string
|
||||
case 91: aSystemData.Information.SwProductRev = (string)sdata; break; // BMS Fw Version - string
|
||||
case 92: aSystemData.Information.HwSerialNumber = (string)sdata; break; // Pack Serial Number - string
|
||||
case 93: aSystemData.Information.VendorName = (string)sdata; break; // Vendor Name - string
|
||||
case 94: aSystemData.Information.ProductCode = (string)sdata; break; // Product Code - string
|
||||
case 95: aSystemData.Information.MajorMinorRev = (string)sdata; break; // Major Minor Revision - string
|
||||
case 96: aSystemData.Information.HwProductRev = (string)sdata; break; // Hardware Product Revision - string
|
||||
case 97: aSystemData.Information.ManufacturingDate = (string)sdata; break; // Manufacturing Date - string
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
public static void MakeAlarm(ref DeviceSystemData rSystemData)
|
||||
{
|
||||
if (((rSystemData.StatusData.faultAndStatus >> 14) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 4; // Anti-theft Gyroscope
|
||||
}
|
||||
else if (((rSystemData.StatusData.faultAndStatus >> 15) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 5; // Anti-theft Comm.
|
||||
}
|
||||
else if (rSystemData.StatusData.protection != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 2;
|
||||
}
|
||||
else if (rSystemData.StatusData.warning != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 0;
|
||||
}
|
||||
}
|
||||
public static short MakeSnmpTripData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 4); // 0x0001:Cell OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 2); // 0x0002:Pack OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 5); // 0x0004:Cell UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 3); // 0x0008:Pack UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC1
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 6); // 0x0020:Charging OC2
|
||||
if (bAlarm[6] == true) result |= (short)(1 << 7); // 0x0010:Discharging OC1
|
||||
if (bAlarm[7] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC2
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 9); // 0x0200:Short Circuit Protection
|
||||
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0080: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 0); // 0x0040: Discharging Over Tempratuer
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
|
||||
return result;
|
||||
}
|
||||
public static short MakeSnmpWarningData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 4); // 0x0001:Cell OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 5); // 0x0002:Cell UV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 2); // 0x0004:Pack OV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 3); // 0x0008:Pack UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[6] == true) result |= (short)(1 << 8); // 0x0040:ENV OT
|
||||
if (bAlarm[7] == true) result |= (short)(1 << 9); // 0x0080:ENV UT
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0100: Charging Over Temprature
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 1); // 0x0200: Charging Under Temprature
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 0); // 0x0400: Discharging Over Temprature
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0800: Discharging Under Temprature
|
||||
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x1000:SOC Low
|
||||
|
||||
if (bAlarm[13] == true) result |= (short)(1 << 13); // 0x2000:Diff Volt
|
||||
if (bAlarm[14] == true) result |= (short)(1 << 14); // 0x4000:CB Off
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
562
LFP_Manager/Function/CsRs232CommFunction124050.cs
Normal file
562
LFP_Manager/Function/CsRs232CommFunction124050.cs
Normal file
@@ -0,0 +1,562 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
using LFP_Manager.Controls;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
/// <summary>
|
||||
/// BMS 장치와의 시리얼 통신을 위한 개선된 클래스
|
||||
/// Modbus RTU 프로토콜 및 커스텀 프로토콜 지원
|
||||
/// </summary>
|
||||
public class CsRs232CommFunction124050
|
||||
{
|
||||
#region Constants - Modbus Function Codes
|
||||
public const byte READ_COIL_STATUS = 0x01;
|
||||
public const byte READ_HOLDING_REG = 0x03;
|
||||
public const byte READ_INPUT_REG = 0x04;
|
||||
public const byte FORCE_SINGLE_COIL = 0x05;
|
||||
public const byte PRESET_SINGLE_REG = 0x06;
|
||||
public const byte WRITE_COIL_REG = 0x0F;
|
||||
public const byte PRESET_MULTI_REG = 0x10;
|
||||
public const byte ERROR_REG = 0x90;
|
||||
public const byte FW_FLASH_ERASE_CMD = 0x43;
|
||||
public const byte FW_FLASH_WRITE_CMD = 0x31;
|
||||
public const byte NO_CMD = 0xFF;
|
||||
#endregion
|
||||
|
||||
#region Constants - Register Addresses
|
||||
private static class RegisterAddress
|
||||
{
|
||||
// Basic Data
|
||||
public const int PACK_VOLTAGE = 0;
|
||||
public const int PACK_CURRENT = 1;
|
||||
public const int CELL_VOLTAGE_START = 2;
|
||||
public const int CELL_VOLTAGE_END = 17;
|
||||
public const int EXT1_TEMPERATURE = 18;
|
||||
public const int EXT2_TEMPERATURE = 19;
|
||||
public const int REMAINING_CAPACITY = 21;
|
||||
public const int MAX_CHARGE_CURRENT = 22;
|
||||
public const int STATE_OF_HEALTH = 23;
|
||||
public const int STATE_OF_CHARGE = 24;
|
||||
|
||||
// Status Registers
|
||||
public const int OPERATING_STATUS = 25;
|
||||
public const int WARNING_STATUS = 26;
|
||||
public const int PROTECTION_STATUS = 27;
|
||||
public const int ERROR_CODE = 28;
|
||||
public const int CYCLE_COUNT_MSB = 29;
|
||||
public const int CYCLE_COUNT_LSB = 30;
|
||||
|
||||
// Temperature Registers (Packed)
|
||||
public const int CELL_TEMP_START = 32;
|
||||
public const int CELL_TEMP_END = 35;
|
||||
|
||||
// Device Info
|
||||
public const int CELL_QTY = 36;
|
||||
public const int DESIGNED_CAPACITY = 37;
|
||||
public const int CELL_BALANCE_STATUS = 38;
|
||||
public const int DATETIME_MSB = 45;
|
||||
public const int DATETIME_LSB = 46;
|
||||
public const int SPECIAL_ALARM = 49;
|
||||
|
||||
// Protection Parameters
|
||||
public const int LOW_SOC_WARNING = 58;
|
||||
public const int CELL_UV_WARNING = 61;
|
||||
public const int CELL_UV_TRIP = 62;
|
||||
public const int CELL_UV_RELEASE = 63;
|
||||
public const int SYS_UV_WARNING = 64;
|
||||
public const int SYS_UV_TRIP = 65;
|
||||
public const int SYS_UV_RELEASE = 66;
|
||||
public const int CELL_OV_WARNING = 67;
|
||||
public const int CELL_OV_TRIP = 68;
|
||||
public const int CELL_OV_RELEASE = 69;
|
||||
public const int SYS_OV_WARNING = 70;
|
||||
public const int SYS_OV_TRIP = 71;
|
||||
public const int SYS_OV_RELEASE = 72;
|
||||
|
||||
// Current Protection
|
||||
public const int CHA_OC_TIMES = 76;
|
||||
public const int DCH_OC_TIMES = 77;
|
||||
public const int CHA_OC_RELEASE_TIME = 78;
|
||||
public const int DCH_OC_RELEASE_TIME = 79;
|
||||
public const int CHA_OC_TRIP1 = 80;
|
||||
public const int DCH_OC_TRIP1 = 81;
|
||||
public const int SHORT_CIRCUIT = 82;
|
||||
public const int CHA_OC_TRIP2 = 83;
|
||||
public const int DCH_OC_TRIP2 = 84;
|
||||
public const int CHA_OC_DELAY1 = 85;
|
||||
public const int CHA_OC_DELAY2 = 86;
|
||||
public const int DCH_OC_DELAY1 = 87;
|
||||
public const int DCH_OC_DELAY2 = 88;
|
||||
|
||||
// Temperature Protection
|
||||
public const int CHA_LOW_TEMP_WARNING = 90;
|
||||
public const int CHA_LOW_TEMP_TRIP = 91;
|
||||
public const int CHA_LOW_TEMP_RELEASE = 92;
|
||||
public const int CHA_HIGH_TEMP_WARNING = 93;
|
||||
public const int CHA_HIGH_TEMP_TRIP = 94;
|
||||
public const int CHA_HIGH_TEMP_RELEASE = 95;
|
||||
public const int DCH_LOW_TEMP_WARNING = 96;
|
||||
public const int DCH_LOW_TEMP_TRIP = 97;
|
||||
public const int DCH_LOW_TEMP_RELEASE = 98;
|
||||
public const int DCH_HIGH_TEMP_WARNING = 99;
|
||||
public const int DCH_HIGH_TEMP_TRIP = 100;
|
||||
public const int DCH_HIGH_TEMP_RELEASE = 101;
|
||||
|
||||
// Device Information
|
||||
public const int MODEL_NAME_START = 105;
|
||||
public const int MODEL_NAME_END = 116;
|
||||
public const int FW_VERSION_START = 117;
|
||||
public const int FW_VERSION_END = 119;
|
||||
public const int SERIAL_NUMBER_START = 120;
|
||||
public const int SERIAL_NUMBER_END = 127;
|
||||
|
||||
// Extended Cell Voltages
|
||||
public const int EXT_CELL_VOLTAGE_START = 138;
|
||||
public const int EXT_CELL_VOLTAGE_END = 160;
|
||||
|
||||
// Manufacturing Date
|
||||
public const int MANU_DATE_START = 163;
|
||||
public const int MANU_DATE_END = 166;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Delegates and Events
|
||||
public delegate void LogEventHandler(string message, LogLevel level);
|
||||
public static event LogEventHandler OnLog;
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Modbus Frame Construction
|
||||
/// <summary>
|
||||
/// Modbus 읽기 요청 프레임 생성
|
||||
/// </summary>
|
||||
public static byte[] CreateReadRegisterFrame(byte deviceId, byte functionCode, ushort startAddress, ushort quantity)
|
||||
{
|
||||
if (quantity == 0 || quantity > 125)
|
||||
throw new ArgumentException("Invalid register quantity");
|
||||
|
||||
var frame = new byte[8];
|
||||
frame[0] = deviceId;
|
||||
frame[1] = functionCode;
|
||||
frame[2] = (byte)(startAddress >> 8);
|
||||
frame[3] = (byte)(startAddress & 0xFF);
|
||||
frame[4] = (byte)(quantity >> 8);
|
||||
frame[5] = (byte)(quantity & 0xFF);
|
||||
|
||||
var crc = csUtils.CalculateCRC(frame, 6);
|
||||
frame[6] = crc[0];
|
||||
frame[7] = crc[1];
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modbus 다중 레지스터 쓰기 요청 프레임 생성
|
||||
/// </summary>
|
||||
public static byte[] CreateWriteMultipleRegistersFrame(byte deviceId, ushort startAddress, short[] values)
|
||||
{
|
||||
if (values == null || values.Length == 0 || values.Length > 123)
|
||||
throw new ArgumentException("Invalid values array");
|
||||
|
||||
var frame = new byte[9 + (values.Length * 2)];
|
||||
int index = 0;
|
||||
|
||||
frame[index++] = deviceId;
|
||||
frame[index++] = PRESET_MULTI_REG;
|
||||
frame[index++] = (byte)(startAddress >> 8);
|
||||
frame[index++] = (byte)(startAddress & 0xFF);
|
||||
frame[index++] = (byte)(values.Length >> 8);
|
||||
frame[index++] = (byte)(values.Length & 0xFF);
|
||||
frame[index++] = (byte)(values.Length * 2);
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
frame[index++] = (byte)(value >> 8);
|
||||
frame[index++] = (byte)(value & 0xFF);
|
||||
}
|
||||
|
||||
var crc = csUtils.CalculateCRC(frame, index);
|
||||
frame[index++] = crc[0];
|
||||
frame[index++] = crc[1];
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 단일 코일 쓰기 요청 프레임 생성
|
||||
/// </summary>
|
||||
public static byte[] CreateWriteCoilFrame(byte deviceId, ushort coilAddress, bool value)
|
||||
{
|
||||
var frame = new byte[8];
|
||||
frame[0] = deviceId;
|
||||
frame[1] = FORCE_SINGLE_COIL;
|
||||
frame[2] = (byte)(coilAddress >> 8);
|
||||
frame[3] = (byte)(coilAddress & 0xFF);
|
||||
frame[4] = value ? (byte)0xFF : (byte)0x00;
|
||||
frame[5] = 0x00;
|
||||
|
||||
var crc = csUtils.CalculateCRC(frame, 6);
|
||||
frame[6] = crc[0];
|
||||
frame[7] = crc[1];
|
||||
|
||||
return frame;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Frame Validation
|
||||
/// <summary>
|
||||
/// Modbus 응답 프레임 검증
|
||||
/// </summary>
|
||||
public static ValidationResult ValidateModbusResponse(byte[] data, int length)
|
||||
{
|
||||
if (data == null || length < 3)
|
||||
return new ValidationResult(false, "Insufficient data length");
|
||||
|
||||
try
|
||||
{
|
||||
byte functionCode = data[1];
|
||||
int expectedLength = CalculateExpectedLength(functionCode, data, length);
|
||||
|
||||
if (length < expectedLength)
|
||||
return new ValidationResult(false, "Incomplete frame");
|
||||
|
||||
var calculatedCrc = csUtils.CalculateCRC(data, length - 2);
|
||||
var receivedCrc = new byte[] { data[length - 2], data[length - 1] };
|
||||
|
||||
if (calculatedCrc[0] != receivedCrc[0] || calculatedCrc[1] != receivedCrc[1])
|
||||
return new ValidationResult(false, "CRC mismatch");
|
||||
|
||||
return new ValidationResult(true, "Valid frame");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnLog?.Invoke($"Frame validation error: {ex.Message}", LogLevel.Error);
|
||||
return new ValidationResult(false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static int CalculateExpectedLength(byte functionCode, byte[] data, int length)
|
||||
{
|
||||
switch (functionCode)
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
case READ_HOLDING_REG:
|
||||
case READ_INPUT_REG:
|
||||
return length >= 3 ? data[2] + 5 : 5;
|
||||
case PRESET_MULTI_REG:
|
||||
case FORCE_SINGLE_COIL:
|
||||
case PRESET_SINGLE_REG:
|
||||
return 8;
|
||||
case ERROR_REG:
|
||||
return 5;
|
||||
case FW_FLASH_ERASE_CMD:
|
||||
case FW_FLASH_WRITE_CMD:
|
||||
return 5;
|
||||
default:
|
||||
return length;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Data Processing
|
||||
/// <summary>
|
||||
/// Modbus 응답 데이터를 시스템 데이터로 변환
|
||||
/// </summary>
|
||||
public static ProcessingResult ProcessModbusResponse(byte[] data, ushort startAddress, ushort length, ref DeviceSystemData systemData)
|
||||
{
|
||||
if (data == null || systemData == null)
|
||||
return new ProcessingResult(false, "Invalid input parameters");
|
||||
|
||||
try
|
||||
{
|
||||
byte functionCode = data[1];
|
||||
|
||||
switch (functionCode)
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
return ProcessCoilResponse(data, startAddress, length, ref systemData);
|
||||
case READ_HOLDING_REG:
|
||||
return ProcessHoldingRegisterResponse(data, startAddress, length, ref systemData);
|
||||
case READ_INPUT_REG:
|
||||
return ProcessInputRegisterResponse(data, startAddress, length, ref systemData);
|
||||
case ERROR_REG:
|
||||
return ProcessErrorResponse(data, ref systemData);
|
||||
default:
|
||||
return new ProcessingResult(false, $"Unsupported function code: {functionCode:X2}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnLog?.Invoke($"Data processing error: {ex.Message}", LogLevel.Error);
|
||||
return new ProcessingResult(false, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static ProcessingResult ProcessHoldingRegisterResponse(byte[] data, ushort startAddress, ushort length, ref DeviceSystemData systemData)
|
||||
{
|
||||
int byteCount = data[2];
|
||||
int registerCount = byteCount / 2;
|
||||
int dataIndex = 3;
|
||||
|
||||
var processors = GetRegisterProcessors();
|
||||
|
||||
for (int i = 0; i < registerCount; i++)
|
||||
{
|
||||
ushort registerAddress = (ushort)(startAddress + i);
|
||||
short registerValue = (short)((data[dataIndex] << 8) | data[dataIndex + 1]);
|
||||
|
||||
if (processors.TryGetValue(registerAddress, out var processor))
|
||||
{
|
||||
processor.Invoke(registerValue, systemData);
|
||||
}
|
||||
|
||||
dataIndex += 2;
|
||||
}
|
||||
|
||||
// 계산된 값들 업데이트
|
||||
UpdateCalculatedValues(ref systemData);
|
||||
|
||||
return new ProcessingResult(true, "Processing completed successfully");
|
||||
}
|
||||
|
||||
private static ProcessingResult ProcessCoilResponse(byte[] data, ushort startAddress, ushort length, ref DeviceSystemData systemData)
|
||||
{
|
||||
// 코일 데이터 처리 로직
|
||||
return new ProcessingResult(true, "Coil processing completed");
|
||||
}
|
||||
|
||||
private static ProcessingResult ProcessInputRegisterResponse(byte[] data, ushort startAddress, ushort length, ref DeviceSystemData systemData)
|
||||
{
|
||||
// 입력 레지스터 데이터 처리 로직
|
||||
return new ProcessingResult(true, "Input register processing completed");
|
||||
}
|
||||
|
||||
private static ProcessingResult ProcessErrorResponse(byte[] data, ref DeviceSystemData systemData)
|
||||
{
|
||||
return new ProcessingResult(false, $"Device error: {data[2]:X2}");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Register Processing
|
||||
private static Dictionary<ushort, Action<short, DeviceSystemData>> GetRegisterProcessors()
|
||||
{
|
||||
return new Dictionary<ushort, Action<short, DeviceSystemData>>
|
||||
{
|
||||
[RegisterAddress.PACK_VOLTAGE] = (value, data) => data.ValueData.voltageOfPack = (short)(value / 10),
|
||||
[RegisterAddress.PACK_CURRENT] = (value, data) => data.ValueData.current = (short)(value / 10),
|
||||
[RegisterAddress.REMAINING_CAPACITY] = (value, data) => data.ValueData.remainingCapacity = value,
|
||||
[RegisterAddress.STATE_OF_HEALTH] = (value, data) => data.ValueData.stateOfHealth = (short)(value * 10),
|
||||
[RegisterAddress.STATE_OF_CHARGE] = (value, data) => data.ValueData.rSOC = (short)(value * 10),
|
||||
[RegisterAddress.OPERATING_STATUS] = (value, data) => data.StatusData.status = value,
|
||||
[RegisterAddress.WARNING_STATUS] = (value, data) => data.StatusData.warning = ConvertWarningData(value),
|
||||
[RegisterAddress.PROTECTION_STATUS] = (value, data) => data.StatusData.protection = ConvertProtectionData(value),
|
||||
[RegisterAddress.CELL_QTY] = (value, data) => data.recv_cellQty = value,
|
||||
[RegisterAddress.DESIGNED_CAPACITY] = (value, data) => data.ValueData.designedCapacity = value,
|
||||
// 추가 레지스터 처리기들...
|
||||
};
|
||||
}
|
||||
|
||||
private static void ProcessCellVoltages(ushort address, short value, ref DeviceSystemData systemData)
|
||||
{
|
||||
if (address >= RegisterAddress.CELL_VOLTAGE_START && address <= RegisterAddress.CELL_VOLTAGE_END)
|
||||
{
|
||||
int cellIndex = address - RegisterAddress.CELL_VOLTAGE_START;
|
||||
if (cellIndex < systemData.ValueData.CellVoltage.Length)
|
||||
{
|
||||
systemData.ValueData.CellVoltage[cellIndex] = (ushort)value;
|
||||
}
|
||||
}
|
||||
else if (address >= RegisterAddress.EXT_CELL_VOLTAGE_START && address <= RegisterAddress.EXT_CELL_VOLTAGE_END)
|
||||
{
|
||||
int cellIndex = address - RegisterAddress.EXT_CELL_VOLTAGE_START + 16;
|
||||
if (cellIndex < systemData.ValueData.CellVoltage.Length)
|
||||
{
|
||||
systemData.ValueData.CellVoltage[cellIndex] = (ushort)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessCellTemperatures(ushort address, short value, ref DeviceSystemData systemData)
|
||||
{
|
||||
if (address >= RegisterAddress.CELL_TEMP_START && address <= RegisterAddress.CELL_TEMP_END)
|
||||
{
|
||||
int tempIndex = (address - RegisterAddress.CELL_TEMP_START) * 2;
|
||||
if (tempIndex + 1 < systemData.ValueData.CellTemperature.Length)
|
||||
{
|
||||
systemData.ValueData.CellTemperature[tempIndex] = (short)(((value >> 8) & 0xFF) * 10);
|
||||
systemData.ValueData.CellTemperature[tempIndex + 1] = (short)((value & 0xFF) * 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Data Conversion
|
||||
private static short ConvertWarningData(short rawData)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] alarmBits = ConvertToBitArray(rawData);
|
||||
|
||||
if (alarmBits[0]) result |= (1 << 2); // Pack OV
|
||||
if (alarmBits[1]) result |= (1 << 4); // Cell OV
|
||||
if (alarmBits[2]) result |= (1 << 3); // Pack UV
|
||||
if (alarmBits[3]) result |= (1 << 5); // Cell UV
|
||||
if (alarmBits[4]) result |= (1 << 6); // Charging OC
|
||||
if (alarmBits[5]) result |= (1 << 7); // Discharging OC
|
||||
if (alarmBits[8]) result |= (1 << 0); // Charging Over Temperature
|
||||
if (alarmBits[9]) result |= (1 << 0); // Discharging Over Temperature
|
||||
if (alarmBits[10]) result |= (1 << 1); // Charging Under Temperature
|
||||
if (alarmBits[11]) result |= (1 << 1); // Discharging Under Temperature
|
||||
if (alarmBits[12]) result |= (1 << 11); // SOC Low
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short ConvertProtectionData(short rawData)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] alarmBits = ConvertToBitArray(rawData);
|
||||
|
||||
if (alarmBits[0]) result |= (1 << 2); // Pack OV
|
||||
if (alarmBits[1]) result |= (1 << 4); // Cell OV
|
||||
if (alarmBits[2]) result |= (1 << 3); // Pack UV
|
||||
if (alarmBits[3]) result |= (1 << 5); // Cell UV
|
||||
if (alarmBits[4]) result |= (1 << 6); // Charging OC
|
||||
if (alarmBits[5]) result |= (1 << 7); // Discharging OC
|
||||
if (alarmBits[8]) result |= (1 << 0); // Charging Over Temperature
|
||||
if (alarmBits[9]) result |= (1 << 0); // Discharging Over Temperature
|
||||
if (alarmBits[10]) result |= (1 << 1); // Charging Under Temperature
|
||||
if (alarmBits[11]) result |= (1 << 1); // Discharging Under Temperature
|
||||
if (alarmBits[13]) result |= (1 << 9); // Short Circuit Protection
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool[] ConvertToBitArray(short value)
|
||||
{
|
||||
var bits = new bool[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
bits[i] = ((value >> i) & 1) == 1;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Calculated Values
|
||||
private static void UpdateCalculatedValues(ref DeviceSystemData systemData)
|
||||
{
|
||||
CalculateCellVoltageStatistics(ref systemData);
|
||||
CalculateTemperatureStatistics(ref systemData);
|
||||
csMakeDataFunction.MakeAlarm(ref systemData);
|
||||
}
|
||||
|
||||
private static void CalculateCellVoltageStatistics(ref DeviceSystemData systemData)
|
||||
{
|
||||
if (systemData.cellQty <= 0) return;
|
||||
|
||||
int max = 0, min = int.MaxValue, sum = 0;
|
||||
int maxIndex = 0, minIndex = 0;
|
||||
|
||||
for (int i = 0; i < systemData.cellQty; i++)
|
||||
{
|
||||
if (i >= systemData.ValueData.CellVoltage.Length) break;
|
||||
|
||||
int cellVoltage = systemData.ValueData.CellVoltage[i];
|
||||
sum += cellVoltage;
|
||||
|
||||
if (cellVoltage > max)
|
||||
{
|
||||
max = cellVoltage;
|
||||
maxIndex = i;
|
||||
}
|
||||
|
||||
if (cellVoltage < min)
|
||||
{
|
||||
min = cellVoltage;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
systemData.AvgData.avgCellVoltage = (short)(sum / systemData.cellQty);
|
||||
systemData.AvgData.maxCellVoltage = (short)max;
|
||||
systemData.AvgData.maxCellNum = (short)(maxIndex + 1);
|
||||
systemData.AvgData.minCellVoltage = (short)min;
|
||||
systemData.AvgData.minCellNum = (short)(minIndex + 1);
|
||||
systemData.AvgData.diffCellVoltage = (short)(max - min);
|
||||
}
|
||||
|
||||
private static void CalculateTemperatureStatistics(ref DeviceSystemData systemData)
|
||||
{
|
||||
if (systemData.tempQty <= 0) return;
|
||||
|
||||
int max = int.MinValue, min = int.MaxValue, sum = 0;
|
||||
int maxIndex = 0, minIndex = 0;
|
||||
|
||||
for (int i = 0; i < systemData.tempQty; i++)
|
||||
{
|
||||
if (i >= systemData.ValueData.CellTemperature.Length) break;
|
||||
|
||||
int temperature = systemData.ValueData.CellTemperature[i];
|
||||
sum += temperature;
|
||||
|
||||
if (temperature > max)
|
||||
{
|
||||
max = temperature;
|
||||
maxIndex = i;
|
||||
}
|
||||
|
||||
if (temperature < min)
|
||||
{
|
||||
min = temperature;
|
||||
minIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
systemData.AvgData.avgTemp = (short)(sum / systemData.tempQty);
|
||||
systemData.AvgData.maxTemp = (short)max;
|
||||
systemData.AvgData.maxTempNum = (short)(maxIndex + 1);
|
||||
systemData.AvgData.minTemp = (short)min;
|
||||
systemData.AvgData.minTempNum = (short)(minIndex + 1);
|
||||
systemData.AvgData.diffTemp = (short)(max - min);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Result Classes
|
||||
public class ValidationResult
|
||||
{
|
||||
public bool IsValid { get; }
|
||||
public string Message { get; }
|
||||
|
||||
public ValidationResult(bool isValid, string message)
|
||||
{
|
||||
IsValid = isValid;
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessingResult
|
||||
{
|
||||
public bool Success { get; }
|
||||
public string Message { get; }
|
||||
|
||||
public ProcessingResult(bool success, string message)
|
||||
{
|
||||
Success = success;
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
996
LFP_Manager/Function/CsRs485CommFunction124050.cs
Normal file
996
LFP_Manager/Function/CsRs485CommFunction124050.cs
Normal file
@@ -0,0 +1,996 @@
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
internal class CsRs485CommFunction124050
|
||||
{
|
||||
public const byte READ_COIL_STATUS = 0x01;
|
||||
public const byte READ_HOLDING_REG = 0x03;
|
||||
public const byte READ_INPUT_REG = 0x04; //Byul 구문 추가 필요
|
||||
public const byte FORCE_SINGLE_COIL = 0x05;
|
||||
public const byte PRESET_SINGLE_REG = 0x06;
|
||||
public const byte PRESET_MULTI_REG = 0x10;
|
||||
public const byte WRITE_COIL_REG = 0x0F;
|
||||
public const byte ERROR_REG = 0x90;
|
||||
|
||||
public const byte READ_WRITE_REG = 0x17;
|
||||
public const byte SPECIAL_REG_02 = 0x19;
|
||||
public const byte READ_DEV_ID = 0x2B;
|
||||
|
||||
public const byte FW_FLASH_ERASE_CMD = 0x43;
|
||||
public const byte FW_FLASH_WRITE_CMD = 0x31;
|
||||
|
||||
public const byte NO_CMD = 0xFF;
|
||||
|
||||
public static byte[] GetCRC(byte[] pby, int nSize)
|
||||
{
|
||||
ushort uIndex, i;
|
||||
ushort crc;
|
||||
byte uchCRCHi = 0xff;
|
||||
byte uchCRCLo = 0xff;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
for (i = 0; i < nSize; i++)
|
||||
{
|
||||
uIndex = (ushort)((int)uchCRCLo ^ (int)pby[i]);
|
||||
uchCRCLo = (byte)(uchCRCHi ^ csConstData.CRC_Data.auchCRCHi[uIndex]);
|
||||
uchCRCHi = csConstData.CRC_Data.auchCRCLo[uIndex];
|
||||
}
|
||||
crc = (ushort)((uchCRCHi << 8) | uchCRCLo);
|
||||
|
||||
result[0] = (byte)(crc >> 8);
|
||||
result[1] = (byte)(crc >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadRegisterData(ushort DevID, ushort cmd, ushort ReadAddr, ushort Size)
|
||||
{
|
||||
byte[] result = new byte[8];
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)cmd; // Command
|
||||
result[2] = (byte)(ReadAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(ReadAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(Size >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(Size >> 0); // Count of Register LSB
|
||||
|
||||
crc = GetCRC(result, 6);
|
||||
|
||||
result[6] = crc[1]; // CRCH
|
||||
result[7] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteCoilData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[7 + (1 * 1) + 2];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)WRITE_COIL_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(1 * 1); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[9 + (1 * 2)];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(1 * 2); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 8);
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadDevIdRegReqData(ushort DevID, ushort cmd, ushort ReadAddr)
|
||||
{
|
||||
byte[] result = new byte[7];
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)cmd; // Command
|
||||
result[2] = (byte)0x0E; // MEI Type
|
||||
result[3] = (byte)0x02; // Read Dev Id code
|
||||
result[4] = (byte)ReadAddr; // Object Id
|
||||
|
||||
crc = GetCRC(result, 5);
|
||||
|
||||
result[5] = crc[1]; // CRCH
|
||||
result[6] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static short GetRegister(ushort reg_addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short result = 0;
|
||||
|
||||
switch (reg_addr)
|
||||
{
|
||||
//case 19: result = (short)(0 >> 16); break; // 0021 : UTC TimeStamp MSB
|
||||
//case 20: result = (short)(58 >> 0); break; // 0022 : UTC TimeStamp LSB
|
||||
//case 21: result = (short)0x1000; break; // 0023 : Cell Balancing Flag
|
||||
//case 22: result = (short)0x0000; break; // 0024 : Cell Balancing Voltage
|
||||
//case 23: result = (short)15; break; // 0024 : Cell Balancing Time
|
||||
|
||||
case 0x4002: result = (short)aParam.CellUnderVoltageWarning; break; // 0061 : Low cell voltage warning data
|
||||
//case 33: result = (short)param.sf1.voltage.CUV_Threshold; break; // 0062 : Low cell voltage protection data
|
||||
//case 34: result = (short)param.sf1.voltage.CUV_Recovery; break; // 0063 : Low cell voltage recovery data
|
||||
//case 35: result = (short)param.sf1.voltage.SUV_Warning; break; // 0064 : Low voltage warning data
|
||||
//case 36: result = (short)param.sf1.voltage.SUV_Threshold; break; // 0065 : Low voltage protection data
|
||||
//case 37: result = (short)param.sf1.voltage.SUV_Recovery; break; // 0066 : Low voltage recovery data
|
||||
//case 38: result = (short)param.sf1.voltage.COV_Warning; break; // 0067 : Over cell voltage warning data
|
||||
//case 39: result = (short)param.sf1.voltage.COV_Threshold; break; // 0068 : Over cell voltage protection data
|
||||
//case 40: result = (short)param.sf1.voltage.COV_Recovery; break; // 0069 : Over cell voltage recovery data
|
||||
//case 41: result = (short)param.sf1.voltage.SOV_Warning; break; // 0070 : Over voltage warning data
|
||||
//case 42: result = (short)param.sf1.voltage.SOV_Threshold; break; // 0071 : Over voltage protection data
|
||||
//case 43: result = (short)param.sf1.voltage.SOV_Recovery; break; // 0072 : Over voltage recovery data
|
||||
|
||||
//case 44: result = (short)param.sf1.temperature.OT_Chg_Warning; break; // 0044 : Charge over temperature warning data
|
||||
//case 45: result = (short)param.sf1.temperature.OT_Chg_Threshold; break; // 0045 : Charge over temperature protection data
|
||||
//case 46: result = (short)param.sf1.temperature.OT_Chg_Recovery; break; // 0046 : Charge over temperature recovery data
|
||||
//case 47: result = (short)param.sf1.temperature.OT_Chg_Time; break; // 0047 : Charge over temperature time
|
||||
|
||||
//case 48: result = (short)param.sf1.temperature.OT_Dsg_Warning; break; // 0048 : Discharge over temperature warning data
|
||||
//case 49: result = (short)param.sf1.temperature.OT_Dsg_Threshold; break; // 0049 : Discharge over temperature protection data
|
||||
//case 50: result = (short)param.sf1.temperature.OT_Dsg_Recovery; break; // 0050 : Discharge over temperature recovery data
|
||||
//case 51: result = (short)param.sf1.temperature.OT_Dsg_Time; break; // 0051 : Discharge over temperature time
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static byte[] ModBusGetRegWordToBytes(ushort addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short data;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
data = GetRegister(addr, ref aParam);
|
||||
|
||||
result[0] = (byte)(data >> 8);
|
||||
result[1] = (byte)(data >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, ushort reg_len, ref DeviceParamData aParam)
|
||||
{
|
||||
int tlen = (reg_len * 2) + 7 + 2;
|
||||
byte[] result = new byte[tlen];
|
||||
byte[] tmp;
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[2] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(reg_len >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(reg_len >> 0); // Count of Register LSB
|
||||
result[6] = (byte)(reg_len * 2); ; // Current Value MSB
|
||||
|
||||
for (int i = 0; i < reg_len; i++)
|
||||
{
|
||||
tmp = ModBusGetRegWordToBytes((ushort)(WriteAddr + i), ref aParam);
|
||||
result[7 + (i * 2) + 0] = tmp[0];
|
||||
result[7 + (i * 2) + 1] = tmp[1];
|
||||
}
|
||||
crc = GetCRC(result, 8);
|
||||
|
||||
result[tlen - 2] = crc[0]; // CRCH
|
||||
result[tlen - 1] = crc[1]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadWriteRegisterData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[15];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)READ_WRITE_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Read Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Read Register Address LSB
|
||||
result[i++] = (byte)(0 >> 8); // Read Count of Register MSB
|
||||
result[i++] = (byte)(0 >> 0); // Read Count of Register LSB
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Write Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Write Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Write Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Write Count of Register LSB
|
||||
result[i++] = (byte)(1 * 2); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 8);
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[0]; // CRCH
|
||||
result[i++] = crc[1]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeCheckSum(byte[] sData, int offset, int len, bool flag)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int checksum = 0;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
checksum += sData[i + offset];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
result[0] = (byte)(checksum >> 8);
|
||||
result[1] = (byte)checksum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] MakeTxPacket(byte[] sData, int len)
|
||||
{
|
||||
string str = "";
|
||||
byte[] result;
|
||||
char[] chrArray;
|
||||
int checksum = 0;
|
||||
string checksumStr = "";
|
||||
char[] checksumChr;
|
||||
|
||||
str = "~";
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str += sData[i].ToString("X2");
|
||||
}
|
||||
|
||||
str += "\r";
|
||||
|
||||
chrArray = str.ToCharArray();
|
||||
|
||||
for (int i = 0; i < (chrArray.Length - 6); i++)
|
||||
{
|
||||
checksum += chrArray[i + 1];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
checksumStr = String.Format("{0:X2}{1:X2}", (byte)(checksum >> 8), (byte)checksum);
|
||||
checksumChr = checksumStr.ToCharArray();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
chrArray[chrArray.Length - 5 + i] = checksumChr[i];
|
||||
}
|
||||
|
||||
result = new byte[chrArray.Length];
|
||||
|
||||
for (int i = 0; i < chrArray.Length; i++)
|
||||
{
|
||||
result[i] = (byte)chrArray[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] LengthLchk(int sLen)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int lchksum = 0;
|
||||
|
||||
lchksum = (~(((sLen >> 8) & 0xF) +
|
||||
((sLen >> 4) & 0xF) +
|
||||
((sLen >> 0) & 0xF)) + 1) % 16;
|
||||
lchksum = ((lchksum << 12) | sLen);
|
||||
|
||||
result[0] = (byte)(lchksum >> 8);
|
||||
result[1] = (byte)(lchksum >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeTxData(byte addr, byte cmd, int sLen)
|
||||
{
|
||||
int buffCh = 0;
|
||||
byte[] sData;
|
||||
byte[] lenId;
|
||||
byte[] checksum;
|
||||
|
||||
sData = new byte[((sLen > 0) ? 11 : 10)];
|
||||
|
||||
sData[buffCh] = 0x7E; buffCh++; // SOI
|
||||
sData[buffCh] = 0x25; buffCh++; // VER
|
||||
sData[buffCh] = addr; buffCh++; // ADDR
|
||||
sData[buffCh] = 0x46; buffCh++; // CID1
|
||||
sData[buffCh] = cmd; buffCh++; // CID2 (CMD)
|
||||
|
||||
lenId = LengthLchk(sLen); // LENID
|
||||
sData[buffCh] = lenId[0]; buffCh++; // LENID MSB
|
||||
sData[buffCh] = lenId[1]; buffCh++; // LENID LSB
|
||||
|
||||
if (sLen > 0)
|
||||
{
|
||||
sData[buffCh] = (byte)(sLen / 2); buffCh++; // INFO
|
||||
}
|
||||
|
||||
checksum = csSerialCommFunction.MakeCheckSum(sData, 1, sData.Length - 4, false);
|
||||
|
||||
sData[buffCh] = checksum[1]; buffCh++;
|
||||
sData[buffCh] = checksum[0]; buffCh++;
|
||||
|
||||
sData[buffCh] = 0x0D; buffCh++; // EOI
|
||||
|
||||
return MakeTxPacket(sData, sData.Length);
|
||||
}
|
||||
|
||||
public static int TbPacketCheck(byte[] rdata, int rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata;
|
||||
byte[] checksum;
|
||||
byte[] checksum1;
|
||||
|
||||
checksum = MakeCheckSum(rdata, 1, rlen - 6, false);
|
||||
|
||||
checksum1 = new byte[2];
|
||||
checksum1[0] = csUtils.StrByte2toByte(rdata[rlen - 4], rdata[rlen - 5]);
|
||||
checksum1[1] = csUtils.StrByte2toByte(rdata[rlen - 2], rdata[rlen - 3]);
|
||||
|
||||
|
||||
if ((checksum[0] == checksum1[0]) && (checksum[1] == checksum1[1]))
|
||||
{
|
||||
cdata = csUtils.StrToByteArray(rdata, 0, rlen);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public int ModbusPacketFromSlaveCheck(byte[] rdata, ushort rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata, crc;
|
||||
ushort clen, bytecount;
|
||||
|
||||
if (rlen > 2)
|
||||
{
|
||||
cdata = rdata;
|
||||
|
||||
switch (cdata[1])
|
||||
{
|
||||
case READ_DEV_ID:
|
||||
if (rlen < 10) break;
|
||||
if (rdata[7] == 0) break;
|
||||
|
||||
int tmp = 0;
|
||||
int cPos = 7;
|
||||
int alen = 0;
|
||||
for (int i = 0; i < cdata[7]; i++)
|
||||
{
|
||||
alen = cdata[cPos + 2];
|
||||
cPos += alen + 2;
|
||||
if (rlen < (cPos + 3))
|
||||
{
|
||||
tmp = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmp == 1) break;
|
||||
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
|
||||
else result = -1;
|
||||
break;
|
||||
case READ_COIL_STATUS:
|
||||
case READ_HOLDING_REG:
|
||||
case READ_INPUT_REG:
|
||||
case READ_WRITE_REG:
|
||||
bytecount = cdata[2];
|
||||
clen = (ushort)(bytecount + 5); // header 3, tail 2
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case PRESET_MULTI_REG:
|
||||
case FORCE_SINGLE_COIL:
|
||||
case PRESET_SINGLE_REG:
|
||||
clen = 8;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case ERROR_REG:
|
||||
clen = 6;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_ERASE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_WRITE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static short[] SerialRxProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
short[] result = new short[2];
|
||||
|
||||
switch (rData[1])
|
||||
{
|
||||
case READ_HOLDING_REG: // 0x03
|
||||
ReadHoldingRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_INPUT_REG: // 0x04
|
||||
ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_WRITE_REG: // 0x17
|
||||
//ReadSP1RegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case SPECIAL_REG_02: // 0x19
|
||||
//ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_DEV_ID: // 0x2B
|
||||
ReadDevIdRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case PRESET_MULTI_REG:
|
||||
// read_holding_reg_process(reverse16(rsp->start_addr, true), reverse16(rsp->qty_reg, true));
|
||||
//result[0] = 1;
|
||||
//result[1] = 1;
|
||||
break;
|
||||
case ERROR_REG:
|
||||
result[0] = 2;
|
||||
result[1] = (short)((rData[0] << 8) | rData[1]);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ReadCoilRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = rData[i];
|
||||
|
||||
i++;
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i + j]);
|
||||
SetCoilRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadHoldingRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetHoldingRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
private static void ReadInputRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetInputRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
private static void ReadDevIdRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int cPos = 7;
|
||||
int alen = 0;
|
||||
int regCount = rData[7];
|
||||
int oID = 0;
|
||||
|
||||
for (int i = 0; i < regCount; i++)
|
||||
{
|
||||
oID = rData[cPos + 1];
|
||||
alen = rData[cPos + 2];
|
||||
byte[] tmp = new byte[alen];
|
||||
for (int j = 0; j < alen; j++) { tmp[j] = rData[cPos + 3 + j]; }
|
||||
|
||||
switch (oID)
|
||||
{
|
||||
case 0x00: rSystemData.Information.VendorName = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x01: rSystemData.Information.ProductCode = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x02: rSystemData.Information.MajorMinorRev = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x05: rSystemData.Information.ModelName = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x82: rSystemData.Information.HwSerialNumber = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x83: rSystemData.Information.HwProductRev = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x84: rSystemData.Information.ManufacturingDate = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x86: rSystemData.Information.SwProductRev = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
}
|
||||
|
||||
cPos += alen + 2;
|
||||
if (rLen < (cPos + 3))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void ReadSP2RegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetSP2Register((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
private static void ReadSP1RegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetSP1Register((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly int CURRENT_OFFSET = 10000;
|
||||
private static readonly int TEMP_OFFSET = 400;
|
||||
|
||||
private static short MakeWarningData_AMG(short reg_value)
|
||||
{
|
||||
byte[] reg_byte = new byte[2];
|
||||
ushort result = 0;
|
||||
|
||||
reg_byte[1] = (byte)(reg_value >> 8);
|
||||
reg_byte[0] = (byte)(reg_value >> 0);
|
||||
|
||||
if (((reg_byte[0] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 4); // Cell Over Voltage
|
||||
if (((reg_byte[0] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 5); // Cell Under Voltage
|
||||
if (((reg_byte[0] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 2); // Pack Over Voltage
|
||||
if (((reg_byte[0] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 3); // Pack Under Voltage
|
||||
if (((reg_byte[0] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 6); // Charge Over Current
|
||||
if (((reg_byte[0] >> 5) & 0x01) == 0x01) result |= (ushort)(1 << 7); // Discharge Over Current
|
||||
if (((reg_byte[0] >> 6) & 0x01) == 0x01) result |= (ushort)(1 << 14); // ENV Over Temperature
|
||||
if (((reg_byte[0] >> 7) & 0x01) == 0x01) result |= (ushort)(1 << 15); // ENV Under Temperature
|
||||
|
||||
if (((reg_byte[1] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Chg Over Temperature
|
||||
if (((reg_byte[1] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Chg Under Temperature
|
||||
if (((reg_byte[1] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Dch Over Temperature
|
||||
if (((reg_byte[1] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Dch Under Temperature
|
||||
if (((reg_byte[1] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 11); // SOC Low Alarm
|
||||
if (((reg_byte[1] >> 5) & 0x01) == 0x01) result |= (ushort)(1 << 9); // Diff Voltage Alarm
|
||||
if (((reg_byte[1] >> 6) & 0x01) == 0x01) result |= (ushort)(1 << 13); // CB On/OFF (1: OFF, 0: ON)
|
||||
if (((reg_byte[1] >> 7) & 0x01) == 0x01) result |= (ushort)(1 << 12); // reserved
|
||||
|
||||
return (short)result;
|
||||
}
|
||||
|
||||
private static short MakeProtectData_AMG(short reg_value)
|
||||
{
|
||||
byte[] reg_byte = new byte[2];
|
||||
ushort result = 0;
|
||||
|
||||
reg_byte[1] = (byte)(reg_value >> 8);
|
||||
reg_byte[0] = (byte)(reg_value >> 0);
|
||||
|
||||
if (((reg_byte[0] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 4); // Cell Over Voltage
|
||||
if (((reg_byte[0] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 2); // Pack Over Voltage
|
||||
if (((reg_byte[0] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 5); // Cell Under Voltage
|
||||
if (((reg_byte[0] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 3); // Pack Under Voltage
|
||||
if (((reg_byte[0] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 6); // Cha Over Current 1
|
||||
if (((reg_byte[0] >> 5) & 0x01) == 0x01) result |= (ushort)(1 << 6); // Cha Over Current 2
|
||||
if (((reg_byte[0] >> 6) & 0x01) == 0x01) result |= (ushort)(1 << 7); // Dch Over Current 1
|
||||
if (((reg_byte[0] >> 7) & 0x01) == 0x01) result |= (ushort)(1 << 7); // Dch Over Current 2
|
||||
|
||||
if (((reg_byte[1] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 8); // SC Protect / CB off
|
||||
if (((reg_byte[1] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Chg Over Temperature
|
||||
if (((reg_byte[1] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Chg Under Temperature
|
||||
if (((reg_byte[1] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Dch Over Temperature
|
||||
if (((reg_byte[1] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Dch Under Temperature
|
||||
|
||||
return (short)result;
|
||||
}
|
||||
|
||||
private static void MakeAlarm(ref DeviceSystemData rSystemData)
|
||||
{
|
||||
if (((rSystemData.StatusData.faultstatus >> 14) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 4; // Anti-theft Gyroscope
|
||||
}
|
||||
else if (((rSystemData.StatusData.faultstatus >> 15) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 5; // Anti-theft Comm.
|
||||
}
|
||||
else if (rSystemData.StatusData.protection != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 2;
|
||||
}
|
||||
else if (rSystemData.StatusData.warning != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetHoldingRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
//100 ~111 : Model_Product Name
|
||||
case 100:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 104:
|
||||
case 105:
|
||||
case 106:
|
||||
case 107:
|
||||
case 108:
|
||||
case 109:
|
||||
case 110:
|
||||
case 111:
|
||||
int mReg = reg_addr - 100;
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 111)
|
||||
{
|
||||
rSystemData.Information.ModelName = Encoding.Default.GetString(rSystemData.Information.Model_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//112 ~114 : FW Version
|
||||
case 112:
|
||||
case 113:
|
||||
case 114:
|
||||
int fReg = reg_addr - 112;
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 114)
|
||||
{
|
||||
rSystemData.Information.SwProductRev = Encoding.Default.GetString(rSystemData.Information.FwVer_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//115 ~ 122 : BMS Serial number
|
||||
case 115:
|
||||
case 116:
|
||||
case 117:
|
||||
case 118:
|
||||
case 119:
|
||||
case 120:
|
||||
case 121:
|
||||
case 122:
|
||||
int snReg = reg_addr - 115;
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 122)
|
||||
{
|
||||
rSystemData.Information.HwSerialNumber = Encoding.Default.GetString(rSystemData.Information.BMS_SN).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//123 ~ 127 : Manufacturer
|
||||
case 123:
|
||||
case 124:
|
||||
case 125:
|
||||
case 126:
|
||||
case 127:
|
||||
int mnReg = reg_addr - 123;
|
||||
rSystemData.Information.Vendor_Byte[(mnReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.Vendor_Byte[(mnReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 127)
|
||||
{
|
||||
rSystemData.Information.VendorName = Encoding.Default.GetString(rSystemData.Information.Vendor_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void SetInputRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x0FFF:
|
||||
rSystemData.ValueData.voltageOfPack = (short)(reg_value / 10);
|
||||
rSystemData.active = true;
|
||||
break; // 48.00V = 4800
|
||||
case 0x1000: rSystemData.ValueData.current = (short)(reg_value - CURRENT_OFFSET); break; // 100.0A = 1000 -10000 = 0;
|
||||
case 0x1001: rSystemData.ValueData.remainingCapacity = (short)(reg_value / 1); break; // 100.0Ah = 1000
|
||||
case 0x1002: rSystemData.ValueData.Ext1Temperature = (short)(reg_value - TEMP_OFFSET); break; // 10.0C = 100
|
||||
case 0x1003: rSystemData.ValueData.Ext2Temperature = (short)(reg_value - TEMP_OFFSET); break; // 10.0C = 100
|
||||
|
||||
case 0x1004: rSystemData.StatusData.warning = MakeWarningData_AMG(reg_value); break; // Warning Status
|
||||
case 0x1005: rSystemData.StatusData.protection = MakeProtectData_AMG(reg_value); break; // Protection Status
|
||||
case 0x1006: // Fault Status
|
||||
rSystemData.StatusData.faultstatus = (short)(reg_value / 1);
|
||||
rSystemData.StatusData.status = (short)((reg_value >> 8) & 0x0003);
|
||||
MakeAlarm(ref rSystemData);
|
||||
break;
|
||||
|
||||
case 0x1007: rSystemData.ValueData.rSOC = (short)(reg_value / 10); break; // 100.00% = 10000
|
||||
case 0x1008: rSystemData.ValueData.stateOfHealth = (short)(reg_value / 10); break; // 100.00% = 10000
|
||||
|
||||
case 0x1009: rSystemData.ValueData.fullChargeCapacity = (short)(reg_value / 1); break; // 100.0Ah = 1000
|
||||
case 0x100A: rSystemData.ValueData.cycleCount = (short)(reg_value / 1); break; // 100 cycles = 100
|
||||
case 0x100B: rSystemData.ValueData.NumOfCells = (short)(reg_value / 1); break; // 15 cells = 15
|
||||
case 0x100C: // Cell Voltage #1
|
||||
case 0x100D: // Cell Voltage #2
|
||||
case 0x100E: // Cell Voltage #3
|
||||
case 0x100F: // Cell Voltage #4
|
||||
case 0x1010: // Cell Voltage #5
|
||||
case 0x1011: // Cell Voltage #6
|
||||
case 0x1012: // Cell Voltage #7
|
||||
case 0x1013: // Cell Voltage #8
|
||||
case 0x1014: // Cell Voltage #9
|
||||
case 0x1015: // Cell Voltage #10
|
||||
case 0x1016: // Cell Voltage #11
|
||||
case 0x1017: // Cell Voltage #12
|
||||
case 0x1018: // Cell Voltage #13
|
||||
case 0x1019: // Cell Voltage #14
|
||||
case 0x101A: // Cell Voltage #15
|
||||
case 0x101B: // Cell Voltage #16
|
||||
case 0x101C: // Cell Voltage #17
|
||||
case 0x101D: // Cell Voltage #18
|
||||
case 0x101E: // Cell Voltage #19
|
||||
case 0x101F: // Cell Voltage #20
|
||||
case 0x1020: // Cell Voltage #21
|
||||
case 0x1021: // Cell Voltage #22
|
||||
case 0x1022: // Cell Voltage #23
|
||||
case 0x1023: // Cell Voltage #24
|
||||
case 0x1024: // Cell Voltage #25
|
||||
case 0x1025: // Cell Voltage #26
|
||||
case 0x1026: // Cell Voltage #27
|
||||
case 0x1027: // Cell Voltage #28
|
||||
case 0x1028: // Cell Voltage #29
|
||||
case 0x1029: // Cell Voltage #30
|
||||
case 0x102A: // Cell Voltage #31
|
||||
case 0x102B: // Cell Voltage #32
|
||||
case 0x102C: // Cell Voltage #33
|
||||
case 0x102D: // Cell Voltage #34
|
||||
case 0x102E: // Cell Voltage #35
|
||||
case 0x102F: // Cell Voltage #36
|
||||
case 0x1030: // Cell Voltage #37
|
||||
case 0x1031: // Cell Voltage #38
|
||||
case 0x1032: // Cell Voltage #39 - 3.256V = 3256
|
||||
int cNo = reg_addr - 0x100C;
|
||||
if (cNo < rSystemData.ValueData.CellVoltage.Length)
|
||||
{
|
||||
rSystemData.ValueData.CellVoltage[cNo] = (ushort)(reg_value / 1);
|
||||
}
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref rSystemData, 39);
|
||||
break;
|
||||
case 0x1033: rSystemData.ValueData.NumOfTemps = (short)(reg_value / 1); break; // 5 temps = 5
|
||||
case 0x1034: rSystemData.ValueData.CellTemperature[0] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x1035: rSystemData.ValueData.CellTemperature[1] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x1036: rSystemData.ValueData.CellTemperature[2] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x1037: rSystemData.ValueData.CellTemperature[3] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x1038: rSystemData.ValueData.CellTemperature[4] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x1039: rSystemData.ValueData.CellTemperature[5] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x103A: rSystemData.ValueData.CellTemperature[6] = (short)(reg_value - TEMP_OFFSET); break;
|
||||
case 0x103B: // 25.3C = 253 - 400 = -147 (Offset -400)
|
||||
rSystemData.ValueData.CellTemperature[7] = (short)(reg_value - TEMP_OFFSET);
|
||||
csUtils.MakeMaxAvgMinTemperature(ref rSystemData, 8);
|
||||
break;
|
||||
case 0x103C: rSystemData.MaxValue.MaxChgCurrent = (short)(reg_value); break; // Max. Charge Current
|
||||
case 0x103D: rSystemData.MaxValue.MaxChgTemperature = (short)(reg_value - TEMP_OFFSET); break; // Max. Charge Temperature
|
||||
case 0x103E: rSystemData.MaxValue.MinChgTemperature = (short)(reg_value - TEMP_OFFSET); break; // Min. Charge Temperature
|
||||
case 0x103F: rSystemData.MaxValue.FloatChgVolt = (short)(reg_value / 10); break; // Float Charge Current
|
||||
case 0x1040: rSystemData.MaxValue.BoostChgVolt = (short)(reg_value / 10); break; // Boost Charge Current
|
||||
|
||||
case 0x3000: rSystemData.CalibrationData.AntiTheftComm.TimeOut = (short)(reg_value / 1); break;
|
||||
case 0x3002: rSystemData.CalibrationData.AntiTheftComm.FuncSwitch = (short)(reg_value / 1); break;
|
||||
|
||||
case 0x4000: rSystemData.CalibrationData.AntiTheftGyro.XAxis = (short)(reg_value / 1); break;
|
||||
case 0x4001: rSystemData.CalibrationData.AntiTheftGyro.YAxis = (short)(reg_value / 1); break;
|
||||
case 0x4002: rSystemData.CalibrationData.AntiTheftGyro.ZAxis = (short)(reg_value / 1); break;
|
||||
case 0x4003: rSystemData.CalibrationData.AntiTheftGyro.GyroPolicySel = (short)(reg_value / 1); break;
|
||||
case 0x4004: rSystemData.CalibrationData.AntiTheftGyro.GyroFuncSwitch = (short)(reg_value / 1); break;
|
||||
case 0x4006: rSystemData.CalibrationData.AntiTheftGyro.GyroState = (short)(reg_value / 1); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetSP1Register(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x4000: rSystemData.GyroValue.X_axis = (short)(reg_value); break; //
|
||||
case 0x4001: rSystemData.GyroValue.Y_axis = (short)(reg_value); break; //
|
||||
case 0x4002: rSystemData.GyroValue.Z_axis = (short)(reg_value); break; //
|
||||
case 0x4003: rSystemData.GyroValue.Gyro_policy_sel = (short)(reg_value); break; //
|
||||
case 0x4004: rSystemData.GyroValue.Gyro_func_sw = (short)(reg_value); break; //
|
||||
case 0x4006: rSystemData.GyroValue.Gyro_state = (short)(reg_value); break; //
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void SetSP2Register(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x3000: rSystemData.GyroValue.X_axis = (short)(reg_value); break; //
|
||||
case 0x3002: rSystemData.GyroValue.Y_axis = (short)(reg_value); break; //
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void SetReadIdRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x4000: rSystemData.GyroValue.X_axis = (short)(reg_value); break; //
|
||||
case 0x4001: rSystemData.GyroValue.Y_axis = (short)(reg_value); break; //
|
||||
case 0x4002: rSystemData.GyroValue.Z_axis = (short)(reg_value); break; //
|
||||
case 0x4003: rSystemData.GyroValue.Gyro_policy_sel = (short)(reg_value); break; //
|
||||
case 0x4004: rSystemData.GyroValue.Gyro_func_sw = (short)(reg_value); break; //
|
||||
case 0x4006: rSystemData.GyroValue.Gyro_state = (short)(reg_value); break; //
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetCoilRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x3078:
|
||||
rSystemData.StatusData.relayStatus = reg_value;
|
||||
rSystemData.CalibrationData.FetCalib.FetStatus = reg_value;
|
||||
break;
|
||||
case 0x502E:
|
||||
rSystemData.CalibrationData.Current.ChargeOption = reg_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static short MakeUartWarningData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x0200:SOC Low
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short MakeUartTripData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Temprature
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Temprature
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Temprature
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Temprature
|
||||
if (bAlarm[13] == true) result |= (short)(1 << 9); // 0x0200:Short Circuit Protection
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short MakeUartErrorData(short rdata, short cdata)
|
||||
{
|
||||
short result = cdata;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 9); // 0x0001:Voltage error
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 9); // 0x0002:Temperature error
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 9); // 0x0004: 电流检测Error
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 9); // 0x0010:Cell unbalance
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
830
LFP_Manager/Function/CsSerialCommFunction124050.cs
Normal file
830
LFP_Manager/Function/CsSerialCommFunction124050.cs
Normal file
@@ -0,0 +1,830 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
using LFP_Manager.Controls;
|
||||
using System.Web.Services.Description;
|
||||
using System.Data.Entity.Core.Common.CommandTrees;
|
||||
using DevExpress.XtraRichEdit.Fields.Expression;
|
||||
using DevExpress.XtraRichEdit.Layout;
|
||||
using DevExpress.XtraPrinting.Native.LayoutAdjustment;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class csSerialCommFunction124050
|
||||
{
|
||||
public const byte READ_COIL_STATUS = 0x01;
|
||||
public const byte READ_HOLDING_REG = 0x03;
|
||||
public const byte READ_INPUT_REG = 0x04; //Byul 구문 추가 필요
|
||||
public const byte FORCE_SINGLE_COIL = 0x05;
|
||||
public const byte PRESET_SINGLE_REG = 0x06;
|
||||
public const byte PRESET_MULTI_REG = 0x10;
|
||||
public const byte WRITE_COIL_REG = 0x0F;
|
||||
public const byte ERROR_REG = 0x90;
|
||||
|
||||
public const byte FW_FLASH_ERASE_CMD = 0x43;
|
||||
public const byte FW_FLASH_WRITE_CMD = 0x31;
|
||||
|
||||
public const byte NO_CMD = 0xFF;
|
||||
|
||||
public static byte[] GetCRC(byte[] pby, int nSize)
|
||||
{
|
||||
ushort uIndex, i;
|
||||
ushort crc;
|
||||
byte uchCRCHi = 0xff;
|
||||
byte uchCRCLo = 0xff;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
for (i = 0; i < nSize; i++)
|
||||
{
|
||||
uIndex = (ushort)((int)uchCRCLo ^ (int)pby[i]);
|
||||
uchCRCLo = (byte)(uchCRCHi ^ csUtils.auchCRCHi[uIndex]);
|
||||
uchCRCHi = csUtils.auchCRCLo[uIndex];
|
||||
}
|
||||
crc = (ushort)((uchCRCHi << 8) | uchCRCLo);
|
||||
|
||||
result[0] = (byte)(crc >> 8);
|
||||
result[1] = (byte)(crc >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadRegisterData(ushort DevID, ushort cmd, ushort ReadAddr, ushort Size)
|
||||
{
|
||||
byte[] result = new byte[8];
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)cmd; // Command
|
||||
result[2] = (byte)(ReadAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(ReadAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(Size >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(Size >> 0); // Count of Register LSB
|
||||
|
||||
crc = GetCRC(result, 6);
|
||||
|
||||
result[6] = crc[1]; // CRCH
|
||||
result[7] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteCoilData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[7 + (1 * 1) + 2];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)WRITE_COIL_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(1 * 1); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, short[] WriteData)
|
||||
{
|
||||
byte[] result = new byte[9 + (WriteData.Length * 2)];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(WriteData.Length >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(WriteData.Length >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(WriteData.Length * 2); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
for (int j = 0; j < WriteData.Length; j++)
|
||||
{
|
||||
result[i++] = (byte)(WriteData[j] >> 8);
|
||||
result[i++] = (byte)(WriteData[j] >> 0);
|
||||
}
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static short GetRegister(ushort reg_addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short result = 0;
|
||||
|
||||
switch (reg_addr)
|
||||
{
|
||||
//case 19: result = (short)(0 >> 16); break; // 0021 : UTC TimeStamp MSB
|
||||
//case 20: result = (short)(58 >> 0); break; // 0022 : UTC TimeStamp LSB
|
||||
//case 21: result = (short)0x1000; break; // 0023 : Cell Balancing Flag
|
||||
//case 22: result = (short)0x0000; break; // 0024 : Cell Balancing Voltage
|
||||
//case 23: result = (short)15; break; // 0024 : Cell Balancing Time
|
||||
|
||||
case 0x4002: result = (short)aParam.CellUnderVoltageWarning; break; // 0061 : Low cell voltage warning data
|
||||
//case 33: result = (short)param.sf1.voltage.CUV_Threshold; break; // 0062 : Low cell voltage protection data
|
||||
//case 34: result = (short)param.sf1.voltage.CUV_Recovery; break; // 0063 : Low cell voltage recovery data
|
||||
//case 35: result = (short)param.sf1.voltage.SUV_Warning; break; // 0064 : Low voltage warning data
|
||||
//case 36: result = (short)param.sf1.voltage.SUV_Threshold; break; // 0065 : Low voltage protection data
|
||||
//case 37: result = (short)param.sf1.voltage.SUV_Recovery; break; // 0066 : Low voltage recovery data
|
||||
//case 38: result = (short)param.sf1.voltage.COV_Warning; break; // 0067 : Over cell voltage warning data
|
||||
//case 39: result = (short)param.sf1.voltage.COV_Threshold; break; // 0068 : Over cell voltage protection data
|
||||
//case 40: result = (short)param.sf1.voltage.COV_Recovery; break; // 0069 : Over cell voltage recovery data
|
||||
//case 41: result = (short)param.sf1.voltage.SOV_Warning; break; // 0070 : Over voltage warning data
|
||||
//case 42: result = (short)param.sf1.voltage.SOV_Threshold; break; // 0071 : Over voltage protection data
|
||||
//case 43: result = (short)param.sf1.voltage.SOV_Recovery; break; // 0072 : Over voltage recovery data
|
||||
|
||||
//case 44: result = (short)param.sf1.temperature.OT_Chg_Warning; break; // 0044 : Charge over temperature warning data
|
||||
//case 45: result = (short)param.sf1.temperature.OT_Chg_Threshold; break; // 0045 : Charge over temperature protection data
|
||||
//case 46: result = (short)param.sf1.temperature.OT_Chg_Recovery; break; // 0046 : Charge over temperature recovery data
|
||||
//case 47: result = (short)param.sf1.temperature.OT_Chg_Time; break; // 0047 : Charge over temperature time
|
||||
|
||||
//case 48: result = (short)param.sf1.temperature.OT_Dsg_Warning; break; // 0048 : Discharge over temperature warning data
|
||||
//case 49: result = (short)param.sf1.temperature.OT_Dsg_Threshold; break; // 0049 : Discharge over temperature protection data
|
||||
//case 50: result = (short)param.sf1.temperature.OT_Dsg_Recovery; break; // 0050 : Discharge over temperature recovery data
|
||||
//case 51: result = (short)param.sf1.temperature.OT_Dsg_Time; break; // 0051 : Discharge over temperature time
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static byte[] ModBusGetRegWordToBytes(ushort addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short data;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
data = GetRegister(addr, ref aParam);
|
||||
|
||||
result[0] = (byte)(data >> 8);
|
||||
result[1] = (byte)(data >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, ushort reg_len, ref DeviceParamData aParam)
|
||||
{
|
||||
int tlen = (reg_len * 2) + 7 + 2;
|
||||
byte[] result = new byte[tlen];
|
||||
byte[] tmp;
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[2] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(reg_len >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(reg_len >> 0); // Count of Register LSB
|
||||
result[6] = (byte)(reg_len * 2); ; // Current Value MSB
|
||||
|
||||
for (int i = 0; i < reg_len; i++)
|
||||
{
|
||||
tmp = ModBusGetRegWordToBytes((ushort)(WriteAddr + i), ref aParam);
|
||||
result[7 + (i * 2) + 0] = tmp[0];
|
||||
result[7 + (i * 2) + 1] = tmp[1];
|
||||
}
|
||||
crc = GetCRC(result, 8);
|
||||
|
||||
result[tlen - 2] = crc[0]; // CRCH
|
||||
result[tlen - 1] = crc[1]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeCheckSum(byte[] sData, int offset, int len, bool flag)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int checksum = 0;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
checksum += sData[i + offset];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
result[0] = (byte)(checksum >> 8);
|
||||
result[1] = (byte)checksum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] MakeTxPacket(byte[] sData, int len)
|
||||
{
|
||||
string str = "";
|
||||
byte[] result;
|
||||
char[] chrArray;
|
||||
int checksum = 0;
|
||||
string checksumStr = "";
|
||||
char[] checksumChr;
|
||||
|
||||
str = "~";
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str += sData[i].ToString("X2");
|
||||
}
|
||||
|
||||
str += "\r";
|
||||
|
||||
chrArray = str.ToCharArray();
|
||||
|
||||
for (int i = 0; i < (chrArray.Length - 6); i++)
|
||||
{
|
||||
checksum += chrArray[i + 1];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
checksumStr = String.Format("{0:X2}{1:X2}", (byte)(checksum >> 8), (byte)checksum);
|
||||
checksumChr = checksumStr.ToCharArray();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
chrArray[chrArray.Length - 5 + i] = checksumChr[i];
|
||||
}
|
||||
|
||||
result = new byte[chrArray.Length];
|
||||
|
||||
for (int i = 0; i < chrArray.Length; i++)
|
||||
{
|
||||
result[i] = (byte)chrArray[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] LengthLchk(int sLen)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int lchksum = 0;
|
||||
|
||||
lchksum = (~(((sLen >> 8) & 0xF) +
|
||||
((sLen >> 4) & 0xF) +
|
||||
((sLen >> 0) & 0xF)) + 1) % 16;
|
||||
lchksum = ((lchksum << 12) | sLen);
|
||||
|
||||
result[0] = (byte)(lchksum >> 8);
|
||||
result[1] = (byte)(lchksum >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeTxData(byte addr, byte cmd, int sLen)
|
||||
{
|
||||
int buffCh = 0;
|
||||
byte[] sData;
|
||||
byte[] lenId;
|
||||
byte[] checksum;
|
||||
|
||||
sData = new byte[((sLen > 0) ? 11 : 10)];
|
||||
|
||||
sData[buffCh] = 0x7E; buffCh++; // SOI
|
||||
sData[buffCh] = 0x25; buffCh++; // VER
|
||||
sData[buffCh] = addr; buffCh++; // ADDR
|
||||
sData[buffCh] = 0x46; buffCh++; // CID1
|
||||
sData[buffCh] = cmd; buffCh++; // CID2 (CMD)
|
||||
|
||||
lenId = LengthLchk(sLen); // LENID
|
||||
sData[buffCh] = lenId[0]; buffCh++; // LENID MSB
|
||||
sData[buffCh] = lenId[1]; buffCh++; // LENID LSB
|
||||
|
||||
if (sLen > 0)
|
||||
{
|
||||
sData[buffCh] = (byte)(sLen / 2); buffCh++; // INFO
|
||||
}
|
||||
|
||||
checksum = csSerialCommFunction.MakeCheckSum(sData, 1, sData.Length - 4, false);
|
||||
|
||||
sData[buffCh] = checksum[1]; buffCh++;
|
||||
sData[buffCh] = checksum[0]; buffCh++;
|
||||
|
||||
sData[buffCh] = 0x0D; buffCh++; // EOI
|
||||
|
||||
return MakeTxPacket(sData, sData.Length);
|
||||
}
|
||||
|
||||
public static int TbPacketCheck(byte[] rdata, int rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata;
|
||||
byte[] checksum;
|
||||
byte[] checksum1;
|
||||
|
||||
checksum = MakeCheckSum(rdata, 1, rlen - 6, false);
|
||||
|
||||
checksum1 = new byte[2];
|
||||
checksum1[0] = csUtils.StrByte2toByte(rdata[rlen - 4], rdata[rlen - 5]);
|
||||
checksum1[1] = csUtils.StrByte2toByte(rdata[rlen - 2], rdata[rlen - 3]);
|
||||
|
||||
|
||||
if ((checksum[0] == checksum1[0]) && (checksum[1] == checksum1[1]))
|
||||
{
|
||||
cdata = csUtils.StrToByteArray(rdata, 0, rlen);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public int ModbusPacketFromSlaveCheck(byte[] rdata, ushort rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata, crc;
|
||||
ushort clen, bytecount;
|
||||
|
||||
if (rlen > 2)
|
||||
{
|
||||
cdata = rdata;
|
||||
|
||||
switch (cdata[1])
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
case READ_HOLDING_REG:
|
||||
case READ_INPUT_REG:
|
||||
bytecount = cdata[2];
|
||||
clen = (ushort)(bytecount + 5); // header 3, tail 2
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case PRESET_MULTI_REG:
|
||||
case FORCE_SINGLE_COIL:
|
||||
case PRESET_SINGLE_REG:
|
||||
clen = 8;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case ERROR_REG:
|
||||
clen = 6;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_ERASE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_WRITE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static short[] SerialRxProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
short[] result = new short[2];
|
||||
|
||||
switch (rData[1])
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
ReadCoilRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_HOLDING_REG:
|
||||
ReadHoldRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_INPUT_REG:
|
||||
//ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
//case READ_INPUT_REG:
|
||||
// ReadRegister(rData, rRegAddr, rLen, ref rSystemData);
|
||||
// break;
|
||||
case PRESET_MULTI_REG:
|
||||
// read_holding_reg_process(reverse16(rsp->start_addr, true), reverse16(rsp->qty_reg, true));
|
||||
//result[0] = 1;
|
||||
//result[1] = 1;
|
||||
break;
|
||||
case ERROR_REG:
|
||||
result[0] = 2;
|
||||
result[1] = (short)((rData[0] << 8) | rData[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ReadCoilRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = rData[i];
|
||||
|
||||
i++;
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i + j]);
|
||||
SetCoilRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadHoldRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetHoldRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetCoilRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x3078:
|
||||
rSystemData.StatusData.relayStatus = reg_value;
|
||||
rSystemData.CalibrationData.FetCalib.FetStatus = reg_value;
|
||||
break;
|
||||
case 0x502E:
|
||||
rSystemData.CalibrationData.Current.ChargeOption = reg_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetHoldRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int temp = 0;
|
||||
try
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0: rSystemData.ValueData.voltageOfPack = (short)(reg_value / 10); break; //Total Voltage
|
||||
case 1: rSystemData.ValueData.current = (short)((reg_value) / 10); break; //Total Current
|
||||
case 2: // Cell Voltage #1
|
||||
case 3: // Cell Voltage #2
|
||||
case 4: // Cell Voltage #3
|
||||
case 5: // Cell Voltage #4
|
||||
case 6: // Cell Voltage #5
|
||||
case 7: // Cell Voltage #6
|
||||
case 8: // Cell Voltage #7
|
||||
case 9: // Cell Voltage #8'
|
||||
case 10: // Cell Voltage #9
|
||||
case 11: // Cell Voltage #10
|
||||
case 12: // Cell Voltage #11
|
||||
case 13: // Cell Voltage #12
|
||||
case 14: // Cell Voltage #13
|
||||
case 15: // Cell Voltage #14
|
||||
case 16: // Cell Voltage #15
|
||||
case 17: // Cell Voltage #16
|
||||
rSystemData.ValueData.CellVoltage[reg_addr - 2] = (ushort)(reg_value / 1);
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref rSystemData, 39);
|
||||
break; // 15 CellVoltage 1mV
|
||||
case 18: rSystemData.ValueData.Ext1Temperature = (short)((reg_value) * 10); break; // Ext1 Temperature (Temp of MOS-FET)
|
||||
case 19: rSystemData.ValueData.Ext2Temperature = (short)((reg_value) * 10); break; // Ext2 Amb. PCB Temperature 1C
|
||||
case 20: break; // Temp Max.
|
||||
case 21: rSystemData.ValueData.remainingCapacity = (short)(reg_value / 1); break; // Remaining Capacity
|
||||
case 22: rSystemData.ValueData.MaxBattChargeCurr = reg_value / 1; break;
|
||||
case 23: rSystemData.ValueData.stateOfHealth = (short)(reg_value * 10); break;
|
||||
case 24: rSystemData.ValueData.rSOC = (short)(reg_value * 10); break; // SOC
|
||||
case 25: rSystemData.StatusData.status = reg_value; break; // Operating Status
|
||||
case 26: rSystemData.StatusData.warning = MakeUartWarningData(reg_value); break; // Warning Status
|
||||
case 27: rSystemData.StatusData.protection = MakeUartTripData(reg_value); break; // Protection Status
|
||||
case 28: rSystemData.StatusData.errorCode = reg_value; break; // Error Code
|
||||
// 0x0001 : Voltage error
|
||||
// 0x0002 : Temperature error
|
||||
// 0x0004 : Current Check Error
|
||||
// 0x0010 : Cell unbalance
|
||||
// 0x4000 : Gyro alarm
|
||||
// 0x8000 : Communication alarm
|
||||
case 29: // Cycle count MSB
|
||||
temp = rSystemData.ValueData.cycleCount;
|
||||
rSystemData.ValueData.cycleCount = (temp & (0x0000FFFF)) | (reg_value << 16);
|
||||
break;
|
||||
case 30: // Cycle count LSB
|
||||
temp = rSystemData.ValueData.cycleCount;
|
||||
rSystemData.ValueData.cycleCount = (int)(temp & (0xFFFF0000)) | (reg_value << 0);
|
||||
break;
|
||||
//case 31: // fullChargeCapacity MSB
|
||||
// temp = rSystemData.ValueData.fullChargeCapacity;
|
||||
// rSystemData.ValueData.fullChargeCapacity = (temp & (0x0000FFFF)) | (reg_value << 16);
|
||||
// break;
|
||||
//case 32: // fullChargeCapacity LSB
|
||||
// temp = rSystemData.ValueData.fullChargeCapacity;
|
||||
// rSystemData.ValueData.fullChargeCapacity = (int)(temp & (0xFFFF0000)) | (reg_value << 0);
|
||||
// break;
|
||||
case 32:
|
||||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
try
|
||||
{
|
||||
rSystemData.ValueData.CellTemperature[((reg_addr - 32) * 2) + 0] = (short)(((reg_value >> 8) & 0xFF) * 10);
|
||||
rSystemData.ValueData.CellTemperature[((reg_addr - 32) * 2) + 1] = (short)(((reg_value >> 0) & 0xFF) * 10);
|
||||
csUtils.MakeMaxAvgMinTemperature(ref rSystemData, 8);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(string.Format("{0} - ({1})({2})", ex, reg_addr, rSystemData.ValueData.CellTemperature.Length), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
break;
|
||||
case 36: rSystemData.recv_cellQty = reg_value; break; // Cell Qty
|
||||
case 37: rSystemData.ValueData.designedCapacity = reg_value; break;
|
||||
case 38: rSystemData.StatusData.cellBallanceStatus = reg_value; break;
|
||||
|
||||
//case 42:
|
||||
// rSystemData.ValueData.CellTemperature[6 + 0] = (short)(((reg_value >> 8) & 0xFF) * 10);
|
||||
// rSystemData.ValueData.CellTemperature[6 + 1] = (short)(((reg_value >> 0) & 0xFF) * 10);
|
||||
// MakeMaxAvgMinTemperature(ref rSystemData);
|
||||
// break;
|
||||
|
||||
//case 61: rSystemData.StatusData.cellBallanceStatus = reg_value; break;
|
||||
//45 ~ 99 : Reserved
|
||||
case 45: rSystemData.BmsDateTimeShort1 = (ushort)reg_value; break; // DateTime
|
||||
case 46:
|
||||
rSystemData.BmsDateTimeShort2 = (ushort)reg_value;
|
||||
int yy, MM, dd, HH, mm, ss;
|
||||
rSystemData.BmsDateTimeInt = (rSystemData.BmsDateTimeShort1 << 16) | (rSystemData.BmsDateTimeShort2);
|
||||
yy = (rSystemData.BmsDateTimeInt >> 26) & 0x003F;
|
||||
MM = ((rSystemData.BmsDateTimeInt >> 22) & 0x000F) % 13;
|
||||
dd = ((rSystemData.BmsDateTimeInt >> 17) & 0x001F) % 32;
|
||||
HH = ((rSystemData.BmsDateTimeInt >> 12) & 0x001F) % 24;
|
||||
mm = ((rSystemData.BmsDateTimeInt >> 6) & 0x003F) % 60;
|
||||
ss = ((rSystemData.BmsDateTimeInt >> 0) & 0x003F) % 60;
|
||||
yy += 2000;
|
||||
|
||||
rSystemData.BmsDateTime.DateTimeStr = string.Format("{0:0000}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}"
|
||||
, yy
|
||||
, MM
|
||||
, dd
|
||||
, HH
|
||||
, mm
|
||||
, ss
|
||||
);
|
||||
break; // DateTime
|
||||
|
||||
case 47: rSystemData.CalibrationData.ChaMode.Mode = reg_value; break; // 0x2F
|
||||
case 48: rSystemData.CalibrationData.ChaMode.Value = reg_value; break; // 0x2F
|
||||
|
||||
case 49: rSystemData.StatusData.specialAlarm = (short)(reg_value); break; // Special Alarm
|
||||
|
||||
case 56: rSystemData.CalibrationData.BalCalib.Volt = reg_value; break; // Cell Balance Voltage
|
||||
case 57: rSystemData.CalibrationData.BalCalib.Diff = reg_value; break; // Cell Balance Diff
|
||||
|
||||
case 58: rSystemData.ParamData.LowSocWarning = reg_value; break;
|
||||
|
||||
case 61: rSystemData.ParamData.CellUnderVoltageWarning = reg_value; break;
|
||||
case 62: rSystemData.ParamData.CellUnderVoltageTrip = reg_value; break;
|
||||
case 63: rSystemData.ParamData.CellUnderVoltageRelease = reg_value; break;
|
||||
case 64: rSystemData.ParamData.SysUnderVoltageWarning = (short)(reg_value / 10); break;
|
||||
case 65: rSystemData.ParamData.SysUnderVoltageTrip = (short)(reg_value / 10); break;
|
||||
case 66: rSystemData.ParamData.SysUnderVoltageRelease = (short)(reg_value / 10); break;
|
||||
case 67: rSystemData.ParamData.CellOverVoltageWarning = reg_value; break;
|
||||
case 68: rSystemData.ParamData.CellOverVoltageTrip = reg_value; break;
|
||||
case 69: rSystemData.ParamData.CellOverVoltageRelease = reg_value; break;
|
||||
case 70: rSystemData.ParamData.SysOverVoltageWarning = (short)(reg_value / 10); break;
|
||||
case 71: rSystemData.ParamData.SysOverVoltageTrip = (short)(reg_value / 10); break;
|
||||
case 72: rSystemData.ParamData.SysOverVoltageRelease = (short)(reg_value / 10); break;
|
||||
|
||||
case 76: rSystemData.ParamData.ChaOverCurrentTimes = (short)(reg_value / 1); break;
|
||||
case 77: rSystemData.ParamData.DchOverCurrentTimes = (short)(reg_value / 1); break;
|
||||
case 78: rSystemData.ParamData.ChaOverCurrentReleaseTime = (short)(reg_value * 1); break;
|
||||
case 79: rSystemData.ParamData.DchOverCurrentReleaseTime = (short)(reg_value * 1); break;
|
||||
case 80: rSystemData.ParamData.ChaOverCurrentTrip1 = (short)(reg_value / 10); break;
|
||||
case 81: rSystemData.ParamData.DchOverCurrentTrip1 = (short)(reg_value / 10); break;
|
||||
case 82: rSystemData.ParamData.ShortCircuit = (short)(reg_value / 10); break; // Short Circuit Current = 300A
|
||||
case 83: rSystemData.ParamData.ChaOverCurrentTrip2 = (short)(reg_value / 10); break;
|
||||
case 84: rSystemData.ParamData.DchOverCurrentTrip2 = (short)(reg_value / 10); break;
|
||||
case 85: rSystemData.ParamData.ChaOverCurrentDelay1 = (short)(reg_value / 1); break;
|
||||
case 86: rSystemData.ParamData.ChaOverCurrentDelay2 = (short)(reg_value / 1); break;
|
||||
case 87: rSystemData.ParamData.DchOverCurrentDelay1 = (short)(reg_value / 1); break;
|
||||
case 88: rSystemData.ParamData.DchOverCurrentDelay2 = (short)(reg_value / 1); break;
|
||||
|
||||
case 90: rSystemData.ParamData.ChaLowTempWarning = (short)(reg_value - 50); break;
|
||||
case 91: rSystemData.ParamData.ChaLowTempTrip = (short)(reg_value - 50); break;
|
||||
case 92: rSystemData.ParamData.ChaLowTempRelease = (short)(reg_value - 50); break;
|
||||
case 93: rSystemData.ParamData.ChaHighTempWarning = (short)(reg_value - 50); break;
|
||||
case 94: rSystemData.ParamData.ChaHighTempTrip = (short)(reg_value - 50); break;
|
||||
case 95: rSystemData.ParamData.ChaHighTempRelease = (short)(reg_value - 50); break;
|
||||
case 96: rSystemData.ParamData.DchLowTempWarning = (short)(reg_value - 50); break;
|
||||
case 97: rSystemData.ParamData.DchLowTempTrip = (short)(reg_value - 50); break;
|
||||
case 98: rSystemData.ParamData.DchLowTempRelease = (short)(reg_value - 50); break;
|
||||
case 99: rSystemData.ParamData.DchHighTempWarning = (short)(reg_value - 50); break;
|
||||
case 100: rSystemData.ParamData.DchHighTempTrip = (short)(reg_value - 50); break;
|
||||
case 101: rSystemData.ParamData.DchHighTempRelease = (short)(reg_value - 50); break;
|
||||
|
||||
case 102: break; // PCB High Temp Warning
|
||||
case 103: break; // PCB High Temp Trip
|
||||
case 104: break; // PCB High Temp Release
|
||||
//100 ~111 : Model_Product Name
|
||||
case 105:
|
||||
case 106:
|
||||
case 107:
|
||||
case 108:
|
||||
case 109:
|
||||
case 110:
|
||||
case 111:
|
||||
case 112:
|
||||
case 113:
|
||||
case 114:
|
||||
case 115:
|
||||
case 116:
|
||||
int mReg = reg_addr - 105;
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 116)
|
||||
{
|
||||
rSystemData.Information.ModelName = Encoding.Default.GetString(rSystemData.Information.Model_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
|
||||
//112 ~114 : FW Version
|
||||
case 117:
|
||||
case 118:
|
||||
case 119:
|
||||
int fReg = reg_addr - 117;
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 119)
|
||||
{
|
||||
rSystemData.Information.SwProductRev = Encoding.Default.GetString(rSystemData.Information.FwVer_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//115 ~ 122 : BMS Serial number
|
||||
case 120:
|
||||
case 121:
|
||||
case 122:
|
||||
case 123:
|
||||
case 124:
|
||||
case 125:
|
||||
case 126:
|
||||
case 127:
|
||||
int snReg = reg_addr - 120;
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 127)
|
||||
{
|
||||
rSystemData.Information.HwSerialNumber = Encoding.Default.GetString(rSystemData.Information.BMS_SN).Trim('\0');
|
||||
}
|
||||
break;
|
||||
|
||||
case 130: rSystemData.ParamData.EnvLowTempWarning = (short)(reg_value - 50); break;
|
||||
case 131: rSystemData.ParamData.EnvLowTempTrip = (short)(reg_value - 50); break;
|
||||
case 132: rSystemData.ParamData.EnvLowTempRelease = (short)(reg_value - 50); break;
|
||||
case 133: rSystemData.ParamData.EnvHighTempWarning = (short)(reg_value - 50); break;
|
||||
case 134: rSystemData.ParamData.EnvHighTempTrip = (short)(reg_value - 50); break;
|
||||
case 135: rSystemData.ParamData.EnvHighTempRelease = (short)(reg_value - 50); break;
|
||||
|
||||
case 136: // Anti-Theft Communication
|
||||
rSystemData.CalibrationData.AntiTheft.Comm = reg_value;
|
||||
break;
|
||||
case 137: // Anti-Theft Gyro-Scope
|
||||
rSystemData.CalibrationData.AntiTheft.GyroScope = reg_value;
|
||||
break;
|
||||
|
||||
case 138: // Cell Voltage #17
|
||||
case 139: // Cell Voltage #18
|
||||
case 140: // Cell Voltage #19
|
||||
case 141: // Cell Voltage #20
|
||||
case 142: // Cell Voltage #21
|
||||
case 143: // Cell Voltage #22
|
||||
case 144: // Cell Voltage #23
|
||||
case 145: // Cell Voltage #24
|
||||
case 146: // Cell Voltage #25
|
||||
case 147: // Cell Voltage #26
|
||||
case 148: // Cell Voltage #27
|
||||
case 149: // Cell Voltage #28
|
||||
case 150: // Cell Voltage #29
|
||||
case 151: // Cell Voltage #30
|
||||
case 152: // Cell Voltage #31
|
||||
case 153: // Cell Voltage #32
|
||||
case 154: // Cell Voltage #33
|
||||
case 155: // Cell Voltage #34
|
||||
case 156: // Cell Voltage #35
|
||||
case 157: // Cell Voltage #36
|
||||
case 158: // Cell Voltage #37
|
||||
case 159: // Cell Voltage #38
|
||||
case 160: // Cell Voltage #39
|
||||
rSystemData.ValueData.CellVoltage[reg_addr - 138 + 16] = (ushort)(reg_value / 1);
|
||||
break;
|
||||
|
||||
case 163: // 0xA3
|
||||
case 164: // 0xA4
|
||||
case 165: // 0xA5
|
||||
case 166: // 0xA6
|
||||
int ManuDateReg = reg_addr - 163;
|
||||
rSystemData.Information.ManuDate_Byte[(ManuDateReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.ManuDate_Byte[(ManuDateReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 166)
|
||||
{
|
||||
rSystemData.Information.ManufacturingDate = Encoding.Default.GetString(rSystemData.Information.ManuDate_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(string.Format("{0} - ({1})", ex, reg_addr), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
csMakeDataFunction.MakeAlarm(ref rSystemData);
|
||||
}
|
||||
|
||||
public static short MakeUartWarningData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x0200:SOC Low
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static short MakeUartTripData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
if (bAlarm[13] == true) result |= (short)(1 << 9); // 0x0200:Short Circuit Protection
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short MakeUartErrorData(short rdata, short cdata)
|
||||
{
|
||||
short result = cdata;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 9); // 0x0001:Voltage error
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 9); // 0x0002:Temperature error
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 9); // 0x0004: 电流检测Error
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 9); // 0x0010:Cell unbalance
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
961
LFP_Manager/Function/CsSerialCommFunctionDelta.cs
Normal file
961
LFP_Manager/Function/CsSerialCommFunctionDelta.cs
Normal file
@@ -0,0 +1,961 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
using LFP_Manager.Controls;
|
||||
using System.Web.Services.Description;
|
||||
using DevExpress.XtraTreeList;
|
||||
using SnmpSharpNet;
|
||||
using DevExpress.XtraGrid.Views.BandedGrid.Handler;
|
||||
using static DevExpress.Xpo.Helpers.AssociatedCollectionCriteriaHelper;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class CsSerialCommFunctionDelta
|
||||
{
|
||||
public const byte READ_COIL_STATUS = 0x01;
|
||||
public const byte READ_HOLDING_REG = 0x03;
|
||||
public const byte READ_INPUT_REG = 0x04; //Byul 구문 추가 필요
|
||||
public const byte FORCE_SINGLE_COIL = 0x05;
|
||||
public const byte PRESET_SINGLE_REG = 0x06;
|
||||
public const byte PRESET_MULTI_REG = 0x10;
|
||||
public const byte WRITE_COIL_REG = 0x0F;
|
||||
public const byte ERROR_REG = 0x90;
|
||||
|
||||
public const byte READ_WRITE_REG = 0x17;
|
||||
public const byte SPECIAL_REG_02 = 0x19;
|
||||
public const byte READ_DEV_ID = 0x2B;
|
||||
|
||||
public const byte FW_FLASH_ERASE_CMD = 0x43;
|
||||
public const byte FW_FLASH_WRITE_CMD = 0x31;
|
||||
|
||||
public const byte NO_CMD = 0xFF;
|
||||
|
||||
public static byte[] GetCRC(byte[] pby, int nSize)
|
||||
{
|
||||
ushort uIndex, i;
|
||||
ushort crc;
|
||||
byte uchCRCHi = 0xff;
|
||||
byte uchCRCLo = 0xff;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
for (i = 0; i < nSize; i++)
|
||||
{
|
||||
uIndex = (ushort)((int)uchCRCLo ^ (int)pby[i]);
|
||||
uchCRCLo = (byte)(uchCRCHi ^ csConstData.CRC_Data.auchCRCHi[uIndex]);
|
||||
uchCRCHi = csConstData.CRC_Data.auchCRCLo[uIndex];
|
||||
}
|
||||
crc = (ushort)((uchCRCHi << 8) | uchCRCLo);
|
||||
|
||||
result[0] = (byte)(crc >> 8);
|
||||
result[1] = (byte)(crc >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadRegisterData(ushort DevID, ushort cmd, ushort ReadAddr, ushort Size)
|
||||
{
|
||||
byte[] result = new byte[8];
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)cmd; // Command
|
||||
result[2] = (byte)(ReadAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(ReadAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(Size >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(Size >> 0); // Count of Register LSB
|
||||
|
||||
crc = GetCRC(result, 6);
|
||||
|
||||
result[6] = crc[1]; // CRCH
|
||||
result[7] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteCoilData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[7 + (1 * 1) + 2];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)WRITE_COIL_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(1 * 1); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[9 + (1 * 2)];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(1 * 2); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 8);
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadDevIdRegReqData(ushort DevID, ushort cmd, ushort ReadAddr)
|
||||
{
|
||||
byte[] result = new byte[7];
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)cmd; // Command
|
||||
result[2] = (byte)0x0E; // MEI Type
|
||||
result[3] = (byte)0x02; // Read Dev Id code
|
||||
result[4] = (byte)ReadAddr; // Object Id
|
||||
|
||||
crc = GetCRC(result, 5);
|
||||
|
||||
result[5] = crc[1]; // CRCH
|
||||
result[6] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static short GetRegister(ushort reg_addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short result = 0;
|
||||
|
||||
switch (reg_addr)
|
||||
{
|
||||
//case 19: result = (short)(0 >> 16); break; // 0021 : UTC TimeStamp MSB
|
||||
//case 20: result = (short)(58 >> 0); break; // 0022 : UTC TimeStamp LSB
|
||||
//case 21: result = (short)0x1000; break; // 0023 : Cell Balancing Flag
|
||||
//case 22: result = (short)0x0000; break; // 0024 : Cell Balancing Voltage
|
||||
//case 23: result = (short)15; break; // 0024 : Cell Balancing Time
|
||||
|
||||
case 0x4002: result = (short)aParam.CellUnderVoltageWarning; break; // 0061 : Low cell voltage warning data
|
||||
//case 33: result = (short)param.sf1.voltage.CUV_Threshold; break; // 0062 : Low cell voltage protection data
|
||||
//case 34: result = (short)param.sf1.voltage.CUV_Recovery; break; // 0063 : Low cell voltage recovery data
|
||||
//case 35: result = (short)param.sf1.voltage.SUV_Warning; break; // 0064 : Low voltage warning data
|
||||
//case 36: result = (short)param.sf1.voltage.SUV_Threshold; break; // 0065 : Low voltage protection data
|
||||
//case 37: result = (short)param.sf1.voltage.SUV_Recovery; break; // 0066 : Low voltage recovery data
|
||||
//case 38: result = (short)param.sf1.voltage.COV_Warning; break; // 0067 : Over cell voltage warning data
|
||||
//case 39: result = (short)param.sf1.voltage.COV_Threshold; break; // 0068 : Over cell voltage protection data
|
||||
//case 40: result = (short)param.sf1.voltage.COV_Recovery; break; // 0069 : Over cell voltage recovery data
|
||||
//case 41: result = (short)param.sf1.voltage.SOV_Warning; break; // 0070 : Over voltage warning data
|
||||
//case 42: result = (short)param.sf1.voltage.SOV_Threshold; break; // 0071 : Over voltage protection data
|
||||
//case 43: result = (short)param.sf1.voltage.SOV_Recovery; break; // 0072 : Over voltage recovery data
|
||||
|
||||
//case 44: result = (short)param.sf1.temperature.OT_Chg_Warning; break; // 0044 : Charge over temperature warning data
|
||||
//case 45: result = (short)param.sf1.temperature.OT_Chg_Threshold; break; // 0045 : Charge over temperature protection data
|
||||
//case 46: result = (short)param.sf1.temperature.OT_Chg_Recovery; break; // 0046 : Charge over temperature recovery data
|
||||
//case 47: result = (short)param.sf1.temperature.OT_Chg_Time; break; // 0047 : Charge over temperature time
|
||||
|
||||
//case 48: result = (short)param.sf1.temperature.OT_Dsg_Warning; break; // 0048 : Discharge over temperature warning data
|
||||
//case 49: result = (short)param.sf1.temperature.OT_Dsg_Threshold; break; // 0049 : Discharge over temperature protection data
|
||||
//case 50: result = (short)param.sf1.temperature.OT_Dsg_Recovery; break; // 0050 : Discharge over temperature recovery data
|
||||
//case 51: result = (short)param.sf1.temperature.OT_Dsg_Time; break; // 0051 : Discharge over temperature time
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static byte[] ModBusGetRegWordToBytes(ushort addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short data;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
data = GetRegister(addr, ref aParam);
|
||||
|
||||
result[0] = (byte)(data >> 8);
|
||||
result[1] = (byte)(data >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, ushort reg_len, ref DeviceParamData aParam)
|
||||
{
|
||||
int tlen = (reg_len * 2) + 7 + 2;
|
||||
byte[] result = new byte[tlen];
|
||||
byte[] tmp;
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[2] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(reg_len >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(reg_len >> 0); // Count of Register LSB
|
||||
result[6] = (byte)(reg_len * 2); ; // Current Value MSB
|
||||
|
||||
for (int i = 0; i < reg_len; i++)
|
||||
{
|
||||
tmp = ModBusGetRegWordToBytes((ushort)(WriteAddr + i), ref aParam);
|
||||
result[7 + (i * 2) + 0] = tmp[0];
|
||||
result[7 + (i * 2) + 1] = tmp[1];
|
||||
}
|
||||
crc = GetCRC(result, 8);
|
||||
|
||||
result[tlen - 2] = crc[0]; // CRCH
|
||||
result[tlen - 1] = crc[1]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadWriteRegisterData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[15];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)READ_WRITE_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Read Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Read Register Address LSB
|
||||
result[i++] = (byte)(0 >> 8); // Read Count of Register MSB
|
||||
result[i++] = (byte)(0 >> 0); // Read Count of Register LSB
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Write Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Write Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Write Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Write Count of Register LSB
|
||||
result[i++] = (byte)(1 * 2); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 8);
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[0]; // CRCH
|
||||
result[i++] = crc[1]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeCheckSum(byte[] sData, int offset, int len, bool flag)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int checksum = 0;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
checksum += sData[i + offset];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
result[0] = (byte)(checksum >> 8);
|
||||
result[1] = (byte)checksum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] MakeTxPacket(byte[] sData, int len)
|
||||
{
|
||||
string str = "";
|
||||
byte[] result;
|
||||
char[] chrArray;
|
||||
int checksum = 0;
|
||||
string checksumStr = "";
|
||||
char[] checksumChr;
|
||||
|
||||
str = "~";
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str += sData[i].ToString("X2");
|
||||
}
|
||||
|
||||
str += "\r";
|
||||
|
||||
chrArray = str.ToCharArray();
|
||||
|
||||
for (int i = 0; i < (chrArray.Length - 6); i++)
|
||||
{
|
||||
checksum += chrArray[i + 1];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
checksumStr = String.Format("{0:X2}{1:X2}", (byte)(checksum >> 8), (byte)checksum);
|
||||
checksumChr = checksumStr.ToCharArray();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
chrArray[chrArray.Length - 5 + i] = checksumChr[i];
|
||||
}
|
||||
|
||||
result = new byte[chrArray.Length];
|
||||
|
||||
for (int i = 0; i < chrArray.Length; i++)
|
||||
{
|
||||
result[i] = (byte)chrArray[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] LengthLchk(int sLen)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int lchksum = 0;
|
||||
|
||||
lchksum = (~(((sLen >> 8) & 0xF) +
|
||||
((sLen >> 4) & 0xF) +
|
||||
((sLen >> 0) & 0xF)) + 1) % 16;
|
||||
lchksum = ((lchksum << 12) | sLen);
|
||||
|
||||
result[0] = (byte)(lchksum >> 8);
|
||||
result[1] = (byte)(lchksum >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeTxData(byte addr, byte cmd, int sLen)
|
||||
{
|
||||
int buffCh = 0;
|
||||
byte[] sData;
|
||||
byte[] lenId;
|
||||
byte[] checksum;
|
||||
|
||||
sData = new byte[((sLen > 0) ? 11 : 10)];
|
||||
|
||||
sData[buffCh] = 0x7E; buffCh++; // SOI
|
||||
sData[buffCh] = 0x25; buffCh++; // VER
|
||||
sData[buffCh] = addr; buffCh++; // ADDR
|
||||
sData[buffCh] = 0x46; buffCh++; // CID1
|
||||
sData[buffCh] = cmd; buffCh++; // CID2 (CMD)
|
||||
|
||||
lenId = LengthLchk(sLen); // LENID
|
||||
sData[buffCh] = lenId[0]; buffCh++; // LENID MSB
|
||||
sData[buffCh] = lenId[1]; buffCh++; // LENID LSB
|
||||
|
||||
if (sLen > 0)
|
||||
{
|
||||
sData[buffCh] = (byte)(sLen / 2); buffCh++; // INFO
|
||||
}
|
||||
|
||||
checksum = csSerialCommFunction.MakeCheckSum(sData, 1, sData.Length - 4, false);
|
||||
|
||||
sData[buffCh] = checksum[1]; buffCh++;
|
||||
sData[buffCh] = checksum[0]; buffCh++;
|
||||
|
||||
sData[buffCh] = 0x0D; buffCh++; // EOI
|
||||
|
||||
return MakeTxPacket(sData, sData.Length);
|
||||
}
|
||||
|
||||
public static int TbPacketCheck(byte[] rdata, int rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata;
|
||||
byte[] checksum;
|
||||
byte[] checksum1;
|
||||
|
||||
checksum = MakeCheckSum(rdata, 1, rlen - 6, false);
|
||||
|
||||
checksum1 = new byte[2];
|
||||
checksum1[0] = csUtils.StrByte2toByte(rdata[rlen - 4], rdata[rlen - 5]);
|
||||
checksum1[1] = csUtils.StrByte2toByte(rdata[rlen - 2], rdata[rlen - 3]);
|
||||
|
||||
|
||||
if ((checksum[0] == checksum1[0]) && (checksum[1] == checksum1[1]))
|
||||
{
|
||||
cdata = csUtils.StrToByteArray(rdata, 0, rlen);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public int ModbusPacketFromSlaveCheck(byte[] rdata, ushort rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata, crc;
|
||||
ushort clen, bytecount;
|
||||
|
||||
if (rlen > 2)
|
||||
{
|
||||
cdata = rdata;
|
||||
|
||||
switch (cdata[1])
|
||||
{
|
||||
case READ_DEV_ID:
|
||||
if (rlen < 10) break;
|
||||
if (rdata[7] == 0) break;
|
||||
|
||||
int tmp = 0;
|
||||
int cPos = 7;
|
||||
int alen = 0;
|
||||
for (int i = 0; i < cdata[7]; i++)
|
||||
{
|
||||
alen = cdata[cPos + 2];
|
||||
cPos += alen + 2;
|
||||
if (rlen < (cPos + 3))
|
||||
{
|
||||
tmp = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tmp == 1) break;
|
||||
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
|
||||
else result = -1;
|
||||
break;
|
||||
case READ_COIL_STATUS:
|
||||
case READ_HOLDING_REG:
|
||||
case READ_INPUT_REG:
|
||||
case READ_WRITE_REG:
|
||||
bytecount = cdata[2];
|
||||
clen = (ushort)(bytecount + 5); // header 3, tail 2
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case PRESET_MULTI_REG:
|
||||
case FORCE_SINGLE_COIL:
|
||||
case PRESET_SINGLE_REG:
|
||||
clen = 8;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case ERROR_REG:
|
||||
clen = 6;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_ERASE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_WRITE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static short[] SerialRxProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
short[] result = new short[2];
|
||||
|
||||
switch (rData[1])
|
||||
{
|
||||
case READ_HOLDING_REG: // 0x03
|
||||
ReadHoldingRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_INPUT_REG: // 0x04
|
||||
ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_WRITE_REG: // 0x17
|
||||
//ReadSP1RegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case SPECIAL_REG_02: // 0x19
|
||||
//ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_DEV_ID: // 0x2B
|
||||
ReadDevIdRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case PRESET_MULTI_REG:
|
||||
// read_holding_reg_process(reverse16(rsp->start_addr, true), reverse16(rsp->qty_reg, true));
|
||||
//result[0] = 1;
|
||||
//result[1] = 1;
|
||||
break;
|
||||
case ERROR_REG:
|
||||
result[0] = 2;
|
||||
result[1] = (short)((rData[0] << 8) | rData[1]);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ReadCoilRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = rData[i];
|
||||
|
||||
i++;
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i + j]);
|
||||
SetCoilRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadHoldingRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetHoldingRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
private static void ReadInputRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetInputRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
private static void ReadDevIdRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int cPos = 7;
|
||||
int alen = 0;
|
||||
int regCount = rData[7];
|
||||
int oID = 0;
|
||||
|
||||
for (int i = 0; i < regCount; i++)
|
||||
{
|
||||
oID = rData[cPos + 1];
|
||||
alen = rData[cPos + 2];
|
||||
byte[] tmp = new byte[alen];
|
||||
for (int j = 0; j < alen; j++) { tmp[j] = rData[cPos + 3 + j]; }
|
||||
|
||||
switch (oID)
|
||||
{
|
||||
case 0x00: rSystemData.Information.VendorName = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x01: rSystemData.Information.ProductCode = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
case 0x02: rSystemData.Information.MajorMinorRev = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
//case 0x05: rSystemData.Information.ModelName = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
//case 0x82: rSystemData.Information.HwSerialNumber = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
//case 0x83: rSystemData.Information.HwProductRev = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
//case 0x84: rSystemData.Information.ManufacturingDate = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
//case 0x86: rSystemData.Information.SwProductRev = Encoding.ASCII.GetString(tmp).Trim('\0'); break;
|
||||
}
|
||||
|
||||
cPos += alen + 2;
|
||||
if (rLen < (cPos + 3))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void ReadSP2RegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetSP2Register((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
private static void ReadSP1RegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetSP1Register((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly int CURRENT_OFFSET = 10000;
|
||||
private static readonly int TEMP_OFFSET = 400;
|
||||
|
||||
private static short MakeWarningData_AMG(short reg_value)
|
||||
{
|
||||
byte[] reg_byte = new byte[2];
|
||||
ushort result = 0;
|
||||
|
||||
reg_byte[1] = (byte)(reg_value >> 8);
|
||||
reg_byte[0] = (byte)(reg_value >> 0);
|
||||
|
||||
if (((reg_byte[0] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 4); // Cell Over Voltage
|
||||
if (((reg_byte[0] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 5); // Cell Under Voltage
|
||||
if (((reg_byte[0] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 2); // Pack Over Voltage
|
||||
if (((reg_byte[0] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 3); // Pack Under Voltage
|
||||
if (((reg_byte[0] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 6); // Charge Over Current
|
||||
if (((reg_byte[0] >> 5) & 0x01) == 0x01) result |= (ushort)(1 << 7); // Discharge Over Current
|
||||
if (((reg_byte[0] >> 6) & 0x01) == 0x01) result |= (ushort)(1 << 14); // ENV Over Temperature
|
||||
if (((reg_byte[0] >> 7) & 0x01) == 0x01) result |= (ushort)(1 << 15); // ENV Under Temperature
|
||||
|
||||
if (((reg_byte[1] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Chg Over Temperature
|
||||
if (((reg_byte[1] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Chg Under Temperature
|
||||
if (((reg_byte[1] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Dch Over Temperature
|
||||
if (((reg_byte[1] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Dch Under Temperature
|
||||
if (((reg_byte[1] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 11); // SOC Low Alarm
|
||||
if (((reg_byte[1] >> 5) & 0x01) == 0x01) result |= (ushort)(1 << 9); // Diff Voltage Alarm
|
||||
if (((reg_byte[1] >> 6) & 0x01) == 0x01) result |= (ushort)(1 << 13); // CB On/OFF (1: OFF, 0: ON)
|
||||
if (((reg_byte[1] >> 7) & 0x01) == 0x01) result |= (ushort)(1 << 12); // reserved
|
||||
|
||||
return (short)result;
|
||||
}
|
||||
|
||||
private static short MakeProtectData_AMG(short reg_value)
|
||||
{
|
||||
byte[] reg_byte = new byte[2];
|
||||
ushort result = 0;
|
||||
|
||||
reg_byte[1] = (byte)(reg_value >> 8);
|
||||
reg_byte[0] = (byte)(reg_value >> 0);
|
||||
|
||||
if (((reg_byte[0] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 4); // Cell Over Voltage
|
||||
if (((reg_byte[0] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 2); // Pack Over Voltage
|
||||
if (((reg_byte[0] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 5); // Cell Under Voltage
|
||||
if (((reg_byte[0] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 3); // Pack Under Voltage
|
||||
if (((reg_byte[0] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 6); // Cha Over Current 1
|
||||
if (((reg_byte[0] >> 5) & 0x01) == 0x01) result |= (ushort)(1 << 6); // Cha Over Current 2
|
||||
if (((reg_byte[0] >> 6) & 0x01) == 0x01) result |= (ushort)(1 << 7); // Dch Over Current 1
|
||||
if (((reg_byte[0] >> 7) & 0x01) == 0x01) result |= (ushort)(1 << 7); // Dch Over Current 2
|
||||
|
||||
if (((reg_byte[1] >> 0) & 0x01) == 0x01) result |= (ushort)(1 << 8); // SC Protect / CB off
|
||||
if (((reg_byte[1] >> 1) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Chg Over Temperature
|
||||
if (((reg_byte[1] >> 2) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Chg Under Temperature
|
||||
if (((reg_byte[1] >> 3) & 0x01) == 0x01) result |= (ushort)(1 << 0); // Dch Over Temperature
|
||||
if (((reg_byte[1] >> 4) & 0x01) == 0x01) result |= (ushort)(1 << 1); // Dch Under Temperature
|
||||
|
||||
return (short)result;
|
||||
}
|
||||
|
||||
private static void MakeAlarm(ref DeviceSystemData rSystemData)
|
||||
{
|
||||
if (((rSystemData.StatusData.faultstatus >> 14) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 4; // Anti-theft Gyroscope
|
||||
}
|
||||
else if (((rSystemData.StatusData.faultstatus >> 15) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 5; // Anti-theft Comm.
|
||||
}
|
||||
else if (rSystemData.StatusData.protection != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 2;
|
||||
}
|
||||
else if (rSystemData.StatusData.warning != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetHoldingRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
//100 ~111 : Model_Product Name
|
||||
case 100:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 104:
|
||||
case 105:
|
||||
case 106:
|
||||
case 107:
|
||||
case 108:
|
||||
case 109:
|
||||
case 110:
|
||||
case 111:
|
||||
int mReg = reg_addr - 100;
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 111)
|
||||
{
|
||||
rSystemData.Information.ModelName = Encoding.Default.GetString(rSystemData.Information.Model_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//112 ~114 : FW Version
|
||||
case 112:
|
||||
case 113:
|
||||
case 114:
|
||||
int fReg = reg_addr - 112;
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 114)
|
||||
{
|
||||
rSystemData.Information.SwProductRev = Encoding.Default.GetString(rSystemData.Information.FwVer_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//115 ~ 122 : BMS Serial number
|
||||
case 115:
|
||||
case 116:
|
||||
case 117:
|
||||
case 118:
|
||||
case 119:
|
||||
case 120:
|
||||
case 121:
|
||||
case 122:
|
||||
int snReg = reg_addr - 115;
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 122)
|
||||
{
|
||||
rSystemData.Information.HwSerialNumber = Encoding.Default.GetString(rSystemData.Information.BMS_SN).Trim('\0');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetInputRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x0FFF:
|
||||
rSystemData.ValueData.voltageOfPack = (short)(reg_value / 10);
|
||||
rSystemData.active = true;
|
||||
break; // 48.00V = 4800
|
||||
case 0x1000: rSystemData.ValueData.current = (short)(reg_value - CURRENT_OFFSET); break; // 100.0A = 1000 -10000 = 0;
|
||||
case 0x1001: rSystemData.ValueData.remainingCapacity = (short)(reg_value / 1); break; // 100.0Ah = 1000
|
||||
case 0x1002: rSystemData.ValueData.Ext1Temperature = (short)(reg_value - TEMP_OFFSET); break; // 10.0C = 100
|
||||
case 0x1003: rSystemData.ValueData.Ext2Temperature = (short)(reg_value - TEMP_OFFSET); break; // 10.0C = 100
|
||||
|
||||
case 0x1004: rSystemData.StatusData.warning = MakeWarningData_AMG(reg_value); break; // Warning Status
|
||||
case 0x1005: rSystemData.StatusData.protection = MakeProtectData_AMG(reg_value); break; // Protection Status
|
||||
case 0x1006: // Fault Status
|
||||
rSystemData.StatusData.faultstatus = (short)(reg_value / 1);
|
||||
rSystemData.StatusData.status = (short)((reg_value >> 8) & 0x0003);
|
||||
MakeAlarm(ref rSystemData);
|
||||
break; // Fault Status
|
||||
|
||||
case 0x1007: rSystemData.ValueData.rSOC = (short)(reg_value / 10); break; // 100.00% = 10000
|
||||
case 0x1008: rSystemData.ValueData.stateOfHealth = (short)(reg_value / 10); break; // 100.00% = 10000
|
||||
|
||||
case 0x1009: rSystemData.ValueData.fullChargeCapacity = (short)(reg_value / 1); break; // 100.0Ah = 1000
|
||||
case 0x100A: rSystemData.ValueData.cycleCount = (short)(reg_value / 1); break; // 100 cycles = 100
|
||||
case 0x100B: rSystemData.ValueData.NumOfCells = (short)(reg_value / 1); break; // 15 cells = 15
|
||||
case 0x100C:
|
||||
case 0x100D:
|
||||
case 0x100E:
|
||||
case 0x100F:
|
||||
case 0x1010:
|
||||
case 0x1011:
|
||||
case 0x1012:
|
||||
case 0x1013:
|
||||
case 0x1014:
|
||||
case 0x1015:
|
||||
case 0x1016:
|
||||
case 0x1017:
|
||||
case 0x1018:
|
||||
case 0x1019:
|
||||
case 0x101A:
|
||||
case 0x101B: // 3.256V = 3256
|
||||
int cNo = reg_addr - 0x100C;
|
||||
if (cNo < 15)
|
||||
{ rSystemData.ValueData.CellVoltage[cNo] = (ushort)(reg_value / 1); }
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref rSystemData, 15);
|
||||
break; // 100.00% = 10000
|
||||
case 0x101C: rSystemData.ValueData.NumOfTemps = (short)(reg_value / 1); break; // 5 temps = 5
|
||||
case 0x101D:
|
||||
case 0x101E:
|
||||
case 0x101F:
|
||||
case 0x1020: // 25.3C = 253 - 400 = -147 (Offset -400)
|
||||
int tNo = reg_addr - 0x101D;
|
||||
rSystemData.ValueData.CellTemperature[tNo] = (short)(reg_value - TEMP_OFFSET);
|
||||
csUtils.MakeMaxAvgMinTemperature(ref rSystemData, 4);
|
||||
break; // 100.00% = 10000
|
||||
case 0x1021: rSystemData.MaxValue.MaxChgCurrent = (short)(reg_value); break; // Max. Charge Current
|
||||
case 0x1022: rSystemData.MaxValue.MaxChgTemperature = (short)(reg_value - TEMP_OFFSET); break; // Max. Charge Temperature
|
||||
case 0x1023: rSystemData.MaxValue.MinChgTemperature = (short)(reg_value - TEMP_OFFSET); break; // Min. Charge Temperature
|
||||
case 0x1024: rSystemData.MaxValue.FloatChgVolt = (short)(reg_value / 10); break; // Float Charge Current
|
||||
case 0x1025: rSystemData.MaxValue.BoostChgVolt = (short)(reg_value / 10); break; // Boost Charge Current
|
||||
|
||||
case 0x3000: rSystemData.CalibrationData.AntiTheftComm.TimeOut = (short)(reg_value / 1); break;
|
||||
case 0x3002: rSystemData.CalibrationData.AntiTheftComm.FuncSwitch = (short)(reg_value / 1); break;
|
||||
|
||||
case 0x4000: rSystemData.CalibrationData.AntiTheftGyro.XAxis = (short)(reg_value / 1); break;
|
||||
case 0x4001: rSystemData.CalibrationData.AntiTheftGyro.YAxis = (short)(reg_value / 1); break;
|
||||
case 0x4002: rSystemData.CalibrationData.AntiTheftGyro.ZAxis = (short)(reg_value / 1); break;
|
||||
case 0x4003: rSystemData.CalibrationData.AntiTheftGyro.GyroPolicySel = (short)(reg_value / 1); break;
|
||||
case 0x4004: rSystemData.CalibrationData.AntiTheftGyro.GyroFuncSwitch = (short)(reg_value / 1); break;
|
||||
case 0x4006: rSystemData.CalibrationData.AntiTheftGyro.GyroState = (short)(reg_value / 1); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetSP1Register(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x4000: rSystemData.GyroValue.X_axis = (short)(reg_value); break; //
|
||||
case 0x4001: rSystemData.GyroValue.Y_axis = (short)(reg_value); break; //
|
||||
case 0x4002: rSystemData.GyroValue.Z_axis = (short)(reg_value); break; //
|
||||
case 0x4003: rSystemData.GyroValue.Gyro_policy_sel = (short)(reg_value); break; //
|
||||
case 0x4004: rSystemData.GyroValue.Gyro_func_sw = (short)(reg_value); break; //
|
||||
case 0x4006: rSystemData.GyroValue.Gyro_state = (short)(reg_value); break; //
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void SetSP2Register(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x3000: rSystemData.GyroValue.X_axis = (short)(reg_value); break; //
|
||||
case 0x3002: rSystemData.GyroValue.Y_axis = (short)(reg_value); break; //
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void SetReadIdRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x4000: rSystemData.GyroValue.X_axis = (short)(reg_value); break; //
|
||||
case 0x4001: rSystemData.GyroValue.Y_axis = (short)(reg_value); break; //
|
||||
case 0x4002: rSystemData.GyroValue.Z_axis = (short)(reg_value); break; //
|
||||
case 0x4003: rSystemData.GyroValue.Gyro_policy_sel = (short)(reg_value); break; //
|
||||
case 0x4004: rSystemData.GyroValue.Gyro_func_sw = (short)(reg_value); break; //
|
||||
case 0x4006: rSystemData.GyroValue.Gyro_state = (short)(reg_value); break; //
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetCoilRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x3078:
|
||||
rSystemData.StatusData.relayStatus = reg_value;
|
||||
rSystemData.CalibrationData.FetCalib.FetStatus = reg_value;
|
||||
break;
|
||||
case 0x502E:
|
||||
rSystemData.CalibrationData.Current.ChargeOption = reg_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static short MakeUartWarningData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x0200:SOC Low
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short MakeUartTripData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Temprature
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Temprature
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Temprature
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Temprature
|
||||
if (bAlarm[13] == true) result |= (short)(1 << 9); // 0x0200:Short Circuit Protection
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short MakeUartErrorData(short rdata, short cdata)
|
||||
{
|
||||
short result = cdata;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 9); // 0x0001:Voltage error
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 9); // 0x0002:Temperature error
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 9); // 0x0004: 电流检测Error
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 9); // 0x0010:Cell unbalance
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
191
LFP_Manager/Function/csExcelExport.cs
Normal file
191
LFP_Manager/Function/csExcelExport.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Data.OleDb;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
public static class csExcelExport
|
||||
{
|
||||
public static void ExportToExcel(this DataTable dataTable, String filePath, bool overwiteFile = true)
|
||||
{
|
||||
if (Directory.Exists(Path.GetDirectoryName(filePath)) == false)
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
|
||||
if (File.Exists(filePath) && overwiteFile)
|
||||
File.Delete(filePath);
|
||||
|
||||
//var conn = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=0';", filePath);
|
||||
var conn = "";
|
||||
|
||||
if (filePath.IndexOf(".xlsx") > -1) // 확장자에 따라서 provider 주의
|
||||
conn = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=Yes;IMEX=3';", filePath);
|
||||
else
|
||||
conn = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=3';", filePath);
|
||||
|
||||
using (OleDbConnection connection = new OleDbConnection(conn))
|
||||
{
|
||||
connection.Open();
|
||||
using (OleDbCommand command = new OleDbCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
List<String> columnNames = new List<string>();
|
||||
List<String> columnTypes = new List<string>();
|
||||
foreach (DataColumn dataColumn in dataTable.Columns)
|
||||
{
|
||||
columnNames.Add(dataColumn.ColumnName);
|
||||
string tName = "VARCHAR";
|
||||
switch (dataColumn.DataType.Name)
|
||||
{
|
||||
case "Int16": tName = "INTEGER"; break;
|
||||
case "Int32": tName = "INTEGER"; break;
|
||||
case "Int64": tName = "INTEGER"; break;
|
||||
case "Double": tName = "DOUBLE"; break;
|
||||
case "String": tName = "VARCHAR"; break;
|
||||
default: tName = dataColumn.DataType.Name; break;
|
||||
}
|
||||
columnTypes.Add(tName);
|
||||
}
|
||||
String tableName = !String.IsNullOrWhiteSpace(dataTable.TableName) ? dataTable.TableName : Guid.NewGuid().ToString();
|
||||
//command.CommandText = @"CREATE TABLE [{tableName}] ({String.Join(",", columnNames.Select(c => $"[{c}] VARCHAR").ToArray())});";
|
||||
//string join = String.Join(",", columnNames.Select(c => String.Format("[{0}] VARCHAR", c)).ToArray());
|
||||
string join = "";
|
||||
for (int i = 0; i < columnNames.Count; i++)
|
||||
{
|
||||
join += String.Format("[{0}] {1}", columnNames[i], columnTypes[i]);
|
||||
if (i < (columnNames.Count - 1)) join += ",";
|
||||
}
|
||||
command.CommandText = String.Format("CREATE TABLE [{0}] ({1});",
|
||||
tableName,
|
||||
join
|
||||
);
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
foreach (DataRow row in dataTable.Rows)
|
||||
{
|
||||
List<String> rowValues = new List<string>();
|
||||
foreach (DataColumn column in dataTable.Columns)
|
||||
{
|
||||
rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? row[column].ToString() : String.Empty);
|
||||
}
|
||||
//command.CommandText = $"INSERT INTO [{tableName}]({String.Join(",", columnNames.Select(c => $"[{c}]"))}) VALUES ({String.Join(",", rowValues.Select(r => $"'{r}'").ToArray())});";
|
||||
string a = String.Join(",", columnNames.Select(c => String.Format("[{0}]", c)));
|
||||
string b = String.Join(",", rowValues.Select(r => String.Format("'{0}'", (r == "") ? "0" : r)).ToArray());
|
||||
command.CommandText = String.Format("INSERT INTO [{0}]({1}) VALUES ({2});", tableName, a, b);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExportToExcelExt(this DataTable dataTable, String filePath, bool overwiteFile = true)
|
||||
{
|
||||
string result = String.Empty;
|
||||
|
||||
Forms.fmxWait WaitForm = new Forms.fmxWait();
|
||||
WaitForm.StartPosition = FormStartPosition.CenterScreen;
|
||||
WaitForm.ShowOnTopMode = DevExpress.XtraWaitForm.ShowFormOnTopMode.AboveParent;
|
||||
|
||||
WaitForm.Show();
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(Path.GetDirectoryName(filePath)) == false)
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
|
||||
if (File.Exists(filePath) && overwiteFile)
|
||||
File.Delete(filePath);
|
||||
|
||||
//var conn = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=0';", filePath);
|
||||
var conn = "";
|
||||
|
||||
if (filePath.IndexOf(".xlsx") > -1) // 확장자에 따라서 provider 주의
|
||||
conn = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=Yes;IMEX=3';", filePath);
|
||||
else
|
||||
conn = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR=Yes;IMEX=3';", filePath);
|
||||
|
||||
using (OleDbConnection connection = new OleDbConnection(conn))
|
||||
{
|
||||
connection.Open();
|
||||
using (OleDbCommand command = new OleDbCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
List<String> columnNames = new List<string>();
|
||||
List<String> columnTypes = new List<string>();
|
||||
foreach (DataColumn dataColumn in dataTable.Columns)
|
||||
{
|
||||
columnNames.Add(dataColumn.ColumnName);
|
||||
string tName = "VARCHAR";
|
||||
switch (dataColumn.DataType.Name)
|
||||
{
|
||||
case "Boolean": tName = "VARCHAR"; break;
|
||||
case "Int16": tName = "INTEGER"; break;
|
||||
case "Int32": tName = "INTEGER"; break;
|
||||
case "Int64": tName = "INTEGER"; break;
|
||||
case "Double": tName = "DOUBLE"; break;
|
||||
case "Decimal": tName = "DOUBLE"; break;
|
||||
case "String": tName = "VARCHAR"; break;
|
||||
default: tName = dataColumn.DataType.Name; break;
|
||||
}
|
||||
columnTypes.Add(tName);
|
||||
}
|
||||
String tableName = !String.IsNullOrWhiteSpace(dataTable.TableName) ? dataTable.TableName : Guid.NewGuid().ToString();
|
||||
//command.CommandText = @"CREATE TABLE [{tableName}] ({String.Join(",", columnNames.Select(c => $"[{c}] VARCHAR").ToArray())});";
|
||||
//string join = String.Join(",", columnNames.Select(c => String.Format("[{0}] VARCHAR", c)).ToArray());
|
||||
string join = "";
|
||||
for (int i = 0; i < columnNames.Count; i++)
|
||||
{
|
||||
join += String.Format("[{0}] {1}", columnNames[i], columnTypes[i]);
|
||||
if (i < (columnNames.Count - 1)) join += ",";
|
||||
}
|
||||
command.CommandText = String.Format("CREATE TABLE [{0}] ({1});",
|
||||
tableName,
|
||||
join
|
||||
);
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
int rNo = 0;
|
||||
|
||||
foreach (DataRow row in dataTable.Rows)
|
||||
{
|
||||
List<String> rowValues = new List<string>();
|
||||
foreach (DataColumn column in dataTable.Columns)
|
||||
{
|
||||
rowValues.Add((row[column] != null && row[column] != DBNull.Value) ? row[column].ToString().Trim('\0') : String.Empty);
|
||||
}
|
||||
//command.CommandText = $"INSERT INTO [{tableName}]({String.Join(",", columnNames.Select(c => $"[{c}]"))}) VALUES ({String.Join(",", rowValues.Select(r => $"'{r}'").ToArray())});";
|
||||
string a = String.Join(",", columnNames.Select(c => String.Format("[{0}]", c)));
|
||||
string b = String.Join(",", rowValues.Select(r => String.Format("'{0}'", (r == "") ? "0" : r)).ToArray());
|
||||
|
||||
command.CommandText = String.Format("INSERT INTO [{0}]({1}) VALUES ({2});", tableName, a, b);
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
rNo++;
|
||||
|
||||
WaitForm.SetDescription(String.Format("{0}//{1}", rNo, dataTable.Rows.Count));
|
||||
Application.DoEvents();
|
||||
}
|
||||
}
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
WaitForm.Close();
|
||||
|
||||
if (result != String.Empty)
|
||||
throw new Exception(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
145
LFP_Manager/Function/csExcelFunction.cs
Normal file
145
LFP_Manager/Function/csExcelFunction.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using System.Data.OleDb;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
public class csExcelFunction
|
||||
{
|
||||
public static DataTable[] ExcelImport(string Ps_FileName, string[] sheetName)
|
||||
{
|
||||
DataTable[] result = null;
|
||||
|
||||
try
|
||||
{
|
||||
string ExcelConn = string.Empty;
|
||||
|
||||
if (Ps_FileName.IndexOf(".xlsx") > -1) // 확장자에 따라서 provider 주의
|
||||
{
|
||||
ExcelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Ps_FileName
|
||||
+ ";Extended Properties='Excel 12.0;HDR=YES'";
|
||||
}
|
||||
else
|
||||
{
|
||||
ExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Ps_FileName
|
||||
+ ";Extended Properties='Excel 8.0;HDR=YES'";
|
||||
}
|
||||
|
||||
// 첫 번째 시트의 이름을 가져옮
|
||||
using (OleDbConnection con = new OleDbConnection(ExcelConn))
|
||||
{
|
||||
using (OleDbCommand cmd = new OleDbCommand())
|
||||
{
|
||||
cmd.Connection = con;
|
||||
con.Open();
|
||||
|
||||
DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
|
||||
|
||||
if (dtExcelSchema.Rows.Count > 0)
|
||||
{
|
||||
sheetName = new string[dtExcelSchema.Rows.Count];
|
||||
|
||||
for (int i = 0; i < dtExcelSchema.Rows.Count; i++)
|
||||
sheetName[i] = dtExcelSchema.Rows[i]["TABLE_NAME"].ToString();
|
||||
}
|
||||
con.Close();
|
||||
}
|
||||
}
|
||||
string msg = string.Empty;
|
||||
for (int i = 0; i < sheetName.Length; i++)
|
||||
msg += sheetName[i] + "\r\n";
|
||||
//MessageBox.Show("sheetName = " + msg);
|
||||
|
||||
// 첫 번째 쉬트의 데이타를 읽어서 datagridview 에 보이게 함.
|
||||
using (OleDbConnection con = new OleDbConnection(ExcelConn))
|
||||
{
|
||||
using (OleDbCommand cmd = new OleDbCommand())
|
||||
{
|
||||
using (OleDbDataAdapter oda = new OleDbDataAdapter())
|
||||
{
|
||||
result = new DataTable[sheetName.Length];
|
||||
|
||||
for (int i = 0; i < sheetName.Length; i++)
|
||||
{
|
||||
result[i] = new DataTable();
|
||||
result[i].TableName = sheetName[i];
|
||||
cmd.CommandText = "SELECT * From [" + sheetName[i] + "]";
|
||||
cmd.Connection = con;
|
||||
con.Open();
|
||||
oda.SelectCommand = cmd;
|
||||
try
|
||||
{
|
||||
oda.Fill(result[i]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//MessageBox.Show(e1.Message);
|
||||
}
|
||||
con.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void ExcelExport(string Ps_FileName, string[] sheetName)
|
||||
{
|
||||
string ExcelConn = string.Empty;
|
||||
|
||||
if (Ps_FileName.IndexOf(".xlsx") > -1) // 확장자에 따라서 provider 주의
|
||||
{
|
||||
ExcelConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Ps_FileName
|
||||
+ ";Extended Properties='Excel 12.0;HDR=YES;IMEX=3;READONLY=FALSE'";
|
||||
}
|
||||
else
|
||||
{
|
||||
ExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Ps_FileName
|
||||
+ ";Extended Properties='Excel 8.0;HDR=YES;IMEX=3;READONLY=FALSE'";
|
||||
}
|
||||
|
||||
// 첫 번째 시트의 이름을 가져옮
|
||||
using (OleDbConnection con = new OleDbConnection(ExcelConn))
|
||||
{
|
||||
using (OleDbCommand cmd = new OleDbCommand())
|
||||
{
|
||||
cmd.Connection = con;
|
||||
con.Open();
|
||||
|
||||
DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
|
||||
|
||||
if (dtExcelSchema.Rows.Count > 0)
|
||||
{
|
||||
sheetName = new string[dtExcelSchema.Rows.Count];
|
||||
|
||||
for (int i = 0; i < dtExcelSchema.Rows.Count; i++)
|
||||
sheetName[i] = dtExcelSchema.Rows[i]["TABLE_NAME"].ToString();
|
||||
}
|
||||
con.Close();
|
||||
}
|
||||
}
|
||||
using (OleDbConnection connection =
|
||||
new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + @"C:\Users\[...]\Classeur.xls"
|
||||
+ ";Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1;READONLY=FALSE\""))
|
||||
{
|
||||
connection.Open();
|
||||
OleDbCommand commande = new OleDbCommand(
|
||||
"INSERT INTO [Feuil1$](F1,F2,F3) VALUES ('A3','B3','C3');", connection);
|
||||
commande.ExecuteNonQuery();
|
||||
|
||||
connection.Close();
|
||||
connection.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
LFP_Manager/Function/csHistoryFunction.cs
Normal file
120
LFP_Manager/Function/csHistoryFunction.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Data;
|
||||
|
||||
using System.Data.SQLite;
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class csHistoryFunction
|
||||
{
|
||||
#region DB CREATE
|
||||
|
||||
public static void DbCreate(string mPath)
|
||||
{
|
||||
string dbFilename = mPath + csDbConstData.DataBase.FileName;
|
||||
|
||||
if (Directory.Exists(System.IO.Path.GetDirectoryName(dbFilename)) == false)
|
||||
Directory.CreateDirectory(System.IO.Path.GetDirectoryName(dbFilename));
|
||||
|
||||
if (File.Exists(dbFilename) == false)
|
||||
// Create database
|
||||
SQLiteConnection.CreateFile(dbFilename);
|
||||
|
||||
// Open database
|
||||
string strConn = @"Data Source=" + dbFilename;
|
||||
using (var connection = new SQLiteConnection(strConn))
|
||||
{
|
||||
connection.Open();
|
||||
try
|
||||
{
|
||||
// Create table
|
||||
using (SQLiteCommand command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = csDbConstData.DataBase.CreateTable;
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DB INSERT DATA
|
||||
private void IDInsert(DataTable aData, string mPath, string Quary)
|
||||
{
|
||||
string dbFilename = mPath + csDbConstData.DataBase.FileName;
|
||||
|
||||
// Open database
|
||||
string strConn = @"Data Source=" + dbFilename;
|
||||
using (var connection = new SQLiteConnection(strConn))
|
||||
{
|
||||
connection.Open();
|
||||
try
|
||||
{
|
||||
// Insert data
|
||||
using (SQLiteCommand command = connection.CreateCommand())
|
||||
{
|
||||
//WaitForm.ShowWaitForm();
|
||||
|
||||
command.CommandText = "BEGIN;"; //명시적 트렌젝션 시작
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
//sSQL = "insert into TrendTable ( TrendStamp, TagName, TagValue) Values ( " + IntToStr(stamp) + "," + name + "," + value + ");";
|
||||
//command.CommandText = "INSERT INTO " + csDbConstData.DataBase.TableName + "(id) " + " Values (@id);";
|
||||
command.CommandText = Quary;
|
||||
SQLiteParameter p = new SQLiteParameter("@id", DbType.String);
|
||||
|
||||
command.Parameters.Add(p);
|
||||
|
||||
for (int i = 0; i < aData.Rows.Count; i++)
|
||||
{
|
||||
p.Value = String.Format("{0}", aData.Rows[i][0].ToString()); // id
|
||||
|
||||
try
|
||||
{
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//MessageBox.Show(e1.ToString() + ":" + i.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
//System.Windows.Forms.Application.DoEvents();
|
||||
//WaitForm.SetWaitFormDescription(String.Format("{0}//{1}", i, aData.Rows.Count));
|
||||
}
|
||||
}
|
||||
command.CommandText = "COMMIT;"; //명시적 트렌젝션 시작
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
//WaitForm.CloseWaitForm();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//MessageBox.Show(e.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
199
LFP_Manager/Function/csIniControlFunction.cs
Normal file
199
LFP_Manager/Function/csIniControlFunction.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class csIniControlFunction
|
||||
{
|
||||
#region [Function] INI File Read Function(Section Setting)
|
||||
public static string[] GetIniValue(string Section, string path)
|
||||
{
|
||||
byte[] ba = new byte[5000];
|
||||
uint Flag = GetPrivateProfileSection(Section, ba, 5000, path);
|
||||
return Encoding.Default.GetString(ba).Split(new char[1] { '\0' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region [Function] INI File Read Function(Section and Key Setting)
|
||||
public static string GetIniValue(string Section, string key, string path)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(500);
|
||||
int Flag = GetPrivateProfileString(Section, key, "", sb, 500, path);
|
||||
return sb.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region [Function] INI File Read Function(Section, Key, Value, Address Setting)
|
||||
public bool SetIniValue(string Section, string Key, string Value, string path)
|
||||
{
|
||||
return (WritePrivateProfileString(Section, Key, Value, path));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region [DLL Function] INI DLL Load
|
||||
[DllImport("kernel32")]
|
||||
public static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
|
||||
[DllImport("kernel32")]
|
||||
public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
|
||||
[DllImport("kernel32")]
|
||||
public static extern uint GetPrivateProfileInt(string lpAppName, string lpKeName, int nDefault, string lpFileName);
|
||||
[DllImport("kernel32")]
|
||||
public static extern uint GetPrivateProfileSection(string lpAppName, byte[] lpPairValues, uint nSize, string lpFileName);
|
||||
[DllImport("kernel32")]
|
||||
public static extern uint GetPrivateProfileSectionNames(byte[] lpSections, uint nSize, string lpFileName);
|
||||
#endregion
|
||||
|
||||
public static DateTime Delay(int MS)
|
||||
{
|
||||
DateTime thisMoment = DateTime.Now;
|
||||
TimeSpan duration = new TimeSpan(0, 0, 0, 0, MS);
|
||||
DateTime afterMoment = thisMoment.Add(duration);
|
||||
|
||||
while (afterMoment >= thisMoment)
|
||||
{
|
||||
System.Windows.Forms.Application.DoEvents();
|
||||
|
||||
thisMoment = DateTime.Now;
|
||||
}
|
||||
|
||||
return DateTime.Now;
|
||||
}
|
||||
|
||||
public static void IniLoad(string AppPath, ref CommConfig rConfig)
|
||||
{
|
||||
string path;
|
||||
|
||||
path = System.IO.Path.GetDirectoryName(AppPath);
|
||||
|
||||
if (File.Exists(String.Format("{0}\\CommSet.ini", path)))
|
||||
{
|
||||
StringBuilder ret = new StringBuilder();
|
||||
string InIPath = String.Format("{0}\\CommSet.ini", path);
|
||||
|
||||
// CommType = 0: RS-485, 1: SNMP
|
||||
rConfig.CommType = (int)csIniControlFunction.GetPrivateProfileInt("COMM TYPE", "TYPE", 0, InIPath);
|
||||
|
||||
// SNMP Config
|
||||
// IP
|
||||
ret.Clear();
|
||||
csIniControlFunction.GetPrivateProfileString("SNMP", "IP", "(NONE)", ret, 32, InIPath);
|
||||
rConfig.SnmpIP = ret.ToString();
|
||||
// Model
|
||||
rConfig.SnmpModelIndex = (int)csIniControlFunction.GetPrivateProfileInt("SNMP", "MODEL", 2, InIPath);
|
||||
|
||||
// Serial Port Config
|
||||
// PORT
|
||||
ret.Clear();
|
||||
csIniControlFunction.GetPrivateProfileString("UART", "PORT", "(NONE)", ret, 32, InIPath);
|
||||
rConfig.UartPort = ret.ToString();
|
||||
// MODEL
|
||||
rConfig.UartModelIndex = (int)csIniControlFunction.GetPrivateProfileInt("UART", "MODEL", 0, InIPath);
|
||||
|
||||
// Module Qunatity = 1 - 16
|
||||
rConfig.ModuleQty = (int)csIniControlFunction.GetPrivateProfileInt("UART", "MODULE_QTY", 1, InIPath);
|
||||
|
||||
// PROTOCOL
|
||||
rConfig.UartProtocol = (int)csIniControlFunction.GetPrivateProfileInt("UART", "PROTOCOL", 0, InIPath);
|
||||
|
||||
// PROTOCOL
|
||||
rConfig.RecvWaitTime = (int)csIniControlFunction.GetPrivateProfileInt("UART", "RECV_WAIT_TIME", 1500, InIPath);
|
||||
|
||||
// Etc. Config
|
||||
rConfig.DbLogPeriod = (int)csIniControlFunction.GetPrivateProfileInt("DATABASE", "LOG_PERIOD", 1, InIPath);
|
||||
|
||||
// Gyro. Config
|
||||
rConfig.GyroSensitive = (int)csIniControlFunction.GetPrivateProfileInt("GYRO", "SENSITIVITY", 120, InIPath);
|
||||
|
||||
try
|
||||
{
|
||||
// ENABLE PASSWORD
|
||||
ret.Clear();
|
||||
csIniControlFunction.GetPrivateProfileString("PW", "MASTER", CsCryptoHelper.Encrypt("8003"), ret, 32, InIPath);
|
||||
rConfig.MasterPw = CsCryptoHelper.Decrypt(ret.ToString());
|
||||
// DISABLE PASSWORD
|
||||
ret.Clear();
|
||||
csIniControlFunction.GetPrivateProfileString("PW", "ENGINEER", CsCryptoHelper.Encrypt("7003"), ret, 32, InIPath);
|
||||
rConfig.EngineerPw = CsCryptoHelper.Decrypt(ret.ToString());
|
||||
// LEVEL PASSWORD
|
||||
ret.Clear();
|
||||
csIniControlFunction.GetPrivateProfileString("PW", "TECHNICIAN", CsCryptoHelper.Encrypt("6003"), ret, 32, InIPath);
|
||||
rConfig.TechnicianPw = CsCryptoHelper.Decrypt(ret.ToString());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
rConfig.MasterPw = "8003";
|
||||
rConfig.EngineerPw = "7003";
|
||||
rConfig.TechnicianPw = "6003";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rConfig.CommType = 0;
|
||||
|
||||
rConfig.SnmpIP = "192.168.0.200";
|
||||
rConfig.SnmpModelIndex = 0;
|
||||
|
||||
rConfig.UartPort = "";
|
||||
rConfig.UartProtocol= 0;
|
||||
rConfig.RecvWaitTime = 1500;
|
||||
|
||||
rConfig.DbLogPeriod = 5;
|
||||
|
||||
rConfig.GyroSensitive = 120;
|
||||
|
||||
rConfig.MasterPw = "8003";
|
||||
rConfig.EngineerPw = "7003";
|
||||
rConfig.TechnicianPw = "6003";
|
||||
}
|
||||
}
|
||||
|
||||
public static void IniSave(string AppPath, CommConfig aConfig)
|
||||
{
|
||||
string path = Path.GetDirectoryName(AppPath);
|
||||
string InIPath = String.Format("{0}\\CommSet.ini", path);
|
||||
|
||||
// write ini
|
||||
|
||||
// CommType = 0: SNMP, 1: RS-485
|
||||
WritePrivateProfileString("COMM TYPE", "TYPE", aConfig.CommType.ToString(), InIPath);
|
||||
|
||||
// SNMP Config
|
||||
// IP
|
||||
WritePrivateProfileString("SNMP", "IP", aConfig.SnmpIP, InIPath);
|
||||
// Model
|
||||
WritePrivateProfileString("SNMP", "MODEL", aConfig.SnmpModelIndex.ToString(), InIPath);
|
||||
|
||||
// Serial Port Config
|
||||
// PORT
|
||||
WritePrivateProfileString("UART", "PORT", aConfig.UartPort, InIPath);
|
||||
// MODEL
|
||||
WritePrivateProfileString("UART", "MODEL", aConfig.UartModelIndex.ToString(), InIPath);
|
||||
// MODULE QTY = 1 - 16
|
||||
WritePrivateProfileString("UART", "MODULE_QTY", aConfig.ModuleQty.ToString(), InIPath);
|
||||
// PROTOCOL
|
||||
WritePrivateProfileString("UART", "PROTOCOL", aConfig.UartProtocol.ToString(), InIPath);
|
||||
// RECV_WAIT_TIME
|
||||
WritePrivateProfileString("UART", "RECV_WAIT_TIME", aConfig.RecvWaitTime.ToString(), InIPath);
|
||||
|
||||
// Etc Config
|
||||
WritePrivateProfileString("DATABASE", "LOG_PERIOD", aConfig.DbLogPeriod.ToString(), InIPath);
|
||||
|
||||
// Gyro Config
|
||||
WritePrivateProfileString("GYRO", "SENSITIVITY", aConfig.GyroSensitive.ToString(), InIPath);
|
||||
|
||||
// MASTER PASSWORD
|
||||
WritePrivateProfileString("PW", "MASTER", CsCryptoHelper.Encrypt(aConfig.MasterPw), InIPath);
|
||||
// ENGINEER PASSWORD
|
||||
WritePrivateProfileString("PW", "ENGINEER", CsCryptoHelper.Encrypt(aConfig.EngineerPw), InIPath);
|
||||
// TECHNICIAN PASSWORD
|
||||
WritePrivateProfileString("PW", "TECHNICIAN", CsCryptoHelper.Encrypt(aConfig.TechnicianPw), InIPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
308
LFP_Manager/Function/csMakeDataFunction.cs
Normal file
308
LFP_Manager/Function/csMakeDataFunction.cs
Normal file
@@ -0,0 +1,308 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.IO;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class csMakeDataFunction
|
||||
{
|
||||
private static DeviceSystemData MakeAlarmTripData(int id, short ndata, DeviceSystemData rSystemData)
|
||||
{
|
||||
bool[] aData = csUtils.Int16ToBitArray(ndata);
|
||||
short bFault = rSystemData.StatusData.protection;
|
||||
short bWarning = rSystemData.StatusData.warning;
|
||||
int i = 0;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case 0: // Warning
|
||||
if (aData[i++]) bWarning |= (1 << 2); // Bit 0 : Over voltage warning
|
||||
else bWarning &= ~(1 << 2);
|
||||
if (aData[i++]) bWarning |= (1 << 4); // Bit 1 : Cell Over voltage warning
|
||||
else bWarning &= ~(1 << 4);
|
||||
if (aData[i++]) bWarning |= (1 << 3); // Bit 2 : Low voltage warning
|
||||
else bWarning &= ~(1 << 3);
|
||||
if (aData[i++]) bWarning |= (1 << 5); // Bit 3 : Low cell voltage warning
|
||||
else bWarning &= ~(1 << 5);
|
||||
if (aData[i++]) bWarning |= (1 << 6); // Bit 4 : Charge over current warning
|
||||
else bWarning &= ~(1 << 6);
|
||||
if (aData[i++]) bWarning |= (1 << 7); // Bit 5 : Discharge over current warning
|
||||
else bWarning &= ~(1 << 7);
|
||||
i++; // 06 Abnormal balancing current
|
||||
i++; // 07 Reserved
|
||||
if ((aData[8]) || (aData[9])) bWarning |= (1 << 0); // Bit 8 : Charge over temperature warning, Bit 9 : Discharge over temperature warning
|
||||
else bWarning &= ~(1 << 0);
|
||||
i++; // 08
|
||||
i++; // 09
|
||||
if ((aData[10]) || (aData[11])) bWarning |= (1 << 1); // Bit 10 : Charge low temperature warning, Bit 11 : Discharge low temperature warning
|
||||
else bWarning &= ~(1 << 1);
|
||||
i++; // 10
|
||||
i++; // 11
|
||||
if (aData[i++]) bWarning |= (1 << 11); // 12 : Low capacity warning
|
||||
else bWarning &= ~(1 << 11);
|
||||
i++; // 13
|
||||
if (aData[i++]) bWarning |= (1 << 9); // 14 Cell Voltage Difference Warning
|
||||
else bWarning &= ~(1 << 9);
|
||||
break;
|
||||
case 1: // Status Code 2
|
||||
if (aData[i++]) bFault |= (1 << 2); // Bit 0 : Over voltage warning
|
||||
else bFault &= ~(1 << 2);
|
||||
if (aData[i++]) bFault |= (1 << 4); // Bit 1 : Cell Over voltage warning
|
||||
else bFault &= ~(1 << 4);
|
||||
if (aData[i++]) bFault |= (1 << 3); // Bit 2 : Low voltage warning
|
||||
else bFault &= ~(1 << 3);
|
||||
if (aData[i++]) bFault |= (1 << 5); // Bit 3 : Low cell voltage warning
|
||||
else bFault &= ~(1 << 5);
|
||||
if (aData[i++]) bFault |= (1 << 6); // Bit 4 : Charge over current warning
|
||||
else bFault &= ~(1 << 6);
|
||||
if (aData[i++]) bFault |= (1 << 7); // Bit 5 : Discharge over current warning
|
||||
else bFault &= ~(1 << 7);
|
||||
i++; // 06 Abnormal balancing current
|
||||
i++; // 07 Reserved
|
||||
if ((aData[8]) || (aData[9])) bFault |= (1 << 0); // Bit 8 : Charge over temperature warning, Bit 9 : Discharge over temperature warning
|
||||
else bFault &= ~(1 << 0);
|
||||
i++; // 08
|
||||
i++; // 09
|
||||
if ((aData[10]) || (aData[11])) bFault |= (1 << 1); // Bit 10 : Charge low temperature warning, Bit 11 : Discharge low temperature warning
|
||||
else bFault &= ~(1 << 1);
|
||||
i++; // 10
|
||||
i++; // 11
|
||||
i++; // 12
|
||||
i++; // 13
|
||||
if (aData[i++]) bFault |= (1 << 9); // 14 Cell Voltage Difference Warning
|
||||
else bFault &= ~(1 << 9);
|
||||
break;
|
||||
}
|
||||
|
||||
rSystemData.StatusData.protection = bFault;
|
||||
rSystemData.StatusData.warning = bWarning;
|
||||
|
||||
return rSystemData;
|
||||
}
|
||||
|
||||
public static void SetData(int index, double sdata, ref DeviceSystemData aSystemData)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: aSystemData.ValueData.voltageOfPack = (short)(sdata / 100); break; // voltageOfPack
|
||||
case 1: aSystemData.ValueData.current = (short)(sdata / 10); break; // current
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16: aSystemData.ValueData.CellVoltage[index - 2] = (ushort)(sdata / 1); break; // CellVoltage14
|
||||
case 17: aSystemData.ValueData.CellTemperature[0] = (short)(sdata / 1); break; // CellTemperature0
|
||||
case 18: aSystemData.ValueData.CellTemperature[1] = (short)(sdata / 1); break; // CellTemperature1
|
||||
case 19: aSystemData.ValueData.CellTemperature[2] = (short)(sdata / 1); break; // CellTemperature2
|
||||
case 20: aSystemData.ValueData.CellTemperature[3] = (short)(sdata / 1); break; // CellTemperature3
|
||||
case 21: aSystemData.ValueData.rSOC = (short)(sdata / 1); break; // Relatvie State Of Charge
|
||||
case 22: aSystemData.ValueData.remainingCapacity = (short)(sdata / 1); break; // Remaining Capacity
|
||||
case 23: aSystemData.ValueData.stateOfHealth = (short)(sdata / 1); break; // stateOfHealth
|
||||
case 24: aSystemData.ValueData.cycleCount = (short)(sdata / 1); break; // cycleCount
|
||||
|
||||
case 25: aSystemData.AvgData.maxCellVoltage = (short)(sdata / 1); break; // maxCellVoltage
|
||||
case 26: aSystemData.AvgData.minCellVoltage = (short)(sdata / 1); break; // minCellVoltage
|
||||
case 27: aSystemData.AvgData.avgCellVoltage = (short)(sdata / 1); break; // avgCellVoltage
|
||||
case 28: aSystemData.AvgData.diffCellVoltage = (short)(sdata / 1); break; // diffCellVoltage
|
||||
case 29: aSystemData.StatusData.batteryStatus = (short)(sdata / 1); break; // batteryStatus
|
||||
//case 37: aSystemData.StatusData.warning = (short)(sdata / 1); break; // warning
|
||||
case 30: aSystemData = MakeAlarmTripData(0, (short)(sdata / 1), aSystemData); break; // warning
|
||||
//case 38: aSystemData.StatusData.protection = (short)(sdata / 1); break; // OID-44 protection
|
||||
case 31: aSystemData = MakeAlarmTripData(1, (short)(sdata / 1), aSystemData); break; // OID-44 protection
|
||||
case 32: aSystemData.StatusData.status = (short)(sdata / 1); break; // status
|
||||
case 33: aSystemData.StatusData.relayStatus = (short)(sdata / 1); break; // relayStatus
|
||||
case 34: aSystemData.StatusData.cellBallanceStatus = (short)(sdata / 1); break; // cellBallanceStatus
|
||||
case 35: aSystemData.StatusData.cellBalanceValue = (short)(sdata / 1); break; // cellBalanceValue
|
||||
case 36: aSystemData.StatusData.cellBalanceFlag = (short)(sdata / 1); break; // cellBalanceFlag
|
||||
case 37: aSystemData.AvgData.maxCellNum = (short)(sdata / 1); break; // maxCellNum
|
||||
case 38: aSystemData.AvgData.minCellNum = (short)(sdata / 1); break; // minCellNum
|
||||
//case 46: aSystemData.AvgData.maxTemp = (short)(sdata / 1); break; // maxTemp
|
||||
//case 47: aSystemData.AvgData.minTemp = (short)(sdata / 1); break; // minTemp
|
||||
//case 48: aSystemData.AvgData.maxTempNum = (short)(sdata / 1); break; // maxTempNum
|
||||
//case 49: aSystemData.AvgData.minTempNum = (short)(sdata / 1); break; // minTempNum
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetSnmpData(int index, object sdata, ref DeviceSystemData aSystemData)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 1: aSystemData.ValueData.voltageOfPack = (short)(Convert.ToDouble(sdata) / 10); break; // voltageOfPack - 0.01V
|
||||
case 2: aSystemData.ValueData.current = (short)(Convert.ToDouble(sdata) - 10000); break; // current - 0.1A, Offset: 10000
|
||||
case 3: // Cell Voltage #1
|
||||
case 4: // Cell Voltage #2
|
||||
case 5: // Cell Voltage #3
|
||||
case 6: // Cell Voltage #4
|
||||
case 7: // Cell Voltage #5
|
||||
case 8: // Cell Voltage #6
|
||||
case 9: // Cell Voltage #7
|
||||
case 10: // Cell Voltage #8
|
||||
case 11: // Cell Voltage #9
|
||||
case 12: // Cell Voltage #10
|
||||
case 13: // Cell Voltage #11
|
||||
case 14: // Cell Voltage #12
|
||||
case 15: // Cell Voltage #13
|
||||
case 16: // Cell Voltage #14
|
||||
case 17: aSystemData.ValueData.CellVoltage[index - 3] = (ushort)(Convert.ToDouble(sdata) / 1);
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref aSystemData, 15);
|
||||
break; // Cell Voltage #16
|
||||
|
||||
case 19: aSystemData.ValueData.Ext1Temperature = (short)(Convert.ToDouble(sdata) * 10); break; // Temp of PCB - C
|
||||
case 20: aSystemData.ValueData.Ext2Temperature = (short)(Convert.ToDouble(sdata) * 10); break; // Temp of Ambient - C
|
||||
case 21: aSystemData.AvgData.maxTemp = (short)(Convert.ToDouble(sdata) * 10); break; // Max. Temp
|
||||
|
||||
case 22: aSystemData.ValueData.remainingCapacity = (short)(Convert.ToDouble(sdata) * 1); break; // Remaining Capacity
|
||||
|
||||
case 24: aSystemData.ValueData.stateOfHealth = (short)(Convert.ToDouble(sdata) / 10); break; // stateOfHealth
|
||||
case 25: aSystemData.ValueData.rSOC = (short)(Convert.ToDouble(sdata) / 10); break; // Relatvie State Of Charge
|
||||
|
||||
case 26: aSystemData.StatusData.status = (short)(Convert.ToDouble(sdata) / 1); break; // Status
|
||||
case 27: aSystemData.StatusData.warning = MakeSnmpWarningData((short)Convert.ToDouble(sdata)); break; // warning
|
||||
case 28: aSystemData.StatusData.protection = MakeSnmpTripData((short)Convert.ToDouble(sdata)); break; // Protection
|
||||
case 29: // FaultAndStatus
|
||||
aSystemData.StatusData.faultAndStatus = (short)(Convert.ToDouble(sdata) / 1);
|
||||
//aSystemData.StatusData.status = (short)(((short)Convert.ToDouble(sdata) >> 8) & 0x0003);
|
||||
MakeAlarm(ref aSystemData);
|
||||
break;
|
||||
case 30: aSystemData.ValueData.cycleCount = (short)(Convert.ToDouble(sdata) / 1); break; // cycleCount
|
||||
|
||||
case 31: // Temperature #1
|
||||
case 32: // Temperature #2
|
||||
case 33: // Temperature #3
|
||||
case 34: // Temperature #4
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref aSystemData, 4);
|
||||
break;
|
||||
|
||||
case 37: aSystemData.cellQty = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number
|
||||
case 38: aSystemData.ValueData.designedCapacity = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number
|
||||
case 40: aSystemData.ValueData.MaxBattChargeCurr = (short)(Convert.ToDouble(sdata) * 1); break; // Max. Charge Current - A
|
||||
case 41: aSystemData.ntcQty = (short)(Convert.ToDouble(sdata) * 1); break; // NTC Number
|
||||
|
||||
case 42: aSystemData.BmsDateTime.year = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Year
|
||||
case 43: aSystemData.BmsDateTime.month = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Month
|
||||
case 44: aSystemData.BmsDateTime.day = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Day
|
||||
case 45: aSystemData.BmsDateTime.hour = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Hour
|
||||
case 46: aSystemData.BmsDateTime.minute = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Minute
|
||||
case 47: aSystemData.BmsDateTime.second = (short)(Convert.ToDouble(sdata) * 1); // BMS DateTime - Second
|
||||
aSystemData.BmsDateTime.DateTimeStr = string.Format("{0:0000}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}"
|
||||
, aSystemData.BmsDateTime.year
|
||||
, aSystemData.BmsDateTime.month
|
||||
, aSystemData.BmsDateTime.day
|
||||
, aSystemData.BmsDateTime.hour
|
||||
, aSystemData.BmsDateTime.minute
|
||||
, aSystemData.BmsDateTime.second
|
||||
);
|
||||
break;
|
||||
|
||||
case 48: aSystemData.FloatVoltage = (int)Convert.ToDouble(sdata); break; // Float Voltage - 0.01V
|
||||
case 49: aSystemData.BoostVoltage = (int)Convert.ToDouble(sdata); break; // Boost Voltage - 0.01V
|
||||
|
||||
case 50: aSystemData.MinChargeTemp = (int)Convert.ToDouble(sdata); break; // Min. Charge Temp - C
|
||||
case 51: aSystemData.MaxChargeTemp = (int)Convert.ToDouble(sdata); break; // Max. Charge Temp - C
|
||||
|
||||
case 60: aSystemData.Information.ModelName = (string)sdata; break; // Model - string
|
||||
case 61: aSystemData.Information.SwProductRev = (string)sdata; break; // BMS Fw Version - string
|
||||
case 62: aSystemData.Information.HwSerialNumber = (string)sdata; break; // Pack Serial Number - string
|
||||
case 63: aSystemData.Information.VendorName = (string)sdata; break; // Vendor Name - string
|
||||
case 64: aSystemData.Information.ProductCode = (string)sdata; break; // Product Code - string
|
||||
case 65: aSystemData.Information.MajorMinorRev = (string)sdata; break; // Major Minor Revision - string
|
||||
case 66: aSystemData.Information.HwProductRev = (string)sdata; break; // Hardware Product Revision - string
|
||||
case 67: aSystemData.Information.ManufacturingDate = (string)sdata; break; // Manufacturing Date - string
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
public static void MakeAlarm(ref DeviceSystemData rSystemData)
|
||||
{
|
||||
if (((rSystemData.StatusData.faultAndStatus >> 14) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 4; // Anti-theft Gyroscope
|
||||
}
|
||||
else if (((rSystemData.StatusData.faultAndStatus >> 15) & 0x0001) == 0x0001)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 5; // Anti-theft Comm.
|
||||
}
|
||||
else if (rSystemData.StatusData.protection != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 2;
|
||||
}
|
||||
else if (rSystemData.StatusData.warning != 0x0000)
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rSystemData.StatusData.batteryStatus = 0;
|
||||
}
|
||||
}
|
||||
public static short MakeSnmpTripData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 4); // 0x0001:Cell OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 2); // 0x0002:Pack OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 5); // 0x0004:Cell UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 3); // 0x0008:Pack UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC1
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 6); // 0x0020:Charging OC2
|
||||
if (bAlarm[6] == true) result |= (short)(1 << 7); // 0x0010:Discharging OC1
|
||||
if (bAlarm[7] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC2
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 9); // 0x0200:Short Circuit Protection
|
||||
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0080: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 0); // 0x0040: Discharging Over Tempratuer
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
|
||||
return result;
|
||||
}
|
||||
public static short MakeSnmpWarningData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 4); // 0x0001:Cell OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 5); // 0x0002:Cell UV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 2); // 0x0004:Pack OV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 3); // 0x0008:Pack UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[6] == true) result |= (short)(1 << 8); // 0x0040:ENV OT
|
||||
if (bAlarm[7] == true) result |= (short)(1 << 9); // 0x0080:ENV UT
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0100: Charging Over Temprature
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 1); // 0x0200: Charging Under Temprature
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 0); // 0x0400: Discharging Over Temprature
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0800: Discharging Under Temprature
|
||||
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x1000:SOC Low
|
||||
|
||||
if (bAlarm[13] == true) result |= (short)(1 << 13); // 0x2000:Diff Volt
|
||||
if (bAlarm[14] == true) result |= (short)(1 << 14); // 0x4000:CB Off
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
819
LFP_Manager/Function/csSerialCommFunction.cs
Normal file
819
LFP_Manager/Function/csSerialCommFunction.cs
Normal file
@@ -0,0 +1,819 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using LFP_Manager.DataStructure;
|
||||
using LFP_Manager.Utils;
|
||||
using LFP_Manager.Controls;
|
||||
using System.Web.Services.Description;
|
||||
using System.Data.Entity.Core.Common.CommandTrees;
|
||||
using DevExpress.XtraRichEdit.Fields.Expression;
|
||||
using DevExpress.XtraRichEdit.Layout;
|
||||
using DevExpress.XtraPrinting.Native.LayoutAdjustment;
|
||||
|
||||
namespace LFP_Manager.Function
|
||||
{
|
||||
class csSerialCommFunction
|
||||
{
|
||||
static readonly byte[] auchCRCHi = {
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
|
||||
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
|
||||
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
|
||||
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,0x40
|
||||
};
|
||||
|
||||
static readonly byte[] auchCRCLo = {
|
||||
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
|
||||
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
|
||||
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
|
||||
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||||
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
|
||||
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
|
||||
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
|
||||
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||||
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
|
||||
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
|
||||
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
|
||||
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||||
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
|
||||
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
|
||||
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
|
||||
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,0x40
|
||||
};
|
||||
|
||||
public const byte READ_COIL_STATUS = 0x01;
|
||||
public const byte READ_HOLDING_REG = 0x03;
|
||||
public const byte READ_INPUT_REG = 0x04; //Byul 구문 추가 필요
|
||||
public const byte FORCE_SINGLE_COIL = 0x05;
|
||||
public const byte PRESET_SINGLE_REG = 0x06;
|
||||
public const byte PRESET_MULTI_REG = 0x10;
|
||||
public const byte WRITE_COIL_REG = 0x0F;
|
||||
public const byte ERROR_REG = 0x90;
|
||||
|
||||
public const byte FW_FLASH_ERASE_CMD = 0x43;
|
||||
public const byte FW_FLASH_WRITE_CMD = 0x31;
|
||||
|
||||
public const byte NO_CMD = 0xFF;
|
||||
|
||||
public static byte[] GetCRC(byte[] pby, int nSize)
|
||||
{
|
||||
ushort uIndex, i;
|
||||
ushort crc;
|
||||
byte uchCRCHi = 0xff;
|
||||
byte uchCRCLo = 0xff;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
for (i = 0; i < nSize; i++)
|
||||
{
|
||||
uIndex = (ushort)((int)uchCRCLo ^ (int)pby[i]);
|
||||
uchCRCLo = (byte)(uchCRCHi ^ auchCRCHi[uIndex]);
|
||||
uchCRCHi = auchCRCLo[uIndex];
|
||||
}
|
||||
crc = (ushort)((uchCRCHi << 8) | uchCRCLo);
|
||||
|
||||
result[0] = (byte)(crc >> 8);
|
||||
result[1] = (byte)(crc >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeReadRegisterData(ushort DevID, ushort cmd, ushort ReadAddr, ushort Size)
|
||||
{
|
||||
byte[] result = new byte[8];
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)cmd; // Command
|
||||
result[2] = (byte)(ReadAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(ReadAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(Size >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(Size >> 0); // Count of Register LSB
|
||||
|
||||
crc = GetCRC(result, 6);
|
||||
|
||||
result[6] = crc[1]; // CRCH
|
||||
result[7] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteCoilData(ushort DevID, ushort WriteAddr, short WriteData)
|
||||
{
|
||||
byte[] result = new byte[7 + (1 * 1) + 2];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)WRITE_COIL_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(1 >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(1 >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(1 * 1); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
result[i++] = (byte)(WriteData >> 0);
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, short[] WriteData)
|
||||
{
|
||||
byte[] result = new byte[9 + (WriteData.Length * 2)];
|
||||
byte[] crc;
|
||||
ushort i = 0;
|
||||
|
||||
result[i++] = (byte)DevID; // Device ID
|
||||
result[i++] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[i++] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[i++] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[i++] = (byte)(WriteData.Length >> 8); // Count of Register MSB
|
||||
result[i++] = (byte)(WriteData.Length >> 0); // Count of Register LSB
|
||||
result[i++] = (byte)(WriteData.Length * 2); // Byte Count - [2 * (Num of register)]
|
||||
|
||||
for (int j = 0; j < WriteData.Length; j++)
|
||||
{
|
||||
result[i++] = (byte)(WriteData[j] >> 8);
|
||||
result[i++] = (byte)(WriteData[j] >> 0);
|
||||
}
|
||||
|
||||
crc = GetCRC(result, i);
|
||||
|
||||
result[i++] = crc[1]; // CRCH
|
||||
result[i++] = crc[0]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static short GetRegister(ushort reg_addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short result = 0;
|
||||
|
||||
switch (reg_addr)
|
||||
{
|
||||
//case 19: result = (short)(0 >> 16); break; // 0021 : UTC TimeStamp MSB
|
||||
//case 20: result = (short)(58 >> 0); break; // 0022 : UTC TimeStamp LSB
|
||||
//case 21: result = (short)0x1000; break; // 0023 : Cell Balancing Flag
|
||||
//case 22: result = (short)0x0000; break; // 0024 : Cell Balancing Voltage
|
||||
//case 23: result = (short)15; break; // 0024 : Cell Balancing Time
|
||||
|
||||
case 0x4002: result = (short)aParam.CellUnderVoltageWarning; break; // 0061 : Low cell voltage warning data
|
||||
//case 33: result = (short)param.sf1.voltage.CUV_Threshold; break; // 0062 : Low cell voltage protection data
|
||||
//case 34: result = (short)param.sf1.voltage.CUV_Recovery; break; // 0063 : Low cell voltage recovery data
|
||||
//case 35: result = (short)param.sf1.voltage.SUV_Warning; break; // 0064 : Low voltage warning data
|
||||
//case 36: result = (short)param.sf1.voltage.SUV_Threshold; break; // 0065 : Low voltage protection data
|
||||
//case 37: result = (short)param.sf1.voltage.SUV_Recovery; break; // 0066 : Low voltage recovery data
|
||||
//case 38: result = (short)param.sf1.voltage.COV_Warning; break; // 0067 : Over cell voltage warning data
|
||||
//case 39: result = (short)param.sf1.voltage.COV_Threshold; break; // 0068 : Over cell voltage protection data
|
||||
//case 40: result = (short)param.sf1.voltage.COV_Recovery; break; // 0069 : Over cell voltage recovery data
|
||||
//case 41: result = (short)param.sf1.voltage.SOV_Warning; break; // 0070 : Over voltage warning data
|
||||
//case 42: result = (short)param.sf1.voltage.SOV_Threshold; break; // 0071 : Over voltage protection data
|
||||
//case 43: result = (short)param.sf1.voltage.SOV_Recovery; break; // 0072 : Over voltage recovery data
|
||||
|
||||
//case 44: result = (short)param.sf1.temperature.OT_Chg_Warning; break; // 0044 : Charge over temperature warning data
|
||||
//case 45: result = (short)param.sf1.temperature.OT_Chg_Threshold; break; // 0045 : Charge over temperature protection data
|
||||
//case 46: result = (short)param.sf1.temperature.OT_Chg_Recovery; break; // 0046 : Charge over temperature recovery data
|
||||
//case 47: result = (short)param.sf1.temperature.OT_Chg_Time; break; // 0047 : Charge over temperature time
|
||||
|
||||
//case 48: result = (short)param.sf1.temperature.OT_Dsg_Warning; break; // 0048 : Discharge over temperature warning data
|
||||
//case 49: result = (short)param.sf1.temperature.OT_Dsg_Threshold; break; // 0049 : Discharge over temperature protection data
|
||||
//case 50: result = (short)param.sf1.temperature.OT_Dsg_Recovery; break; // 0050 : Discharge over temperature recovery data
|
||||
//case 51: result = (short)param.sf1.temperature.OT_Dsg_Time; break; // 0051 : Discharge over temperature time
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static byte[] ModBusGetRegWordToBytes(ushort addr, ref DeviceParamData aParam)
|
||||
{
|
||||
short data;
|
||||
byte[] result = new byte[2];
|
||||
|
||||
data = GetRegister(addr, ref aParam);
|
||||
|
||||
result[0] = (byte)(data >> 8);
|
||||
result[1] = (byte)(data >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte[] MakeWriteRegisterData(ushort DevID, ushort WriteAddr, ushort reg_len, ref DeviceParamData aParam)
|
||||
{
|
||||
int tlen = (reg_len * 2) + 7 + 2;
|
||||
byte[] result = new byte[tlen];
|
||||
byte[] tmp;
|
||||
byte[] crc;
|
||||
|
||||
result[0] = (byte)DevID; // Device ID
|
||||
result[1] = (byte)PRESET_MULTI_REG; // Command
|
||||
result[2] = (byte)(WriteAddr >> 8); // Register Address MSB
|
||||
result[3] = (byte)(WriteAddr >> 0); // Register Address LSB
|
||||
result[4] = (byte)(reg_len >> 8); // Count of Register MSB
|
||||
result[5] = (byte)(reg_len >> 0); // Count of Register LSB
|
||||
result[6] = (byte)(reg_len * 2); ; // Current Value MSB
|
||||
|
||||
for (int i = 0; i < reg_len; i++)
|
||||
{
|
||||
tmp = ModBusGetRegWordToBytes((ushort)(WriteAddr + i),ref aParam);
|
||||
result[7 + (i * 2) + 0] = tmp[0];
|
||||
result[7 + (i * 2) + 1] = tmp[1];
|
||||
}
|
||||
crc = GetCRC(result, 8);
|
||||
|
||||
result[tlen - 2] = crc[0]; // CRCH
|
||||
result[tlen - 1] = crc[1]; // CRCL
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeCheckSum(byte[] sData, int offset, int len, bool flag)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int checksum = 0;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
checksum += sData[i + offset];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
result[0] = (byte)(checksum >> 8);
|
||||
result[1] = (byte)checksum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static byte[] MakeTxPacket(byte[] sData, int len)
|
||||
{
|
||||
string str = "";
|
||||
byte[] result;
|
||||
char[] chrArray;
|
||||
int checksum = 0;
|
||||
string checksumStr = "";
|
||||
char[] checksumChr;
|
||||
|
||||
str = "~";
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
str += sData[i].ToString("X2");
|
||||
}
|
||||
|
||||
str += "\r";
|
||||
|
||||
chrArray = str.ToCharArray();
|
||||
|
||||
for (int i = 0; i < (chrArray.Length - 6); i++)
|
||||
{
|
||||
checksum += chrArray[i + 1];
|
||||
}
|
||||
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
checksumStr = String.Format("{0:X2}{1:X2}", (byte)(checksum >> 8), (byte)checksum);
|
||||
checksumChr = checksumStr.ToCharArray();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
chrArray[chrArray.Length - 5 + i] = checksumChr[i];
|
||||
}
|
||||
|
||||
result = new byte[chrArray.Length];
|
||||
|
||||
for (int i = 0; i < chrArray.Length; i++)
|
||||
{
|
||||
result[i] = (byte)chrArray[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] LengthLchk(int sLen)
|
||||
{
|
||||
byte[] result = new byte[2];
|
||||
int lchksum = 0;
|
||||
|
||||
lchksum = (~(((sLen >> 8) & 0xF) +
|
||||
((sLen >> 4) & 0xF) +
|
||||
((sLen >> 0) & 0xF)) + 1) % 16;
|
||||
lchksum = ((lchksum << 12) | sLen);
|
||||
|
||||
result[0] = (byte)(lchksum >> 8);
|
||||
result[1] = (byte)(lchksum >> 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] MakeTxData(byte addr, byte cmd, int sLen)
|
||||
{
|
||||
int buffCh = 0;
|
||||
byte[] sData;
|
||||
byte[] lenId;
|
||||
byte[] checksum;
|
||||
|
||||
sData = new byte[((sLen > 0) ? 11 : 10)];
|
||||
|
||||
sData[buffCh] = 0x7E; buffCh++; // SOI
|
||||
sData[buffCh] = 0x25; buffCh++; // VER
|
||||
sData[buffCh] = addr; buffCh++; // ADDR
|
||||
sData[buffCh] = 0x46; buffCh++; // CID1
|
||||
sData[buffCh] = cmd; buffCh++; // CID2 (CMD)
|
||||
|
||||
lenId = LengthLchk(sLen); // LENID
|
||||
sData[buffCh] = lenId[0]; buffCh++; // LENID MSB
|
||||
sData[buffCh] = lenId[1]; buffCh++; // LENID LSB
|
||||
|
||||
if (sLen > 0)
|
||||
{
|
||||
sData[buffCh] = (byte)(sLen / 2); buffCh++; // INFO
|
||||
}
|
||||
|
||||
checksum = csSerialCommFunction.MakeCheckSum(sData, 1, sData.Length - 4, false);
|
||||
|
||||
sData[buffCh] = checksum[1]; buffCh++;
|
||||
sData[buffCh] = checksum[0]; buffCh++;
|
||||
|
||||
sData[buffCh] = 0x0D; buffCh++; // EOI
|
||||
|
||||
return MakeTxPacket(sData, sData.Length);
|
||||
}
|
||||
|
||||
public static int TbPacketCheck(byte[] rdata, int rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata;
|
||||
byte[] checksum;
|
||||
byte[] checksum1;
|
||||
|
||||
checksum = MakeCheckSum(rdata, 1, rlen - 6, false);
|
||||
|
||||
checksum1 = new byte[2];
|
||||
checksum1[0] = csUtils.StrByte2toByte(rdata[rlen - 4], rdata[rlen - 5]);
|
||||
checksum1[1] = csUtils.StrByte2toByte(rdata[rlen - 2], rdata[rlen - 3]);
|
||||
|
||||
|
||||
if ((checksum[0] == checksum1[0]) && (checksum[1] == checksum1[1]))
|
||||
{
|
||||
cdata = csUtils.StrToByteArray(rdata, 0, rlen);
|
||||
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public int ModbusPacketFromSlaveCheck(byte[] rdata, ushort rlen)
|
||||
{
|
||||
int result = 0;
|
||||
byte[] cdata, crc;
|
||||
ushort clen, bytecount;
|
||||
|
||||
if (rlen > 2)
|
||||
{
|
||||
cdata = rdata;
|
||||
|
||||
switch (cdata[1])
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
case READ_HOLDING_REG:
|
||||
case READ_INPUT_REG:
|
||||
bytecount = cdata[2];
|
||||
clen = (ushort)(bytecount + 5); // header 3, tail 2
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[1] == cdata[rlen - 2]) && (crc[0] == cdata[rlen - 1])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case PRESET_MULTI_REG:
|
||||
case FORCE_SINGLE_COIL:
|
||||
case PRESET_SINGLE_REG:
|
||||
clen = 8;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case ERROR_REG:
|
||||
clen = 6;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 1;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_ERASE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
case FW_FLASH_WRITE_CMD:
|
||||
clen = 5;
|
||||
if (rlen >= clen)
|
||||
{
|
||||
crc = GetCRC(cdata, (ushort)(rlen - 2));
|
||||
if ((crc[0] == cdata[rlen - 1]) && (crc[1] == cdata[rlen - 2])) result = 2;
|
||||
else result = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static short[] SerialRxProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
short[] result = new short[2];
|
||||
|
||||
switch (rData[1])
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
ReadCoilRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_HOLDING_REG:
|
||||
ReadHoldRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
case READ_INPUT_REG:
|
||||
//ReadInputRegisterProcess(rData, rRegAddr, rLen, ref rSystemData);
|
||||
break;
|
||||
//case READ_INPUT_REG:
|
||||
// ReadRegister(rData, rRegAddr, rLen, ref rSystemData);
|
||||
// break;
|
||||
case PRESET_MULTI_REG:
|
||||
// read_holding_reg_process(reverse16(rsp->start_addr, true), reverse16(rsp->qty_reg, true));
|
||||
//result[0] = 1;
|
||||
//result[1] = 1;
|
||||
break;
|
||||
case ERROR_REG:
|
||||
result[0] = 2;
|
||||
result[1] = (short)((rData[0] << 8) | rData[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ReadCoilRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = rData[i];
|
||||
|
||||
i++;
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i + j]);
|
||||
SetCoilRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadHoldRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int i, j;
|
||||
short reg_count;
|
||||
short reg_value;
|
||||
i = 2;
|
||||
reg_count = (short)(rData[i] / 2); i += 1;
|
||||
|
||||
for (j = 0; j < reg_count; j++)
|
||||
{
|
||||
reg_value = (short)(rData[i] << 8 | rData[i + 1]);
|
||||
SetHoldRegister((short)(rRegAddr + j), reg_value, ref rSystemData);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetCoilRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0x3078:
|
||||
rSystemData.StatusData.relayStatus = reg_value;
|
||||
rSystemData.CalibrationData.FetCalib.FetStatus = reg_value;
|
||||
break;
|
||||
case 0x502E:
|
||||
rSystemData.CalibrationData.Current.ChargeOption = reg_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetHoldRegister(short reg_addr, short reg_value, ref DeviceSystemData rSystemData)
|
||||
{
|
||||
int temp = 0;
|
||||
switch (reg_addr)
|
||||
{
|
||||
case 0: rSystemData.ValueData.voltageOfPack = (short)(reg_value / 10); break; //Total Voltage
|
||||
case 1: rSystemData.ValueData.current = (short)((reg_value) / 10); break; //Total Current
|
||||
case 2: // Cell Voltage #1
|
||||
case 3: // Cell Voltage #2
|
||||
case 4: // Cell Voltage #3
|
||||
case 5: // Cell Voltage #4
|
||||
case 6: // Cell Voltage #5
|
||||
case 7: // Cell Voltage #6
|
||||
case 8: // Cell Voltage #7
|
||||
case 9: // Cell Voltage #8'
|
||||
case 10: // Cell Voltage #9
|
||||
case 11: // Cell Voltage #10
|
||||
case 12: // Cell Voltage #11
|
||||
case 13: // Cell Voltage #12
|
||||
case 14: // Cell Voltage #13
|
||||
case 15: // Cell Voltage #14
|
||||
case 16: // Cell Voltage #15
|
||||
rSystemData.ValueData.CellVoltage[reg_addr - 2] = (ushort)(reg_value / 1);
|
||||
csUtils.MakeMaxAvgMinCellVoltage(ref rSystemData, 15);
|
||||
break; // 15 CellVoltage 1mV
|
||||
case 17: break; // Cell Voltage #16 - Reserved
|
||||
case 18: rSystemData.ValueData.Ext1Temperature = (short)((reg_value) * 10); break; //Ext1 Temperature (Temp of MOS-FET)
|
||||
case 19: rSystemData.ValueData.Ext2Temperature = (short)((reg_value) * 10); break; //Ext2 Amb. PCB Temperature 1C
|
||||
case 20: break; // Temp Max.
|
||||
case 21: rSystemData.ValueData.remainingCapacity = (short)(reg_value / 1); break; // Remaining Capacity
|
||||
case 22: rSystemData.ValueData.MaxBattChargeCurr = reg_value / 1; break;
|
||||
case 23: rSystemData.ValueData.stateOfHealth = (short)(reg_value * 10); break;
|
||||
case 24: rSystemData.ValueData.rSOC = (short)(reg_value * 10); break; //SOC
|
||||
case 25: rSystemData.StatusData.status = reg_value; break; //Operating Status
|
||||
case 26: rSystemData.StatusData.warning = MakeUartWarningData(reg_value); break; //Warning Status
|
||||
case 27: rSystemData.StatusData.protection = MakeUartTripData(reg_value); break; //Protection Status
|
||||
case 28: // Error Code
|
||||
// 0x0001:Voltage error
|
||||
// 0x0002:Temperature error
|
||||
// 0x0004: Current Check Error
|
||||
// 0x0010:Cell unbalance
|
||||
break;
|
||||
case 29: // Cycle count MSB
|
||||
temp = rSystemData.ValueData.cycleCount;
|
||||
rSystemData.ValueData.cycleCount = (temp & (0x0000FFFF)) | (reg_value << 16);
|
||||
break;
|
||||
case 30: // Cycle count LSB
|
||||
temp = rSystemData.ValueData.cycleCount;
|
||||
rSystemData.ValueData.cycleCount = (int)(temp & (0xFFFF0000)) | (reg_value << 0);
|
||||
break;
|
||||
case 31: // fullChargeCapacity MSB
|
||||
temp = rSystemData.ValueData.fullChargeCapacity;
|
||||
rSystemData.ValueData.fullChargeCapacity = (temp & (0x0000FFFF)) | (reg_value << 16);
|
||||
break;
|
||||
case 32: // fullChargeCapacity LSB
|
||||
temp = rSystemData.ValueData.fullChargeCapacity;
|
||||
rSystemData.ValueData.fullChargeCapacity = (int)(temp & (0xFFFF0000)) | (reg_value << 0);
|
||||
break;
|
||||
case 33:
|
||||
case 34:
|
||||
rSystemData.ValueData.CellTemperature[((reg_addr - 33) * 2) + 0] = (short)(((reg_value >> 8) & 0xFF) * 10);
|
||||
rSystemData.ValueData.CellTemperature[((reg_addr - 33) * 2) + 1] = (short)(((reg_value >> 0) & 0xFF) * 10);
|
||||
csUtils.MakeMaxAvgMinTemperature(ref rSystemData, 4);
|
||||
break;
|
||||
case 35: break; // Reserved
|
||||
case 36: rSystemData.cellQty = reg_value; break; // Cell Qty
|
||||
case 37: rSystemData.ValueData.designedCapacity = reg_value; break;
|
||||
case 38: rSystemData.StatusData.cellBallanceStatus = reg_value; break;
|
||||
|
||||
case 39: rSystemData.StatusData.specialAlarm = (short)(reg_value); break; // Special Alarm
|
||||
|
||||
//case 61: rSystemData.StatusData.cellBallanceStatus = reg_value; break;
|
||||
//45 ~ 99 : Reserved
|
||||
case 45: rSystemData.BmsDateTimeShort1 = (ushort)reg_value; break; // DateTime
|
||||
case 46: rSystemData.BmsDateTimeShort2 = (ushort)reg_value;
|
||||
int yy, MM, dd, HH, mm, ss;
|
||||
rSystemData.BmsDateTimeInt = (rSystemData.BmsDateTimeShort1 << 16) | (rSystemData.BmsDateTimeShort2);
|
||||
yy = (rSystemData.BmsDateTimeInt >> 26) & 0x003F;
|
||||
MM = ((rSystemData.BmsDateTimeInt >> 22) & 0x000F) % 13;
|
||||
dd = ((rSystemData.BmsDateTimeInt >> 17) & 0x001F) % 32;
|
||||
HH = ((rSystemData.BmsDateTimeInt >> 12) & 0x001F) % 24;
|
||||
mm = ((rSystemData.BmsDateTimeInt >> 6) & 0x003F) % 60;
|
||||
ss = ((rSystemData.BmsDateTimeInt >> 0) & 0x003F) % 60;
|
||||
yy += 2000;
|
||||
|
||||
rSystemData.BmsDateTime.DateTimeStr = string.Format("{0:0000}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}"
|
||||
, yy
|
||||
, MM
|
||||
, dd
|
||||
, HH
|
||||
, mm
|
||||
, ss
|
||||
);
|
||||
break; // DateTime
|
||||
|
||||
case 47: rSystemData.CalibrationData.ChaMode.Mode = reg_value; break; // 0x2F
|
||||
case 48: rSystemData.CalibrationData.ChaMode.Value = reg_value; break; // 0x2F
|
||||
|
||||
case 56: rSystemData.CalibrationData.BalCalib.Volt = reg_value; break; // Cell Balance Voltage
|
||||
case 57: rSystemData.CalibrationData.BalCalib.Diff = reg_value; break; // Cell Balance Diff
|
||||
|
||||
case 58: rSystemData.ParamData.LowSocWarning = reg_value; break;
|
||||
|
||||
case 61: rSystemData.ParamData.CellUnderVoltageWarning = reg_value; break;
|
||||
case 62: rSystemData.ParamData.CellUnderVoltageTrip = reg_value; break;
|
||||
case 63: rSystemData.ParamData.CellUnderVoltageRelease = reg_value; break;
|
||||
case 64: rSystemData.ParamData.SysUnderVoltageWarning = (short)(reg_value / 10); break;
|
||||
case 65: rSystemData.ParamData.SysUnderVoltageTrip = (short)(reg_value / 10); break;
|
||||
case 66: rSystemData.ParamData.SysUnderVoltageRelease = (short)(reg_value / 10); break;
|
||||
case 67: rSystemData.ParamData.CellOverVoltageWarning = reg_value; break;
|
||||
case 68: rSystemData.ParamData.CellOverVoltageTrip = reg_value; break;
|
||||
case 69: rSystemData.ParamData.CellOverVoltageRelease = reg_value; break;
|
||||
case 70: rSystemData.ParamData.SysOverVoltageWarning = (short)(reg_value / 10); break;
|
||||
case 71: rSystemData.ParamData.SysOverVoltageTrip = (short)(reg_value / 10); break;
|
||||
case 72: rSystemData.ParamData.SysOverVoltageRelease = (short)(reg_value / 10); break;
|
||||
|
||||
case 76: rSystemData.ParamData.ChaOverCurrentTimes = (short)(reg_value / 1); break;
|
||||
case 77: rSystemData.ParamData.DchOverCurrentTimes = (short)(reg_value / 1); break;
|
||||
case 78: rSystemData.ParamData.ChaOverCurrentReleaseTime = (short)(reg_value * 1); break;
|
||||
case 79: rSystemData.ParamData.DchOverCurrentReleaseTime = (short)(reg_value * 1); break;
|
||||
case 80: rSystemData.ParamData.ChaOverCurrentTrip1 = (short)(reg_value / 10); break;
|
||||
case 81: rSystemData.ParamData.DchOverCurrentTrip1 = (short)(reg_value / 10); break;
|
||||
case 82: rSystemData.ParamData.ShortCircuit = (short)(reg_value / 10); break; // Short Circuit Current = 300A
|
||||
case 83: rSystemData.ParamData.ChaOverCurrentTrip2 = (short)(reg_value / 10); break;
|
||||
case 84: rSystemData.ParamData.DchOverCurrentTrip2 = (short)(reg_value / 10); break;
|
||||
case 85: rSystemData.ParamData.ChaOverCurrentDelay1 = (short)(reg_value / 1); break;
|
||||
case 86: rSystemData.ParamData.ChaOverCurrentDelay2 = (short)(reg_value / 1); break;
|
||||
case 87: rSystemData.ParamData.DchOverCurrentDelay1 = (short)(reg_value / 1); break;
|
||||
case 88: rSystemData.ParamData.DchOverCurrentDelay2 = (short)(reg_value / 1); break;
|
||||
|
||||
case 90: rSystemData.ParamData.ChaLowTempWarning = (short)(reg_value - 50); break;
|
||||
case 91: rSystemData.ParamData.ChaLowTempTrip = (short)(reg_value - 50); break;
|
||||
case 92: rSystemData.ParamData.ChaLowTempRelease = (short)(reg_value - 50); break;
|
||||
case 93: rSystemData.ParamData.ChaHighTempWarning = (short)(reg_value - 50); break;
|
||||
case 94: rSystemData.ParamData.ChaHighTempTrip = (short)(reg_value - 50); break;
|
||||
case 95: rSystemData.ParamData.ChaHighTempRelease = (short)(reg_value - 50); break;
|
||||
case 96: rSystemData.ParamData.DchLowTempWarning = (short)(reg_value - 50); break;
|
||||
case 97: rSystemData.ParamData.DchLowTempTrip = (short)(reg_value - 50); break;
|
||||
case 98: rSystemData.ParamData.DchLowTempRelease = (short)(reg_value - 50); break;
|
||||
case 99: rSystemData.ParamData.DchHighTempWarning = (short)(reg_value - 50); break;
|
||||
case 100: rSystemData.ParamData.DchHighTempTrip = (short)(reg_value - 50); break;
|
||||
case 101: rSystemData.ParamData.DchHighTempRelease = (short)(reg_value - 50); break;
|
||||
|
||||
case 102: break; // PCB High Temp Warning
|
||||
case 103: break; // PCB High Temp Trip
|
||||
case 104: break; // PCB High Temp Release
|
||||
//100 ~111 : Model_Product Name
|
||||
case 105:
|
||||
case 106:
|
||||
case 107:
|
||||
case 108:
|
||||
case 109:
|
||||
case 110:
|
||||
case 111:
|
||||
case 112:
|
||||
case 113:
|
||||
case 114:
|
||||
case 115:
|
||||
case 116:
|
||||
int mReg = reg_addr - 105;
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.Model_Byte[(mReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 116)
|
||||
{
|
||||
rSystemData.Information.ModelName = Encoding.Default.GetString(rSystemData.Information.Model_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
|
||||
//112 ~114 : FW Version
|
||||
case 117:
|
||||
case 118:
|
||||
case 119:
|
||||
int fReg = reg_addr - 117;
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.FwVer_Byte[(fReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 119)
|
||||
{
|
||||
rSystemData.Information.SwProductRev = Encoding.Default.GetString(rSystemData.Information.FwVer_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
//115 ~ 122 : BMS Serial number
|
||||
case 120:
|
||||
case 121:
|
||||
case 122:
|
||||
case 123:
|
||||
case 124:
|
||||
case 125:
|
||||
case 126:
|
||||
case 127:
|
||||
int snReg = reg_addr - 120;
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.BMS_SN[(snReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 127)
|
||||
{
|
||||
rSystemData.Information.HwSerialNumber = Encoding.Default.GetString(rSystemData.Information.BMS_SN).Trim('\0');
|
||||
}
|
||||
break;
|
||||
|
||||
case 130: rSystemData.ParamData.EnvLowTempWarning = (short)(reg_value - 50); break;
|
||||
case 131: rSystemData.ParamData.EnvLowTempTrip = (short)(reg_value - 50); break;
|
||||
case 132: rSystemData.ParamData.EnvLowTempRelease = (short)(reg_value - 50); break;
|
||||
case 133: rSystemData.ParamData.EnvHighTempWarning = (short)(reg_value - 50); break;
|
||||
case 134: rSystemData.ParamData.EnvHighTempTrip = (short)(reg_value - 50); break;
|
||||
case 135: rSystemData.ParamData.EnvHighTempRelease = (short)(reg_value - 50); break;
|
||||
|
||||
case 136: // Anti-Theft Communication
|
||||
rSystemData.CalibrationData.AntiTheft.Comm = reg_value;
|
||||
break;
|
||||
case 137: // Anti-Theft Gyro-Scope
|
||||
rSystemData.CalibrationData.AntiTheft.GyroScope = reg_value;
|
||||
break;
|
||||
case 163: // 0xA3
|
||||
case 164: // 0xA4
|
||||
case 165: // 0xA5
|
||||
case 166: // 0xA6
|
||||
int ManuDateReg = reg_addr - 163;
|
||||
rSystemData.Information.ManuDate_Byte[(ManuDateReg * 2) + 0] = (byte)(reg_value >> 8);
|
||||
rSystemData.Information.ManuDate_Byte[(ManuDateReg * 2) + 1] = (byte)(reg_value >> 0);
|
||||
if (reg_addr == 166)
|
||||
{
|
||||
rSystemData.Information.ManufacturingDate = Encoding.Default.GetString(rSystemData.Information.ManuDate_Byte).Trim('\0');
|
||||
}
|
||||
break;
|
||||
}
|
||||
csMakeDataFunction.MakeAlarm(ref rSystemData);
|
||||
}
|
||||
|
||||
public static short MakeUartWarningData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
if (bAlarm[12] == true) result |= (short)(1 << 11); // 0x0200:SOC Low
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static short MakeUartTripData(short rdata)
|
||||
{
|
||||
short result = 0;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001:Pack OV
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002:Cell OV
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004:Pack UV
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008:Cell UV
|
||||
|
||||
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010:Charging OC
|
||||
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020:Discharging OC
|
||||
|
||||
if (bAlarm[8] == true) result |= (short)(1 << 0); // 0x0080: Charging Over Tempratuer
|
||||
if (bAlarm[9] == true) result |= (short)(1 << 0); // 0x0080: Discharging Over Tempratuer
|
||||
if (bAlarm[10] == true) result |= (short)(1 << 1); // 0x0040: Charging Under Tempratuer
|
||||
if (bAlarm[11] == true) result |= (short)(1 << 1); // 0x0040: Discharging Under Tempratuer
|
||||
if (bAlarm[13] == true) result |= (short)(1 << 9); // 0x0200:Short Circuit Protection
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static short MakeUartErrorData(short rdata, short cdata)
|
||||
{
|
||||
short result = cdata;
|
||||
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
|
||||
|
||||
if (bAlarm[0] == true) result |= (short)(1 << 9); // 0x0001:Voltage error
|
||||
if (bAlarm[1] == true) result |= (short)(1 << 9); // 0x0002:Temperature error
|
||||
if (bAlarm[2] == true) result |= (short)(1 << 9); // 0x0004: 电流检测Error
|
||||
if (bAlarm[3] == true) result |= (short)(1 << 9); // 0x0010:Cell unbalance
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user