초기 커밋.

This commit is contained in:
2025-12-17 12:40:51 +09:00
parent e8d195c03e
commit 368acb1aa8
184 changed files with 95393 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Data.OleDb;
namespace LFP_Manager.Utils
{
class csExcelControl
{
/// <summary>
/// Excel Database Control Class
/// version 0.1.5
/// </summary>
/// <License>
/// <Copyright>자유배포</Copyright>
/// <Writer>황현우 [ LiA's Blog ]</Writer>
/// <DocUrl>http://blog.naver.com/exila</DocUrl>
/// <Company>CoreBank Co.,Ltd.</Company>
/// <Note>불펌금지효.. 만든 사람의 성의좀 생각을..-_-;;</Note>
/// </License>
/*---------------------------------------------------------------------
* Connection String 에는 어마어마한 옵션들이.. 주로 영문 사이트이긴
* 하지만 좀더 상세한 제어를 원한다면 OleDB Connection String 옵션과
* Extended Properties 에 들어가는 Excel Option 들을 살펴보는 것이 좋을
* 듯.. HDR = 첫줄을 헤더로 사용할 것인지,IMEX = 데이터유형적용여부 등등
*-------------------------------------------------------------------*/
// 확장명 XLS (Excel 97~2003 용)
private const string ConnectStrFrm_Excel97_2003 =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=\"{0}\";" +
"Mode=ReadWrite|Share Deny None;" +
"Extended Properties='Excel 8.0; HDR={1}; IMEX={2}';" +
"Persist Security Info=False";
// 확장명 XLSX (Excel 2007 이상용)
private const string ConnectStrFrm_Excel =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=\"{0}\";" +
"Mode=ReadWrite|Share Deny None;" +
"Extended Properties='Excel 12.0; HDR={1}; IMEX={2}';" +
"Persist Security Info=False";
/// <summary>
/// Excel 파일의 형태를 반환한다.
/// -2 : Error
/// -1 : 엑셀파일아님
/// 0 : 97-2003 엑셀 파일 (xls)0
/// 1 : 2007 이상 파일 (xlsx)
/// </summary>
/// <param name="XlsFile">
/// Excel File 명 전체 경로입니다.
/// </param>
public static int ExcelFileType(string XlsFile)
{
byte[,] ExcelHeader = {
{ 0xD0, 0xCF, 0x11, 0xE0, 0xA1 }, // XLS File Header
{ 0x50, 0x4B, 0x03, 0x04, 0x14 } // XLSX File Header
};
// result -2 = error, -1 = not excel , 0 = xls , 1 = xlsx
int result = -1;
FileInfo FI = new FileInfo(XlsFile);
FileStream FS = FI.Open(FileMode.Open);
try
{
byte[] FH = new byte[5];
FS.Read(FH, 0, 5);
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 5; j++)
{
if (FH[j] != ExcelHeader[i, j]) break;
else if (j == 4) result = i;
}
if (result >= 0) break;
}
}
catch
{
result = (-2);
//throw e;
}
finally
{
FS.Close();
}
return result;
}
/// <summary>
/// Excel 파일을 DataSet 으로 변환하여 반환한다.
/// </summary>
/// <param name="FileName">
/// Excel File 명 PullPath
/// </param>
/// <param name="UseHeader">
/// 첫번째 줄을 Field 명으로 사용할 것이지 여부
/// </param>
private static DataSet OpenExcel(string FileName, bool UseHeader)
{
DataSet DS = null;
string[] HDROpt = { "NO", "YES" };
string HDR = "";
string ConnStr = "";
if (UseHeader)
HDR = HDROpt[1];
else
HDR = HDROpt[0];
int ExcelType = ExcelFileType(FileName);
switch (ExcelType)
{
case (-2): throw new Exception(FileName + "의 형식검사중 오류가 발생하였습니다."); // An error occurred during type inspection
case (-1): throw new Exception(FileName + "은 엑셀 파일형식이 아닙니다."); // Is not an Excel file format.
case ( 0): ConnStr = string.Format(ConnectStrFrm_Excel97_2003, FileName, HDR, "1"); break;
case ( 1): ConnStr = string.Format(ConnectStrFrm_Excel, FileName, HDR, "1"); break;
}
OleDbConnection OleDBConn = null;
OleDbDataAdapter OleDBAdap = null;
DataTable Schema;
try
{
OleDBConn = new OleDbConnection(ConnStr);
OleDBConn.Open();
Schema = OleDBConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
DS = new DataSet();
foreach (DataRow DR in Schema.Rows)
{
OleDBAdap = new OleDbDataAdapter(DR["TABLE_NAME"].ToString(), OleDBConn);
OleDBAdap.SelectCommand.CommandType = CommandType.TableDirect;
OleDBAdap.AcceptChangesDuringFill = false;
string TableName = DR["TABLE_NAME"].ToString().Replace("$", String.Empty).Replace("'", String.Empty);
if (DR["TABLE_NAME"].ToString().Contains("$")) OleDBAdap.Fill(DS, TableName);
}
}
catch (Exception e)
{
throw e;
}
finally
{
if (OleDBConn != null) OleDBConn.Close();
}
return DS;
}
/// <summary>
/// DataSet 을 Excel 파일로 저장한다.
/// </summary>
/// <param name="FileName">
/// Excel File 명 PullPath
/// </param>
/// <param name="DS">
/// Excel 로 저장할 대상 DataSet 객체.
/// </param>
/// <param name="ExistDel">
/// 동일한 파일명이 있을 때 삭제 할 것인지 여부, 파일이 있고 false 면 저장안하고 그냥 false 를 리턴.
/// </param>
/// <param name="OldExcel">
/// xls 형태로 저장할 것인지 여부, false 이면 xlsx 형태로 저장함.
/// </param>
private static bool SaveExcel(string FileName, DataSet DS, bool ExistDel, bool OldExcel)
{
bool result = true;
if (File.Exists(FileName))
if (ExistDel) File.Delete(FileName);
else return result;
string TempFile = FileName;
// 파일 확장자가 xls 이나 xlsx 가 아니면 아예 파일을 안만들어서
// 템프파일로 생성후 지정한 파일명으로 변경..
OleDbConnection OleDBConn = null;
try
{
OleDbCommand Cmd = null;
string ConnStr = "";
if (OldExcel)
{
TempFile = TempFile + ".xls";
ConnStr = string.Format(ConnectStrFrm_Excel97_2003, TempFile, "YES", "0");
}
else
{
TempFile = TempFile + ".xlsx";
ConnStr = string.Format(ConnectStrFrm_Excel, TempFile, "YES", "0");
}
OleDBConn = new OleDbConnection(ConnStr);
OleDBConn.Open();
// Create Table(s).. : 테이블 단위 처리
foreach (DataTable DT in DS.Tables)
{
String TableName = DT.TableName;
StringBuilder FldsInfo = new StringBuilder();
StringBuilder Flds = new StringBuilder();
// Create Field(s) String : 현재 테이블의 Field 명 생성
foreach (DataColumn Column in DT.Columns)
{
if (FldsInfo.Length > 0)
{
FldsInfo.Append(",");
Flds.Append(",");
}
FldsInfo.Append("[" + Column.ColumnName.Replace("'", "''") + "] CHAR(255)");
Flds.Append(Column.ColumnName.Replace("'", "''"));
}
// Table Create
Cmd = new OleDbCommand("CREATE TABLE " + TableName + "(" + FldsInfo.ToString() + ")", OleDBConn);
Cmd.ExecuteNonQuery();
// Insert Data
foreach (DataRow DR in DT.Rows)
{
StringBuilder Values = new StringBuilder();
foreach (DataColumn Column in DT.Columns)
{
if (Values.Length > 0) Values.Append(",");
Values.Append("'" + DR[Column.ColumnName].ToString().Replace("'", "''") + "'");
}
Cmd = new OleDbCommand(
"INSERT INTO [" + TableName + "$]" +
"(" + Flds.ToString() + ") " +
"VALUES (" + Values.ToString() + ")",
OleDBConn);
Cmd.ExecuteNonQuery();
}
}
}
catch (Exception)
{
result = false;
}
finally
{
if (OleDBConn != null) OleDBConn.Close();
try
{
if (File.Exists(TempFile))
{
File.Move(TempFile, FileName);
}
}
catch { }
}
return result;
}
/// <summary>
/// Excel 파일을 DataSet 으로 변환하여 반환한다.
/// </summary>
/// <param name="ExcelFile">
/// 읽어올 Excel File 명(전체경로)입니다.
/// </param>
public static DataSet OpenExcelDB(string ExcelFile)
{
return OpenExcel(ExcelFile, true);
}
/// <summary>
/// DataSet 을 Excel 파일로 저장한다. 동일 파일명이 있으면 Overwrite 됩니다.
/// </summary>
/// <param name="ExcelFile">
/// 저장할 Excel File 명(전체경로)입니다.
/// </param>
/// <param name="DS">
/// 저장할 대상 DataSet 입니다.
/// </param>
public static bool SaveExcelDB(string ExcelFile, DataSet DS)
{
return SaveExcel(ExcelFile, DS, true, false);
}
}
}

567
LFP_Manager/Utils/csLog.cs Normal file
View File

@@ -0,0 +1,567 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using LFP_Manager.DataStructure;
using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;
namespace LFP_Manager.Utils
{
public class csL4Logger
{
private static csL4Logger LoggerInstance;
public ILog log;
public RollingFileAppender rollingAppender;
public PatternLayout layout;
public log4net.Filter.LoggerMatchFilter lmf;
public static csL4Logger GetInstance()
{
if (LoggerInstance == null)
{
LoggerInstance = new csL4Logger();
}
return LoggerInstance;
}
public csL4Logger()
{
string FilePath = AppDomain.CurrentDomain.BaseDirectory + "\\Log\\App.log"; // 실행폴더 아래에 Log폴더
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.Configured = true;
RollingFileAppender rollingAppender = new RollingFileAppender();
rollingAppender.Name = "logger";
rollingAppender.File = FilePath; // 로그파일 이름
rollingAppender.AppendToFile = true;
rollingAppender.StaticLogFileName = true;
rollingAppender.CountDirection = 1;
rollingAppender.RollingStyle = RollingFileAppender.RollingMode.Date;
rollingAppender.DatePattern = "_yyyyMMdd\".log\""; // 날짜가 변경되면 이전 로그에 붙은 이름
PatternLayout layout = new PatternLayout("%date [%-5level] %message%newline"); // 로그출력 포맷
rollingAppender.Layout = layout;
hierarchy.Root.AddAppender(rollingAppender);
rollingAppender.ActivateOptions();
hierarchy.Root.Level = log4net.Core.Level.All;
log = LogManager.GetLogger("logger");
Logger l = (Logger)log.Logger;
}
public void AddDebug(string LogMsg)
{
log.Debug(LogMsg);
}
public void AddError(string LogMsg)
{
log.Error(LogMsg);
}
public void Close()
{
LogManager.Shutdown();
}
}
class csLog
{
private static string SYSTEMLOG_FILE_DIR_M = "\\log\\systemlog";
private static string SYSTEMLOG_FILE_DIR = "\\log\\systemlog";
private static string DB_FILE_DIR = @"\db";
public static string GetLogFolder(string AppPath)
{
string path = System.IO.Path.GetDirectoryName(AppPath);
if (Directory.Exists(path + SYSTEMLOG_FILE_DIR_M) == false)
Directory.CreateDirectory(path + SYSTEMLOG_FILE_DIR_M);
return path + SYSTEMLOG_FILE_DIR_M;
}
public static string GetDbFolder(string AppPath)
{
string path = System.IO.Path.GetDirectoryName(AppPath);
if (Directory.Exists(path + DB_FILE_DIR) == false)
Directory.CreateDirectory(path + DB_FILE_DIR);
return path + DB_FILE_DIR;
}
public static void SystemDataLog(int RackID, CommConfig sConfig, DeviceSystemData sData, DateTime aTime, string AppPath)
{
SYSTEMLOG_FILE_DIR = String.Format("{0}\\SHELF{1}\\{2}", "\\log\\systemlog", RackID, String.Format("{0:yyyyMM}", aTime));
FileStream logFile = null;
string path = System.IO.Path.GetDirectoryName(AppPath);
string FileName = String.Format(path + SYSTEMLOG_FILE_DIR + "\\SHELF{0}_LOG_{1}.csv", RackID, String.Format("{0:yyMMdd}", aTime));
byte[] logData;
if (Directory.Exists(path + SYSTEMLOG_FILE_DIR) == false)
Directory.CreateDirectory(path + SYSTEMLOG_FILE_DIR);
if (File.Exists(FileName) == false)
{
logFile = new FileStream(FileName, FileMode.CreateNew, FileAccess.ReadWrite);
logData = WriteDataHeader(aTime, sData);
logFile.Write(logData, 0, logData.Length);
logFile.Close();
}
logFile = null;
//logFile = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
logFile = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
if (logFile != null)
{
logFile.Seek(0, SeekOrigin.End);
logData = WriteData(aTime, sConfig, sData);
logFile.Write(logData, 0, logData.Length);
logFile.Close();
}
}
public static void SystemTotalDataLog(CommConfig sConfig, DeviceSystemTotalData tData, DateTime aTime, string AppPath, string LogFileName)
{
SYSTEMLOG_FILE_DIR = String.Format("{0}\\MAIN\\{1}", "\\log\\systemlog", String.Format("{0:yyyyMM}", aTime));
FileStream logFile = null;
string path = System.IO.Path.GetDirectoryName(AppPath);
//string FileName = String.Format(path + SYSTEMLOG_FILE_DIR + "\\SHELF{0}_LOG_{1}.csv", RackID, String.Format("{0:yyMMdd}", aTime));
string FileName = String.Format(path + SYSTEMLOG_FILE_DIR + "\\MAIN_LOG_{0}.csv", LogFileName);
byte[] logData;
if (Directory.Exists(path + SYSTEMLOG_FILE_DIR) == false)
Directory.CreateDirectory(path + SYSTEMLOG_FILE_DIR);
if (File.Exists(FileName) == false)
{
logFile = new FileStream(FileName, FileMode.CreateNew, FileAccess.ReadWrite);
logData = WriteTotalDataHeader(aTime);
logFile.Write(logData, 0, logData.Length);
logFile.Close();
}
logFile = null;
//logFile = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
logFile = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
if (logFile != null)
{
logFile.Seek(0, SeekOrigin.End);
logData = WriteTotalData(aTime, sConfig, tData);
logFile.Write(logData, 0, logData.Length);
logFile.Close();
}
}
public static void SystemDataLog(int mID, CommConfig sConfig, DeviceSystemData sData, DateTime aTime, string AppPath, string LogFileName)
{
SYSTEMLOG_FILE_DIR = String.Format("{0}\\SHELF{1}\\{2}", "\\log\\systemlog", mID, String.Format("{0:yyyyMM}", aTime));
FileStream logFile = null;
string path = Path.GetDirectoryName(AppPath);
//string FileName = String.Format(path + SYSTEMLOG_FILE_DIR + "\\SHELF{0}_LOG_{1}.csv", RackID, String.Format("{0:yyMMdd}", aTime));
string FileName = String.Format(path + SYSTEMLOG_FILE_DIR + "\\SHELF{0}_LOG_{1}.csv", mID, LogFileName);
byte[] logData;
if (Directory.Exists(path + SYSTEMLOG_FILE_DIR) == false)
Directory.CreateDirectory(path + SYSTEMLOG_FILE_DIR);
if (File.Exists(FileName) == false)
{
logFile = new FileStream(FileName, FileMode.CreateNew, FileAccess.ReadWrite);
logData = WriteDataHeader(aTime, sData);
logFile.Write(logData, 0, logData.Length);
logFile.Close();
}
logFile = null;
//logFile = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
logFile = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
if (logFile != null)
{
logFile.Seek(0, SeekOrigin.End);
logData = WriteData(aTime, sConfig, sData);
logFile.Write(logData, 0, logData.Length);
logFile.Close();
}
}
#region SYSTEM DATE LOGGING
private static byte[] WriteTotalDataHeader(DateTime aDateTime)
{
string tt;
string sdata;
tt = aDateTime.ToString("yyyy-MM-dd HH:mm:ss");
sdata = String.Format(
"{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},"
, "DATETIME" // 0
, "INTERFACE" // 1
, "MODEL" // 2
, "COMM STATUS" // 3
, "STATUS" // 4
, "ALARM" // 5
, "VOLTAGE" // 6
, "CURRENT" // 7
, "SOC" // 8
, "MAX. TEMP" // 9
);
sdata += "\r\n";
Byte[] info =
new UTF8Encoding(true).GetBytes(sdata);
return info;
}
private static byte[] WriteDataHeader(DateTime aDateTime, DeviceSystemData aSystemData)
{
string tt;
string sdata;
tt = aDateTime.ToString("yyyy-MM-dd HH:mm:ss");
sdata = String.Format(
"{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},"
, "DATETIME" // 0
, "INTERFACE" // 1
, "MODEL" // 2
, "FW_VER" // 3
, "MODULE_SN" // 4
, "COMM STATUS" // 5
, "STATUS" // 6
, "ALARM" // 7
, "VOLTAGE" // 8
, "CURRENT" // 9
, "SOC" // 10
, "SOH" // 11
, "CYCLES" // 12
);
sdata += "CV_DIFF,";
for (int i = 0; i < aSystemData.cellQty; i++)
{
sdata += String.Format("{0},", String.Format("Cell_{0}", i + 1));
}
sdata += "TP_DIFF,";
for (int i = 0; i < aSystemData.tempQty; i++)
{
sdata += String.Format("{0},", String.Format("Temp_{0}", i + 1));
}
sdata += String.Format("{0},", String.Format("EXT1_Temp"));
sdata += String.Format("{0},", String.Format("EXT2_Temp"));
sdata += String.Format(
"{0},{1},{2},"
, "Warning" // 0
, "Fault" // 1
, "CB" // 2
);
sdata += "\r\n";
Byte[] info =
new UTF8Encoding(true).GetBytes(sdata);
return info;
}
private static string GetStatusString(short aStatus)
{
string result = "";
if (aStatus == 0)
{
result = "STANDBY";
}
else if (aStatus == 1)
{
result = "CHARGING";
}
else if (aStatus == 2)
{
result = "DISCHARGING";
}
else if (aStatus == 3)
{
result = "FLOATING";
}
else
{
result = "UNKNOWN";
}
return result;
}
private static string GetAlarmString(short aAlarm)
{
string result = "";
bool[] rackStatus = csUtils.Int16ToBitArray(aAlarm);
if (aAlarm == 0) result = "NORMAL";
else if (aAlarm == 1) result = "WARNING";
else if (aAlarm == 2) result = "FAULT";
else if (aAlarm == 3) result = "WARMING UP";
else result = "UNKNOWN";
return result;
}
private static string GetInterface(int sCommType)
{
string result = "";
result = "UART";
return result;
}
private static string GetModelName(CommConfig sConfig)
{
string result = "";
result = csConstData.MODEL_STR[sConfig.UartModelIndex];
return result;
}
private static string GetCommStatus(CommConfig sConfig, DeviceSystemData sData)
{
string result = "";
switch (sConfig.CommType)
{
case csConstData.CommType.COMM_UART:
result = sData.CommFail == false ? "NORM" : "FAIL";
break;
case csConstData.CommType.COMM_RS485:
result = sData.CommFail == false ? "NORM" : "FAIL";
break;
case csConstData.CommType.COMM_SNMP:
if (sData.CommFail == false)
{
if (sData.ShelfCommFail == false) result = "NORM";
else result = "FAIL";
}
else
{
result = "OFF-LINE";
}
break;
default:
break;
}
return result;
}
private static string GetCommStatus(DeviceSystemTotalData tData)
{
string result = "";
if (tData.CommFail)
result = "OFF-LINE";
else
result = "NORM";
return result;
}
private static byte[] WriteTotalData(DateTime aLog, CommConfig sConfig, DeviceSystemTotalData tData)
{
string tt;
string sdata;
tt = aLog.ToString("yyyy-MM-dd HH:mm:ss");
sdata = String.Format(
"{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},"
, tt // 0 DATETIME
, GetInterface(sConfig.CommType) // 1 INTERFACE
, GetModelName(sConfig) // 2 MODEL
, GetCommStatus(tData) // 3 COMM STATUS
, GetStatusString(tData.StatusData.status) // 4 STATUS
, GetAlarmString(tData.StatusData.batteryStatus) // 5 ALARM
, String.Format("{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalVoltage) / 10) // 6 voltageOfPack
, String.Format("{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalCurrent) / 10) // 7 current
, String.Format("{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalSOC) / 10) // 8 SOC
, String.Format("{0:#0.0}", Convert.ToDouble(tData.ValueData.TotalTemp) / 10) // 9 Max Temperature
);
sdata += "\r\n";
Byte[] info =
new UTF8Encoding(true).GetBytes(sdata);
return info;
}
private static byte[] WriteData(DateTime aLog, CommConfig sConfig, DeviceSystemData sData)
{
string tt;
string sdata;
tt = string.Format("{0:yyyy-MM-dd HH:mm:ss}", aLog);
sdata = String.Format(
"{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},"
, tt // 0 DATETIME
, GetInterface(sConfig.CommType) // 1 INTERFACE
, sData.Information.ModelName // 2 MODEL
, sData.Information.SwProductRev // 3 FW Ver
, sData.Information.HwSerialNumber // 4 SN
, GetCommStatus(sConfig, sData) // 5 COMM STATUS
, GetStatusString(sData.StatusData.status) // 6 STATUS
, GetAlarmString(sData.StatusData.batteryStatus) // 7 ALARM
, String.Format("{0:#0.0}", Convert.ToDouble(sData.ValueData.voltageOfPack) / 10) // 8 voltageOfPack
, String.Format("{0:#0.0}", Convert.ToDouble(sData.ValueData.current) / 10) // 9 current
, String.Format("{0:#0.0}", Convert.ToDouble(sData.ValueData.rSOC) / 10) // 10 SOC
, String.Format("{0:#0.0}", Convert.ToDouble(sData.ValueData.stateOfHealth) / 10) // 11 SOH
, String.Format("{0}", Convert.ToDouble(sData.ValueData.cycleCount) / 1) // 12 Cycle Count
);
sdata += String.Format("{0:#0.000},", Convert.ToDouble(sData.AvgData.diffCellVoltage) / 1000); // 13 Cell Voltage Diff
for (int i = 0; i < sData.cellQty; i++)
{
sdata += String.Format("{0:#0.000},", Convert.ToDouble(sData.ValueData.CellVoltage[i]) / 1000); // 14 - 28 Cell Voltage n
}
sdata += String.Format("{0:#0.0},", Convert.ToDouble(sData.AvgData.diffTemp) / 10); // 29 Temperature Diff
for (int i = 0; i < sData.tempQty; i++)
{
sdata += String.Format("{0:#0.0},", Convert.ToDouble(sData.ValueData.CellTemperature[i]) / 10); // 30 - 33 Cell Temperature n
}
sdata += String.Format("{0:#0.0},", Convert.ToDouble(sData.ValueData.Ext1Temperature) / 10); // 34 Ext1 Temperature n
sdata += String.Format("{0:#0.0},", Convert.ToDouble(sData.ValueData.Ext2Temperature) / 10); // 35 Ext2 Temperature n
sdata += String.Format(
"{0},{1},{2},"
, String.Format("0x{0}", sData.StatusData.warning.ToString("X4")) // 0 Warning
, String.Format("0x{0}", sData.StatusData.protection.ToString("X4")) // 1 Protection
, String.Format("0x{0}", sData.StatusData.cellBallanceStatus.ToString("X4")) // 2 cellBallanceStatus
);
sdata += "\r\n";
Byte[] info =
new UTF8Encoding(true).GetBytes(sdata);
return info;
}
#endregion
#region DATA PRINT
public static string data_print(byte[] data, int len)
{
byte[] ASC;
int i, j;
string result = "";
ASC = new byte[20];
if (len > 2)
{
if (ASC != null)
{
for (i = 0; i < (len / 16 + 1); i++)
{
result += String.Format("0x{0:X8} ", (int)(i * 16));
for (j = 0; j < 16; j++)
{
if ((i * 16 + j) >= data.Length)
{
result += " ";
ASC[j] = (byte)' ';
}
else
{
result += String.Format("{0:X2} ", data[(i * 16) + j]);
if (data[i * 16 + j] < ' ')
ASC[j] = (byte)'.';
else
{
if ((j == 15) && (data[i * 16 + j] > 128))
ASC[j] = (byte)'.';
else
ASC[j] = data[i * 16 + j];
}
}
}
ASC[16] = 0x00;
result += "\r\n";
//result += String.Format(" {0}\r\n", ASC.ToArray<byte>().ToString());
}
}
result += "\r\n";
//result += String.Format("ID: {0:X2}\r\n", data[6]);
//result += String.Format("CMD: {0:X2}\r\n", data[7]);
//result += String.Format("S-A: {0:X4}({0:d})\r\n", (data[8] << 8) | data[9]);
//result += String.Format("S-L: {0:X4}({0:d})\r\n", (data[10] << 8) | data[11]);
}
return result;
}
public static string trx_data_print(byte[] data, int len, int flag)
{
int i, j;
string result = "";
if (len > 2)
{
for (i = 0; i < (len / 16 + 1); i++)
{
if (flag == 0)
{ result += string.Format("[{0:yyyy-MM-dd HH:mm:ss.fff}] TX({1:0000}): ", DateTime.Now, len); }
else
{ result += string.Format("[{0:yyyy-MM-dd HH:mm:ss.fff}] RX({1:0000}): ", DateTime.Now, len); }
for (j = 0; j < 16; j++)
{
if ((i * 16 + j) >= len)
{
result += " ";
}
else
{
result += string.Format("{0:X2} ", data[(i * 16) + j]);
}
}
result += "\r\n";
}
}
return result;
}
public static string trx_msg_print(string msg, int flag)
{
string result = "";
if (flag == 0)
{
result += string.Format("[{0:yyyy-MM-dd HH:mm:ss.fff}] TX({1}) ", DateTime.Now, msg);
}
else
{
result += string.Format("[{0:yyyy-MM-dd HH:mm:ss.fff}] RX({1}) ", DateTime.Now, msg);
}
return result;
}
#endregion
}
}

View File

@@ -0,0 +1,442 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LFP_Manager.DataStructure;
namespace LFP_Manager.Utils
{
static class csUtils
{
public 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
};
public 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
};
#region CRC Calculation
/// <summary>
/// Modbus CRC-16 계산
/// </summary>
public static byte[] CalculateCRC(byte[] data, int length)
{
if (data == null || length <= 0 || length > data.Length)
throw new ArgumentException("Invalid data or length");
ushort crc = 0xFFFF;
for (int i = 0; i < length; i++)
{
crc ^= data[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 1) == 1)
crc = (ushort)((crc >> 1) ^ 0xA001);
else
crc >>= 1;
}
}
return new byte[] { (byte)(crc & 0xFF), (byte)(crc >> 8) };
}
#endregion
public static int GetModuleQty(CommConfig aConfig)
{
int mQty = 0;
switch (aConfig.CommType)
{
case csConstData.CommType.COMM_UART:
mQty = 1;
break;
case csConstData.CommType.COMM_RS485:
mQty = aConfig.ModuleQty;
break;
case csConstData.CommType.COMM_SNMP:
mQty = 1;
break;
default:
mQty = 0;
break;
}
return mQty;
}
public static void TypingOnlyNumber(object sender, KeyPressEventArgs e, bool includePoint, bool includeMinus)
{
bool isValidInput = false;
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
if (includePoint == true) { if (e.KeyChar == '.') isValidInput = true; }
if (includeMinus == true) { if (e.KeyChar == '-') isValidInput = true; }
if (isValidInput == false) e.Handled = true;
}
if (includePoint == true)
{
if (e.KeyChar == '.' && (string.IsNullOrEmpty((sender as DevExpress.XtraEditors.TextEdit).Text.Trim()) || (sender as DevExpress.XtraEditors.TextEdit).Text.IndexOf('.') > -1)) e.Handled = true;
}
if (includeMinus == true)
{
if (e.KeyChar == '-' && (!string.IsNullOrEmpty((sender as DevExpress.XtraEditors.TextEdit).Text.Trim()) || (sender as DevExpress.XtraEditors.TextEdit).Text.IndexOf('-') > -1)) e.Handled = true;
}
}
public static bool[] Int16ToBitArray(Int16 data)
{
bool[] result = new bool[16];
for (int i = 0; i < 16; i++)
{
result[i] = (((data >> i) & 0x0001) == 0x0001) ? true : false;
}
return result;
}
public static byte[] GetCRC(byte[] pby, UInt16 nSize)
{
byte[] result = new byte[2];
UInt16 uIndex, i;
UInt16 crc;
byte uchCRCHi = 0xff;
byte uchCRCLo = 0xff;
for (i = 0; i < nSize; i++)
{
uIndex = (UInt16)(uchCRCHi ^ pby[i]);
uchCRCHi = (byte)(uchCRCLo ^ csConstData.CRC_Data.auchCRCHi[uIndex]);
uchCRCLo = csConstData.CRC_Data.auchCRCLo[uIndex];
}
crc = (UInt16)(((UInt16)uchCRCHi << 8) | uchCRCLo);
result[1] = (byte)(crc / 256);
result[0] = (byte)(crc % 256);
return result;
}
public static byte StrByte2toByte(byte a, byte b)
{
byte result = 0;
byte a1 = 0, b1 = 0;
if ((a >= (byte)'0')&&(a <= (byte)'9'))
{
a1 = (byte)(a - (byte)'0');
}
else if ((a >= (byte)'a')&&(a <= (byte)'f'))
{
a1 = (byte)(a - (byte)'a');
}
else if ((a >= (byte)'A')&&(a <= (byte)'F'))
{
a1 = (byte)((a - (byte)'A') + 0x0A);
}
if ((b >= (byte)'0') && (b <= (byte)'9'))
{
b1 = (byte)(b - (byte)'0');
}
else if ((b >= (byte)'a') && (b <= (byte)'f'))
{
b1 = (byte)(b - (byte)'a');
}
else if ((b >= (byte)'A') && (b <= (byte)'F'))
{
b1 = (byte)((b - (byte)'A') + 0x0A);
}
result = (byte)((b1 << 4) | a1);
return result;
}
public static byte[] StrToByteArray(byte[] rData, int offset, int rlen)
{
int len = (rlen - 2) / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
{
result[i] = StrByte2toByte(rData[(i * 2) + offset + 2], rData[(i * 2) + offset + 1]);
}
return result;
}
public static byte[] StringToByte(string str)
{
byte[] StrByte = Encoding.UTF8.GetBytes(str); return StrByte;
}
#region OPERATING WARNING FUCTION
public static bool BitCheck(short rData, int pos)
{
if (((rData >> pos) & 0x0001) == 0x0001)
return true;
else
return false;
}
#endregion
#region TIMESTAMP FUNCTION
public static UInt32 CalcKKTimeStamp(DateTime tDate)
{
//Time of test and calibration. Local time in seconds since 2000.
//Ex:
//Epoch time offset (1 January 2000 00:00:00) = 946684800
//Current epoch time (1 October 2019 12:00:00) = 1569931200
//Timestamp = 1569931200 - 946684800 = 623246400
//(Used 'https://www.epochconverter.com/' for conversion)
DateTime baseDate = new DateTime(2000, 1, 1, 0, 0, 0);
int bDate = ConvertToUnixTimestamp(baseDate);
int nDate = ConvertToUnixTimestamp(tDate);
return (UInt32)(nDate - bDate);
}
public static DateTime ConvertTimeStampToDateTime(UInt32 tStamp)
{
DateTime result = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
result = result.AddSeconds(tStamp);
// DateTimeOffset.Now.ToUnixTimeSeconds() // (.NET Framework 4.6 +/.NET Core),
// older versions:
//var epoch = (DateTime.UtcNow - new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
return result;
}
public static int ConvertToUnixTimestamp(DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0);
TimeSpan diff = date - origin;
return (int)Math.Floor(diff.TotalSeconds);
}
#endregion
#region DateTime Format Methods
/// <summary>
/// DateTime을 기본 형식으로 변환합니다. (yyyy-MM-dd HH:mm:ss)
/// </summary>
public static string FormatDateTime(DateTime dateTime)
{
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
}
#endregion
#region DATA INIT
public static void DataInit(CommConfig aConfig, ref DeviceSystemData aSystemData)
{
aSystemData.ShelfCommFail = true;
switch (aConfig.CommType)
{
case csConstData.CommType.COMM_UART:
case csConstData.CommType.COMM_RS485:
switch (aConfig.UartModelIndex)
{
case csConstData.MODEL_INDEX.LFPM_48100D:
case csConstData.MODEL_INDEX.LFPM_48150D:
case csConstData.MODEL_INDEX.LFPM_48200D:
case csConstData.MODEL_INDEX.LFPM_48250D:
case csConstData.MODEL_INDEX.LFPM_48300D:
aSystemData.cellQty = 15;
aSystemData.tempQty = 4;
break;
case csConstData.MODEL_INDEX.LFPM_124050D:
aSystemData.cellQty = csConstData.SystemInfo.MAX_MODULE_CELL_SIZE;
aSystemData.tempQty = csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE;
break;
default:
aSystemData.cellQty = 15;
aSystemData.tempQty = 4;
break;
}
break;
case csConstData.CommType.COMM_SNMP:
switch (aConfig.SnmpModelIndex)
{
case csConstData.MODEL_INDEX.LFPM_48100D:
case csConstData.MODEL_INDEX.LFPM_48150D:
case csConstData.MODEL_INDEX.LFPM_48200D:
case csConstData.MODEL_INDEX.LFPM_48250D:
case csConstData.MODEL_INDEX.LFPM_48300D:
aSystemData.cellQty = 15;
aSystemData.tempQty = 4;
break;
case csConstData.MODEL_INDEX.LFPM_124050D:
aSystemData.cellQty = csConstData.SystemInfo.MAX_MODULE_CELL_SIZE;
aSystemData.tempQty = csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE;
break;
default:
aSystemData.cellQty = 15;
aSystemData.tempQty = 4;
break;
}
break;
default:
aSystemData.cellQty = 15;
aSystemData.tempQty = 4;
break;
}
for (int j = 0; j < aSystemData.ValueData.CellVoltage.Length; j++)
{
aSystemData.ValueData.CellVoltage[j] = 0;
}
for (int j = 0; j < aSystemData.ValueData.CellTemperature.Length; j++)
{
aSystemData.ValueData.CellTemperature[j] = 0;
}
aSystemData.ValueData.voltageOfPack = 0;
aSystemData.ValueData.current = 0;
aSystemData.ValueData.rSOC = 0;
aSystemData.AvgData.maxCellVoltage = 0;
aSystemData.AvgData.minCellVoltage = 0;
aSystemData.AvgData.avgCellVoltage = 0;
aSystemData.AvgData.maxTemp = 0;
aSystemData.AvgData.minTemp = 0;
aSystemData.AvgData.avgTemp = 0;
aSystemData.heatbeat = 0;
aSystemData.StatusData.warning = 0;
aSystemData.StatusData.protection = 0;
for (int j = 0; j < aSystemData.Information.BMS_SN.Length; j++)
{
aSystemData.Information.BMS_SN[j] = 0;
}
for (int j = 0; j < aSystemData.Information.Module_SN.Length; j++)
{
aSystemData.Information.Module_SN[j] = 0;
}
aSystemData.CalibrationData.Battery.Capacity = 0;
aSystemData.CalibrationData.Current.ChaAndDchSelect = 0;
aSystemData.CalibrationData.Current.ChgCalibration_K = 0;
aSystemData.CalibrationData.Current.DchCalibration_K = 0;
}
#endregion
#region MAKE AVERAGE VALUE
public static void MakeMaxAvgMinCellVoltage(ref DeviceSystemData rSystemData, int cellQty)
{
int Max, Avg, Min, Sum;
int MaxNo, MinNo;
Max = Avg = Min = Sum = 0;
MaxNo = MinNo = 0;
for (int i = 0; i < cellQty; i++)
{
if (i == 0)
{
Max = Min = rSystemData.ValueData.CellVoltage[i];
}
Sum += rSystemData.ValueData.CellVoltage[i];
if (Max < rSystemData.ValueData.CellVoltage[i])
{
Max = rSystemData.ValueData.CellVoltage[i];
MaxNo = i;
}
if (Min > rSystemData.ValueData.CellVoltage[i])
{
Min = rSystemData.ValueData.CellVoltage[i];
MinNo = i;
}
}
Avg = Sum / cellQty;
rSystemData.AvgData.avgCellVoltage = (short)Avg;
rSystemData.AvgData.maxCellVoltage = (short)Max;
rSystemData.AvgData.maxCellNum = (short)(MaxNo + 1);
rSystemData.AvgData.minCellVoltage = (short)Min;
rSystemData.AvgData.minCellNum = (short)(MinNo + 1);
rSystemData.AvgData.diffCellVoltage = (short)(Max - Min);
}
public static void MakeMaxAvgMinTemperature(ref DeviceSystemData rSystemData, int tempQty)
{
int Max, Avg, Min, Sum;
int MaxNo, MinNo;
Max = Avg = Min = Sum = 0;
MaxNo = MinNo = 0;
for (int i = 0; i < tempQty; i++)
{
if (i == 0)
{
Max = Min = rSystemData.ValueData.CellTemperature[i];
}
Sum += rSystemData.ValueData.CellTemperature[i];
if (Max < rSystemData.ValueData.CellTemperature[i])
{
Max = rSystemData.ValueData.CellTemperature[i];
MaxNo = i;
}
if (Min > rSystemData.ValueData.CellTemperature[i])
{
Min = rSystemData.ValueData.CellTemperature[i];
MinNo = i;
}
}
Avg = Sum / tempQty;
rSystemData.AvgData.avgTemp = (short)Avg;
rSystemData.AvgData.maxTemp = (short)Max;
rSystemData.AvgData.maxTempNum = (short)(MaxNo + 1);
rSystemData.AvgData.minTemp = (short)Min;
rSystemData.AvgData.minTempNum = (short)(MinNo + 1);
rSystemData.AvgData.diffTemp = (short)(Max - Min);
}
#endregion
}
}