초기 커밋.

This commit is contained in:
2025-12-19 13:59:34 +09:00
parent 1c0b03f88c
commit 79fea6964b
184 changed files with 94471 additions and 0 deletions

View 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();
}
}
}
}
}

View File

@@ -0,0 +1,62 @@
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 CsModbusFunction
{
static public byte[] MakeWriteRegisterData(ushort devId, ushort writeAddr, short[] writeData)
{
if (writeData == null || writeData.Length == 0)
return Array.Empty<byte>();
// 부호 확장 없이 캐스팅 (2s complement 그대로 0..65535 범위로 들어갑니다)
Span<ushort> regs = writeData.Length <= 16
? stackalloc ushort[writeData.Length]
: new ushort[writeData.Length]; // 길면 힙 사용
for (int k = 0; k < writeData.Length; k++)
regs[k] = unchecked((ushort)writeData[k]);
return MakeWriteRegisterData(devId, writeAddr, regs);
}
static private byte[] MakeWriteRegisterData(ushort devId, ushort writeAddr, ReadOnlySpan<ushort> writeData)
{
if (writeData.Length <= 0)
return Array.Empty<byte>();
const byte Func = 0x10; // PRESET_MULTI_REG
int regCount = writeData.Length;
int payloadLen = 7 + regCount * 2; // CRC 제외 길이
byte[] frame = new byte[payloadLen + 2];
int i = 0;
frame[i++] = (byte)devId; // Device ID
frame[i++] = Func; // Function Code (0x10)
frame[i++] = (byte)(writeAddr >> 8); // Addr Hi
frame[i++] = (byte)writeAddr; // Addr Lo
frame[i++] = (byte)(regCount >> 8); // Count Hi
frame[i++] = (byte)regCount; // Count Lo
frame[i++] = (byte)(regCount * 2); // ByteCount
// 데이터: 각 레지스터를 Hi → Lo 바이트로
for (int j = 0; j < regCount; j++)
{
ushort v = writeData[j];
frame[i++] = (byte)(v >> 8);
frame[i++] = (byte)v;
}
// CRC (CRCL → CRCH) 부착
if (!CsCRC16.TryAppendCrcLowHigh(frame, payloadLen, 0))
return Array.Empty<byte>();
return frame;
}
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}
}
}

View 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();
}
}
}
}

View 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 + DbConstData.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 = DbConstData.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 + DbConstData.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
}
}

View File

@@ -0,0 +1,207 @@
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);
// COMM FAIL TIME OUT
rConfig.CommFailTime = (int)csIniControlFunction.GetPrivateProfileInt("UART", "COMM_FAIL_TIME", 5000, 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.CommFailTime = 5000;
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);
// COMM_FAIL_TIME
WritePrivateProfileString("UART", "COMM_FAIL_TIME", aConfig.CommFailTime.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);
}
}
}

View File

@@ -0,0 +1,218 @@
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
{
//0x0001: Over voltage warning
//0x0002: Cell Over voltage warning
//0x0004: Low voltage warning
//0x0008: Low cell voltage warning
//0x0010: Charge over current warning
//0x0020: Discharge over current warning
//0x0040: ambient temp warning
//0x0080: MOSFET over temp warning
//0x0100: Charge over temperature warning
//0x0200: Discharge over temperature warning
//0x0400: Charge low temperature warning
//0x0800: Discharge low temperature warning
//0x1000: Low capacity warning
//0x2000: Low SOH warning
private static ushort MakeAlarmTripData(int id, short ndata, CsDeviceData.DeviceModuleData mData)
{
bool[] aData = csUtils.Int16ToBitArray(ndata);
int bFault = mData.StatusData.protect;
int bWarning = mData.StatusData.warning;
int i = 0;
if (id == 0)
{
// Warning
if (aData[i++]) bWarning |= (1 << 1); // Bit 0 : Cell Over voltage warning --> Bit 1
else bWarning &= ~(1 << 1);
if (aData[i++]) bWarning |= (1 << 3); // Bit 1 : Cell Under voltage warning --> Bit 3
else bWarning &= ~(1 << 3);
if (aData[i++]) bWarning |= (1 << 0); // Bit 2 : Pack Over voltage warning --> Bit 0
else bWarning &= ~(1 << 0);
if (aData[i++]) bWarning |= (1 << 2); // Bit 3 : Pack Under voltage warning --> Bit 2
else bWarning &= ~(1 << 2);
if (aData[i++]) bWarning |= (1 << 4); // Bit 4 : Charge over current warning --> Bit 4
else bWarning &= ~(1 << 4);
if (aData[i++]) bWarning |= (1 << 5); // Bit 5 : Discharge over current warning --> Bit 5
else bWarning &= ~(1 << 5);
if (aData[i++]) bWarning |= (1 << 6); // Bit 6 : Env over temperature warning --> Bit 6
else bWarning &= ~(1 << 6);
//if (aData[i++]) bWarning |= (1 << 7); // Bit 7 : Env under temperature warning --> Bit 7
//else bWarning &= ~(1 << 7);
i++; // 07 Reserved
if (aData[i++]) bWarning |= (1 << 8); // Bit 8 : Charge over temperature warning --> Bit 8
else bWarning &= ~(1 << 8);
if (aData[i++]) bWarning |= (1 << 10); // Bit 9 : Charge under temperature warning --> Bit 10
else bWarning &= ~(1 << 10);
if (aData[i++]) bWarning |= (1 << 9); // Bit 10 : Discharge over temperature warning --> Bit 9
else bWarning &= ~(1 << 9);
if (aData[i++]) bWarning |= (1 << 11); // Bit 11 : Discharge under temperature warning --> Bit 11
else bWarning &= ~(1 << 11);
if (aData[i++]) bWarning |= (1 << 12); // Bit 12 : Low capacity warning --> Bit 12
else bWarning &= ~(1 << 12);
i++; // 13
return (ushort)bWarning;
}
else
{
// Protection
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);
return (ushort)bFault;
}
}
public static void SetSnmpData(int index, object sdata, ref CsDeviceData.DeviceModuleData aModuleData)
{
switch (index)
{
case 1: aModuleData.ValueData.voltage = (short)(Convert.ToDouble(sdata) / 10); break; // voltageOfPack - 0.01V
case 2: aModuleData.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:
aModuleData.ValueData.CellVoltage[index - 3] = (ushort)(Convert.ToDouble(sdata) / 1);
csSerialCommFunction.MakeMaxAvgMinCellVoltage(ref aModuleData);
break; // Cell Voltage #16
case 19: aModuleData.ValueData.MosTemperature = (short)(Convert.ToDouble(sdata) * 10); break; // Temp of PCB - C
case 20: aModuleData.ValueData.AmbTemperature = (short)(Convert.ToDouble(sdata) * 10); break; // Temp of Ambient - C
case 21: aModuleData.AvgData.maxTemp = (short)(Convert.ToDouble(sdata) * 10); break; // Max. Temp
case 22: aModuleData.ValueData.remainingCapacity = (short)(Convert.ToDouble(sdata) * 1); break; // Remaining Capacity
case 24: aModuleData.ValueData.SOH = (short)(Convert.ToDouble(sdata) / 10); break; // stateOfHealth
case 25: aModuleData.ValueData.SOC = (short)(Convert.ToDouble(sdata) / 10); break; // Relatvie State Of Charge
case 26: aModuleData.StatusData.status = (ushort)(Convert.ToDouble(sdata) / 1); break; // Status
case 27: aModuleData.StatusData.warning = (ushort)CsAlarmDefine.DevWarningToGui(Convert.ToInt32(sdata)); break; // warning
case 28: aModuleData.StatusData.protect = (ushort)CsAlarmDefine.DevProtectToGui(Convert.ToInt32(sdata)); break; // protection
case 29: // FaultAndStatus
aModuleData.StatusData.faultAndStatus = (ushort)(Convert.ToDouble(sdata) / 1);
//aModuleData.StatusData.status = (short)(((short)Convert.ToDouble(sdata) >> 8) & 0x0003);
MakeAlarm(ref aModuleData);
break;
case 30: aModuleData.ValueData.cycleCount = (ushort)(Convert.ToDouble(sdata) / 1); break; // cycleCount
case 31: // Temperature #1
case 32: // Temperature #2
case 33: // Temperature #3
case 34: aModuleData.ValueData.CellTemperature[index - 31] = (short)(Convert.ToDouble(sdata) * 10); break; // Temperature #4
case 37: aModuleData.cellQty = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number
case 38: aModuleData.ValueData.designedCapacity = (short)(Convert.ToDouble(sdata) * 1); break; // Cell Number
case 40: aModuleData.ValueData.RecMaxBattChgCurrLmt = (short)(Convert.ToDouble(sdata) * 1); break; // Max. Charge Current - A
case 41: aModuleData.ntcQty = (short)(Convert.ToDouble(sdata) * 1); break; // NTC Number
case 42: aModuleData.BmsDateTime.year = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Year
case 43: aModuleData.BmsDateTime.month = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Month
case 44: aModuleData.BmsDateTime.day = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Day
case 45: aModuleData.BmsDateTime.hour = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Hour
case 46: aModuleData.BmsDateTime.minute = (short)(Convert.ToDouble(sdata) * 1); break; // BMS DateTime - Minute
case 47: aModuleData.BmsDateTime.second = (short)(Convert.ToDouble(sdata) * 1); // BMS DateTime - Second
aModuleData.BmsDateTime.DateTimeStr = string.Format("{0:0000}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}"
, aModuleData.BmsDateTime.year
, aModuleData.BmsDateTime.month
, aModuleData.BmsDateTime.day
, aModuleData.BmsDateTime.hour
, aModuleData.BmsDateTime.minute
, aModuleData.BmsDateTime.second
);
break;
case 48: aModuleData.FloatVoltage = (int)Convert.ToDouble(sdata); break; // Float Voltage - 0.01V
case 49: aModuleData.BoostVoltage = (int)Convert.ToDouble(sdata); break; // Boost Voltage - 0.01V
case 50: aModuleData.MinChargeTemp = (int)Convert.ToDouble(sdata); break; // Min. Charge Temp - C
case 51: aModuleData.MaxChargeTemp = (int)Convert.ToDouble(sdata); break; // Max. Charge Temp - C
case 60: aModuleData.Information.ModelName = (string)sdata; break; // Model - string
case 61: aModuleData.Information.SwProductRev = (string)sdata; break; // BMS Fw Version - string
case 62: aModuleData.Information.HwSerialNumber = (string)sdata; break; // Pack Serial Number - string
case 63: aModuleData.Information.VendorName = (string)sdata; break; // Vendor Name - string
case 64: aModuleData.Information.ProductCode = (string)sdata; break; // Product Code - string
case 65: aModuleData.Information.MajorMinorRev = (string)sdata; break; // Major Minor Revision - string
case 66: aModuleData.Information.HwProductRev = (string)sdata; break; // Hardware Product Revision - string
case 67: aModuleData.Information.ManufacturingDate = (string)sdata; break; // Manufacturing Date - string
default:
break;
}
}
public static void MakeAlarm(ref CsDeviceData.DeviceModuleData aModuleData)
{
if (((aModuleData.StatusData.faultAndStatus >> 14) & 0x0001) == 0x0001)
{
aModuleData.StatusData.batteryStatus = 4; // Anti-theft Gyroscope
}
else if (((aModuleData.StatusData.faultAndStatus >> 15) & 0x0001) == 0x0001)
{
aModuleData.StatusData.batteryStatus = 5; // Anti-theft Comm.
}
else if (aModuleData.StatusData.protect != 0x0000)
{
aModuleData.StatusData.batteryStatus = 2;
}
else if (aModuleData.StatusData.warning != 0x0000)
{
aModuleData.StatusData.batteryStatus = 1;
}
else
{
aModuleData.StatusData.batteryStatus = 0;
}
}
}
}

View File

@@ -0,0 +1,969 @@
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 CsDeviceData.DeviceModuleData aModuleData)
{
short[] result = new short[2];
switch (rData[1])
{
case READ_COIL_STATUS:
ReadCoilRegisterProcess(rData, rRegAddr, rLen, ref aModuleData);
break;
case READ_HOLDING_REG:
ReadHoldRegisterProcess(rData, rRegAddr, rLen, ref aModuleData);
break;
case READ_INPUT_REG:
ReadInputRegisterProcess(rData, rRegAddr, rLen, ref aModuleData);
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 CsDeviceData.DeviceModuleData aModuleData)
{
// 기본 유효성 검사
if (rData == null || rData.Length < 3)
{
// TODO: 로그/에러 처리 - 응답 길이 부족(DevID, Func, ByteCount 최소 필요)
return;
}
int i = 2; // rData[0]=DevID, rData[1]=Func(0x01), rData[2]=ByteCount
int byteCount = rData[i++];
if (byteCount < 0) // byte → int 승격 시 의미 없지만 방어적 체크
{
// TODO: 로그/에러 처리 - ByteCount 음수
return;
}
// 바이트 카운트만큼의 데이터가 실제로 존재하는지 확인
if (rData.Length < i + byteCount)
{
// TODO: 로그/에러 처리 - 실제 데이터가 ByteCount보다 짧음
return;
}
// 파싱할 수 있는 최대 코일 수와 요청한 코일 수 중 작은 쪽으로 제한
int coilsAvailable = byteCount * 8;
int coilsToParse = Math.Min(coilsAvailable, rLen);
if (coilsToParse <= 0)
{
// TODO: 로그/에러 처리 - 파싱할 코일 없음
return;
}
// Modbus Coils는 LSB-first: 각 바이트의 bit0이 가장 먼저 오는 코일 상태
for (int bit = 0; bit < coilsToParse; bit++)
{
int byteIndex = i + (bit / 8);
int bitPos = bit % 8;
// 방어적 인덱스 검사 (이론상 위의 길이검사로 안전하지만 이중 방어)
if (byteIndex < 0 || byteIndex >= rData.Length)
{
// TODO: 로그/에러 처리 - 계산된 인덱스가 범위를 벗어남
break;
}
int val = (rData[byteIndex] >> bitPos) & 0x01;
try
{
SetCoilRegister((short)(rRegAddr + bit), (short)val, ref aModuleData);
}
catch
{
// TODO: 로그/에러 처리 - 개별 레지스터 반영 실패(계속 진행)
}
}
}
private static void ReadHoldRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref CsDeviceData.DeviceModuleData aModuleData)
{
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 aModuleData);
i += 2;
}
}
private static void ReadInputRegisterProcess(byte[] rData, ushort rRegAddr, ushort rLen, ref CsDeviceData.DeviceModuleData aModuleData)
{
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 aModuleData);
i += 2;
}
}
private static void SetInputRegister(short reg_addr, short reg_value, ref CsDeviceData.DeviceModuleData aModuleData)
{
switch (reg_addr)
{
case 1: MakeMaxAvgMinCellVoltage(ref aModuleData); break;
case 2: MakeMaxAvgMinTemperature(ref aModuleData); break;
case 45: break;
}
}
private static void SetCoilRegister(short reg_addr, short reg_value, ref CsDeviceData.DeviceModuleData aModuleData)
{
switch (reg_addr)
{
case 0x3078:
aModuleData.StatusData.relayStatus = (ushort)reg_value;
aModuleData.CalibrationData.FetCalib.FetStatus = reg_value;
break;
case 0x502E:
aModuleData.CalibrationData.Current.ChargeOption = reg_value;
break;
}
}
private static void SetHoldRegister(short reg_addr, short reg_value, ref CsDeviceData.DeviceModuleData aModuleData)
{
uint temp = 0;
switch (reg_addr)
{
case 0: aModuleData.ValueData.voltage = (short)(reg_value / 10); break; //Total Voltage
case 1: aModuleData.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
aModuleData.ValueData.CellVoltage[reg_addr - 2] = (ushort)(reg_value / 1);
MakeMaxAvgMinCellVoltage(ref aModuleData);
break; // 15 CellVoltage 1mV
case 17: break; // Cell Voltage #16 - Reserved
case 18: aModuleData.ValueData.MosTemperature = (short)((reg_value) * 10); break; //Ext1 Temperature (Temp of MOS-FET)
case 19: aModuleData.ValueData.AmbTemperature = (short)((reg_value) * 10); break; //Ext2 Amb. PCB Temperature 1C
case 20: break; // Temp Max.
case 21: aModuleData.ValueData.remainingCapacity = (short)(reg_value / 1); break; // Remaining Capacity
case 22: aModuleData.ValueData.MaxBattChgCurr = reg_value / 1; break;
case 23: aModuleData.ValueData.SOH = (short)(reg_value * 10); break;
case 24: aModuleData.ValueData.SOC = (short)(reg_value * 10); break; //SOC
case 25: aModuleData.StatusData.status = (ushort)reg_value; break; //Operating Status
case 26:
aModuleData.StatusData.warning = (ushort)reg_value;
if ((aModuleData.StatusData.specialAlarm & 0x0004) != 0)
aModuleData.StatusData.warning |= 0x4000;
else
aModuleData.StatusData.warning &= 0xBFFF;
break; //Warning Status
case 27: aModuleData.StatusData.protect = (ushort)reg_value; break; //Protection Status
case 28: // Error Code
// 0x0001Voltage error
// 0x0002Temperature error
// 0x0004: Current Check Error
// 0x0010Cell unbalance
break;
case 29: // Cycle count MSB
temp = aModuleData.ValueData.cycleCount;
aModuleData.ValueData.cycleCount = (temp & (0x0000FFFF)) | ((uint)reg_value << 16);
break;
case 30: // Cycle count LSB
temp = aModuleData.ValueData.cycleCount;
aModuleData.ValueData.cycleCount = (temp & (0xFFFF0000)) | ((uint)reg_value << 0);
break;
case 31: // fullChargeCapacity MSB
temp = aModuleData.ValueData.fullChgCapacity_Ah;
aModuleData.ValueData.fullChgCapacity_Ah = (temp & (0x0000FFFF)) | ((uint)reg_value << 16);
break;
case 32: // fullChargeCapacity LSB
temp = aModuleData.ValueData.fullChgCapacity_Ah;
aModuleData.ValueData.fullChgCapacity_Ah = (temp & (0xFFFF0000)) | ((uint)reg_value << 0);
break;
case 33:
case 34:
aModuleData.ValueData.CellTemperature[((reg_addr - 33) * 2) + 0] = (short)(((reg_value >> 8) & 0xFF) * 10);
aModuleData.ValueData.CellTemperature[((reg_addr - 33) * 2) + 1] = (short)(((reg_value >> 0) & 0xFF) * 10);
MakeMaxAvgMinTemperature(ref aModuleData);
break;
case 35: break; // Reserved
case 36: aModuleData.cellQty = reg_value; break; // Cell Qty
case 37: aModuleData.ValueData.designedCapacity = reg_value; break;
case 38: aModuleData.StatusData.cellBallanceStatus = (ushort)reg_value; break;
case 39: aModuleData.StatusData.specialAlarm = (ushort)(reg_value); break; // Special Alarm
//case 61: aModuleData.StatusData.cellBallanceStatus = reg_value; break;
//45 ~ 99 : Reserved
case 45: aModuleData.BmsDateTimeShort1 = (ushort)reg_value; break; // DateTime
case 46: aModuleData.BmsDateTimeShort2 = (ushort)reg_value;
int yy, MM, dd, HH, mm, ss;
aModuleData.BmsDateTimeInt = (aModuleData.BmsDateTimeShort1 << 16) | (aModuleData.BmsDateTimeShort2);
yy = (aModuleData.BmsDateTimeInt >> 26) & 0x003F;
MM = ((aModuleData.BmsDateTimeInt >> 22) & 0x000F) % 13;
dd = ((aModuleData.BmsDateTimeInt >> 17) & 0x001F) % 32;
HH = ((aModuleData.BmsDateTimeInt >> 12) & 0x001F) % 24;
mm = ((aModuleData.BmsDateTimeInt >> 6) & 0x003F) % 60;
ss = ((aModuleData.BmsDateTimeInt >> 0) & 0x003F) % 60;
yy += 2000;
aModuleData.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: aModuleData.CalibrationData.ChaMode.Mode = reg_value; break; // 0x2F
case 48: aModuleData.CalibrationData.ChaMode.Value = reg_value; break; // 0x2F
//case 56: aModuleData.CalibrationData.BalCalib.Volt = reg_value; break; // Cell Balance Voltage
//case 57: aModuleData.CalibrationData.BalCalib.Diff = reg_value; break; // Cell Balance Diff
case 58: aModuleData.ParamData.LowSocWarning = reg_value; break;
case 61: aModuleData.ParamData.CellUnderVoltageWarning = reg_value; break;
case 62: aModuleData.ParamData.CellUnderVoltageTrip = reg_value; break;
case 63: aModuleData.ParamData.CellUnderVoltageRelease = reg_value; break;
case 64: aModuleData.ParamData.SysUnderVoltageWarning = (short)(reg_value / 10); break;
case 65: aModuleData.ParamData.SysUnderVoltageTrip = (short)(reg_value / 10); break;
case 66: aModuleData.ParamData.SysUnderVoltageRelease = (short)(reg_value / 10); break;
case 67: aModuleData.ParamData.CellOverVoltageWarning = reg_value; break;
case 68: aModuleData.ParamData.CellOverVoltageTrip = reg_value; break;
case 69: aModuleData.ParamData.CellOverVoltageRelease = reg_value; break;
case 70: aModuleData.ParamData.SysOverVoltageWarning = (short)(reg_value / 10); break;
case 71: aModuleData.ParamData.SysOverVoltageTrip = (short)(reg_value / 10); break;
case 72: aModuleData.ParamData.SysOverVoltageRelease = (short)(reg_value / 10); break;
case 76: aModuleData.ParamData.ChaOverCurrentTimes = (short)(reg_value / 1); break;
case 77: aModuleData.ParamData.DchOverCurrentTimes = (short)(reg_value / 1); break;
case 78: aModuleData.ParamData.ChaOverCurrentReleaseTime = (short)(reg_value * 1); break;
case 79: aModuleData.ParamData.DchOverCurrentReleaseTime = (short)(reg_value * 1); break;
case 80: aModuleData.ParamData.ChaOverCurrentTrip1 = (short)(reg_value / 10); break;
case 81: aModuleData.ParamData.DchOverCurrentTrip1 = (short)(reg_value / 10); break;
case 82: aModuleData.ParamData.ShortCircuit = (short)(reg_value / 10); break; // Short Circuit Current = 300A
case 83: aModuleData.ParamData.ChaOverCurrentTrip2 = (short)(reg_value / 10); break;
case 84: aModuleData.ParamData.DchOverCurrentTrip2 = (short)(reg_value / 10); break;
case 85: aModuleData.ParamData.ChaOverCurrentDelay1 = (short)(reg_value / 1); break;
case 86: aModuleData.ParamData.ChaOverCurrentDelay2 = (short)(reg_value / 1); break;
case 87: aModuleData.ParamData.DchOverCurrentDelay1 = (short)(reg_value / 1); break;
case 88: aModuleData.ParamData.DchOverCurrentDelay2 = (short)(reg_value / 1); break;
case 90: aModuleData.ParamData.ChaLowTempWarning = (short)(reg_value - 50); break;
case 91: aModuleData.ParamData.ChaLowTempTrip = (short)(reg_value - 50); break;
case 92: aModuleData.ParamData.ChaLowTempRelease = (short)(reg_value - 50); break;
case 93: aModuleData.ParamData.ChaHighTempWarning = (short)(reg_value - 50); break;
case 94: aModuleData.ParamData.ChaHighTempTrip = (short)(reg_value - 50); break;
case 95: aModuleData.ParamData.ChaHighTempRelease = (short)(reg_value - 50); break;
case 96: aModuleData.ParamData.DchLowTempWarning = (short)(reg_value - 50); break;
case 97: aModuleData.ParamData.DchLowTempTrip = (short)(reg_value - 50); break;
case 98: aModuleData.ParamData.DchLowTempRelease = (short)(reg_value - 50); break;
case 99: aModuleData.ParamData.DchHighTempWarning = (short)(reg_value - 50); break;
case 100: aModuleData.ParamData.DchHighTempTrip = (short)(reg_value - 50); break;
case 101: aModuleData.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;
aModuleData.Information.Model_Byte[(mReg * 2) + 0] = (byte)(reg_value >> 8);
aModuleData.Information.Model_Byte[(mReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 116)
{
aModuleData.Information.ModelName = Encoding.Default.GetString(aModuleData.Information.Model_Byte).Trim('\0');
}
break;
//112 ~114 : FW Version
case 117:
case 118:
case 119:
int fReg = reg_addr - 117;
aModuleData.Information.FwVer_Byte[(fReg * 2) + 0] = (byte)(reg_value >> 8);
aModuleData.Information.FwVer_Byte[(fReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 119)
{
aModuleData.Information.SwProductRev = Encoding.Default.GetString(aModuleData.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;
aModuleData.Information.BMS_SN[(snReg * 2) + 0] = (byte)(reg_value >> 8);
aModuleData.Information.BMS_SN[(snReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 127)
{
aModuleData.Information.HwSerialNumber = Encoding.Default.GetString(aModuleData.Information.BMS_SN).Trim('\0');
}
break;
case 130: aModuleData.ParamData.EnvLowTempWarning = (short)(reg_value - 50); break;
case 131: aModuleData.ParamData.EnvLowTempTrip = (short)(reg_value - 50); break;
case 132: aModuleData.ParamData.EnvLowTempRelease = (short)(reg_value - 50); break;
case 133: aModuleData.ParamData.EnvHighTempWarning = (short)(reg_value - 50); break;
case 134: aModuleData.ParamData.EnvHighTempTrip = (short)(reg_value - 50); break;
case 135: aModuleData.ParamData.EnvHighTempRelease = (short)(reg_value - 50); break;
case 136: // Anti-Theft Communication
aModuleData.CalibrationData.AntiTheft.Comm = reg_value;
break;
case 137: // Anti-Theft Gyro-Scope
aModuleData.CalibrationData.AntiTheft.GyroScope = reg_value;
break;
case 163: // 0xA3
case 164: // 0xA4
case 165: // 0xA5
case 166: // 0xA6
int ManuDateReg = reg_addr - 163;
aModuleData.Information.ManuDate_Byte[(ManuDateReg * 2) + 0] = (byte)(reg_value >> 8);
aModuleData.Information.ManuDate_Byte[(ManuDateReg * 2) + 1] = (byte)(reg_value >> 0);
if (reg_addr == 166)
{
aModuleData.Information.ManufacturingDate = Encoding.Default.GetString(aModuleData.Information.ManuDate_Byte).Trim('\0');
}
break;
}
csMakeDataFunction.MakeAlarm(ref aModuleData);
}
public static void MakeMaxAvgMinCellVoltage(ref CsDeviceData.DeviceModuleData aModuleData)
{
int Max, Avg, Min, Sum;
int MaxNo, MinNo;
Max = Avg = Min = Sum = 0;
MaxNo = MinNo = 0;
for (int i = 0; i < csConstData.SystemInfo.MAX_MODULE_CELL_SIZE; i++)
{
if (i == 0)
{
Max = Min = aModuleData.ValueData.CellVoltage[i];
}
Sum += aModuleData.ValueData.CellVoltage[i];
if (Max < aModuleData.ValueData.CellVoltage[i])
{
Max = aModuleData.ValueData.CellVoltage[i];
MaxNo = i;
}
if (Min > aModuleData.ValueData.CellVoltage[i])
{
Min = aModuleData.ValueData.CellVoltage[i];
MinNo = i;
}
}
Avg = Sum / csConstData.SystemInfo.MAX_MODULE_CELL_SIZE;
aModuleData.AvgData.avgCellVoltage = (short)Avg;
aModuleData.AvgData.maxCellVoltage = (short)Max;
aModuleData.AvgData.maxCellNum = (short)(MaxNo + 1);
aModuleData.AvgData.minCellVoltage = (short)Min;
aModuleData.AvgData.minCellNum = (short)(MinNo + 1);
aModuleData.AvgData.diffCellVoltage = (short)(Max - Min);
}
private static void MakeMaxAvgMinTemperature(ref CsDeviceData.DeviceModuleData aModuleData)
{
int Max, Avg, Min, Sum;
int MaxNo, MinNo;
Max = Avg = Min = Sum = 0;
MaxNo = MinNo = 0;
//for (int i = 0; i < csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE; i++)
for (int i = 0; i < 4; i++)
{
if (i == 0)
{
Max = Min = aModuleData.ValueData.CellTemperature[i];
}
Sum += aModuleData.ValueData.CellTemperature[i];
if (Max < aModuleData.ValueData.CellTemperature[i])
{
Max = aModuleData.ValueData.CellTemperature[i];
MaxNo = i;
}
if (Min > aModuleData.ValueData.CellTemperature[i])
{
Min = aModuleData.ValueData.CellTemperature[i];
MinNo = i;
}
}
//Avg = Sum / csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE;
Avg = Sum / 4;
aModuleData.AvgData.avgTemp = (short)Avg;
aModuleData.AvgData.maxTemp = (short)Max;
aModuleData.AvgData.maxTempNum = (short)(MaxNo + 1);
aModuleData.AvgData.minTemp = (short)Min;
aModuleData.AvgData.minTempNum = (short)(MinNo + 1);
aModuleData.AvgData.diffTemp = (short)(Max - Min);
}
public static short MakeUartWarningData(short rdata)
{
short result = 0;
bool[] bAlarm = csUtils.Int16ToBitArray(rdata);
if (bAlarm[0] == true) result |= (short)(1 << 2); // 0x0001Pack OV
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002Cell OV
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004Pack UV
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008Cell UV
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010Charging OC
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020Discharging 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); // 0x0200SOC 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); // 0x0001Pack OV
if (bAlarm[1] == true) result |= (short)(1 << 4); // 0x0002Cell OV
if (bAlarm[2] == true) result |= (short)(1 << 3); // 0x0004Pack UV
if (bAlarm[3] == true) result |= (short)(1 << 5); // 0x0008Cell UV
if (bAlarm[4] == true) result |= (short)(1 << 6); // 0x0010Charging OC
if (bAlarm[5] == true) result |= (short)(1 << 7); // 0x0020Discharging 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); // 0x0200Short 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); // 0x0001Voltage error
if (bAlarm[1] == true) result |= (short)(1 << 9); // 0x0002Temperature error
if (bAlarm[2] == true) result |= (short)(1 << 9); // 0x0004: 电流检测Error
if (bAlarm[3] == true) result |= (short)(1 << 9); // 0x0010Cell unbalance
return result;
}
}
}