Update BMS D1000 project files and documentation

This commit is contained in:
2026-08-12 10:35:22 +09:00
parent 15535f4e1a
commit 8c71cd683d
9 changed files with 182 additions and 251 deletions

30
.gitignore vendored Normal file
View File

@@ -0,0 +1,30 @@
## Visual Studio / C# Ignore Files
.vs/
bin/
obj/
*.suo
*.user
*.userosv
*.userprefs
*.pidb
*.booproj
*.svclog
*.cache
## Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Ob]j/
## Windows temp files
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

View File

@@ -215,9 +215,6 @@
<Content Include="AMO_LOGO.ico" /> <Content Include="AMO_LOGO.ico" />
<Content Include="Revision history.txt" /> <Content Include="Revision history.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Service\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>

View File

@@ -80,63 +80,47 @@ namespace BMS_D1000H.Utils.Functions
private byte[] WriteDataHeader(DeviceDataSystem sData) private byte[] WriteDataHeader(DeviceDataSystem sData)
{ {
string tt; StringBuilder sb = new StringBuilder();
string sdata;
DateTime aLog = DateTime.Now;
tt = aLog.ToString("yyyy-MM-dd HH:mm:ss"); sb.Append("DATETIME,OPERATING,ALARM,SYSTEM VOLTAGE,SYSTEM CURRENT,SYSTEM SOC,TRIP,WARNING,");
sdata = String.Format(
"{0},{1},{2},{3},{4},{5},{6},{7},"
, "DATETIME" // 0
, "OPERATING" // 1
, "ALARM" // 2
, "SYSTEM VOLTAGE" // 3
, "SYSTEM CURRENT" // 4
, "SYSTEM SOC" // 5
, "TRIP" // 6
, "WARNING" // 7
);
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("VOLTAGE_{0:00},", i + 1); sb.AppendFormat("VOLTAGE_{0:00},", i + 1);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("CURRENT_{0:00},", i + 1); sb.AppendFormat("CURRENT_{0:00},", i + 1);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("SOC_{0:00},", i + 1); sb.AppendFormat("SOC_{0:00},", i + 1);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("MAX_TEMP_{0:00},", i + 1); sb.AppendFormat("MAX_TEMP_{0:00},", i + 1);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("MIN_TEMP_{0:00},", i + 1); sb.AppendFormat("MIN_TEMP_{0:00},", i + 1);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("MAX_CVOLT_{0:00},", i + 1); sb.AppendFormat("MAX_CVOLT_{0:00},", i + 1);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("MIN_CVOLT_{0:00},", i + 1); sb.AppendFormat("MIN_CVOLT_{0:00},", i + 1);
} }
sdata += "\r\n"; sb.Append("\r\n");
Byte[] info = return new UTF8Encoding(true).GetBytes(sb.ToString());
new UTF8Encoding(true).GetBytes(sdata);
return info;
} }
#endregion #endregion
@@ -145,224 +129,185 @@ namespace BMS_D1000H.Utils.Functions
private byte[] WriteData(DeviceDataSystem sData, DeviceDataTray[] tData) private byte[] WriteData(DeviceDataSystem sData, DeviceDataTray[] tData)
{ {
string tt; StringBuilder sb = new StringBuilder();
string sdata;
DateTime aLog = DateTime.Now; DateTime aLog = DateTime.Now;
tt = aLog.ToString("yyyy-MM-dd HH:mm:ss"); sb.AppendFormat("{0:yyyy-MM-dd HH:mm:ss},{1},{2},{3:#0.0},{4:#0.0},{5:#0.0},"
sdata = String.Format( , aLog
"{0},{1},{2},{3},{4},{5}," , StatusStr.operating[sData.OpStatus]
, tt // {0} DATETIME , StatusStr.alarm[sData.AlarmStatus]
, String.Format("{0}", StatusStr.operating[sData.OpStatus]) // {1} OPERATING , Convert.ToDouble(sData.BatVoltage) / 100
, String.Format("{0}", StatusStr.alarm[sData.AlarmStatus]) // {2} ALARM , Convert.ToDouble(sData.Current) / 10
, String.Format("{0:#0.0}", Convert.ToDouble(sData.BatVoltage) / 100) // {3} SYSTEM VOLTAGE , Convert.ToDouble(sData.RelativeStateOfCharge) / 10
, String.Format("{0:#0.0}", Convert.ToDouble(sData.Current) / 10) // {4} SYSTEM CURRENT
, String.Format("{0:#0.0}", Convert.ToDouble(sData.RelativeStateOfCharge) / 10) // {5} SYSTEM SOC
); );
sdata += String.Format("0x{0:X4},", sData.Protection); // Protection sb.AppendFormat("0x{0:X4},", sData.Protection);
sdata += String.Format("0x{0:X4},", sData.Warning); // Warning sb.AppendFormat("0x{0:X4},", sData.Warning);
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0.0},", Convert.ToDouble(tData[i].BatVoltage) / 100); // Module Voltage sb.AppendFormat("{0:#0.0},", Convert.ToDouble(tData[i].BatVoltage) / 100);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0.0},", Convert.ToDouble(tData[i].Current) / 10); // Module Current sb.AppendFormat("{0:#0.0},", Convert.ToDouble(tData[i].Current) / 10);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0},", Convert.ToDouble(tData[i].RelativeStateOfCharge) / 10); // Module SOC sb.AppendFormat("{0:#0},", Convert.ToDouble(tData[i].RelativeStateOfCharge) / 10);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0.0},", Convert.ToDouble(tData[i].MaxTemp) / 10); // Module Max Temp sb.AppendFormat("{0:#0.0},", Convert.ToDouble(tData[i].MaxTemp) / 10);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0.0},", Convert.ToDouble(tData[i].MinTemp) / 10); // Module Min Temp sb.AppendFormat("{0:#0.0},", Convert.ToDouble(tData[i].MinTemp) / 10);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0.000},", Convert.ToDouble(tData[i].MaxCellVoltage) / 1000); // Cell Max Volage sb.AppendFormat("{0:#0.000},", Convert.ToDouble(tData[i].MaxCellVoltage) / 1000);
} }
for (int i = 0; i < sData.ModuleQuantity; i++) for (int i = 0; i < sData.ModuleQuantity; i++)
{ {
sdata += String.Format("{0:#0.000},", Convert.ToDouble(tData[i].MinCellVoltage) / 1000); // Cell Max Volage sb.AppendFormat("{0:#0.000},", Convert.ToDouble(tData[i].MinCellVoltage) / 1000);
} }
sdata += "\r\n"; sb.Append("\r\n");
Byte[] info = return new UTF8Encoding(true).GetBytes(sb.ToString());
new UTF8Encoding(true).GetBytes(sdata);
return info;
} }
#endregion #endregion
public void LoggingData(DeviceDataSystem sData, DeviceDataTray[] tData) public void LoggingData(DeviceDataSystem sData, DeviceDataTray[] tData)
{ {
string filename;
string path;
DateTime aLog = DateTime.Now; DateTime aLog = DateTime.Now;
FileStream fStream = null; string filename = String.Format("{0}log{1}.csv", LoggingFilePath, aLog.ToString("yyyyMMdd"));
byte[] logData; string path = System.IO.Path.GetDirectoryName(filename);
filename = String.Format("{0}log{1}.csv", LoggingFilePath, aLog.ToString("yyyyMMdd"));
path = System.IO.Path.GetDirectoryName(filename);
//if (Directory.Exists(SdCardPath) == true)
//{
try try
{ {
if (Directory.Exists(path) == false) if (Directory.Exists(path) == false)
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
if (File.Exists(filename)) bool fileExists = File.Exists(filename);
{ FileMode mode = fileExists ? FileMode.Open : FileMode.CreateNew;
fStream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite);
if (fStream != null) using (FileStream fStream = new FileStream(filename, mode, FileAccess.ReadWrite))
{ {
fStream.Seek(0, SeekOrigin.End); fStream.Seek(0, SeekOrigin.End);
logData = WriteData(sData, tData); if (!fileExists)
//logData = WriteData(sData, tDataA, tDataB);
fStream.Write(logData, 0, logData.Length);
fStream.Close();
}
}
else
{ {
fStream = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite); byte[] logHeader = WriteDataHeader(sData);
fStream.Write(logHeader, 0, logHeader.Length);
if (fStream != null)
{
fStream.Seek(0, SeekOrigin.End);
logData = WriteDataHeader(sData);
//logData = WriteDataHeader(sData, tDataA, tDataB);
fStream.Write(logData, 0, logData.Length);
logData = WriteData(sData, tData);
//logData = WriteData(sData, tDataA, tDataB);
fStream.Write(logData, 0, logData.Length);
fStream.Close();
} }
byte[] logData = WriteData(sData, tData);
fStream.Write(logData, 0, logData.Length);
} }
} }
catch (Exception) catch (Exception)
{ {
} }
//}
} }
public void InitPasswordData() public void InitPasswordData()
{ {
string filepath = PasswordFilePath; string filepath = PasswordFilePath;
FileStream fStream = null; using (FileStream fStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
byte[] bData;
fStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
if (fStream != null)
{ {
BMS_PASSWORD = "0000"; BMS_PASSWORD = "0000";
bData = Encoding.ASCII.GetBytes(BMS_PASSWORD); byte[] bData = Encoding.ASCII.GetBytes(BMS_PASSWORD);
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Write(bData, 0, bData.Length); fStream.Write(bData, 0, bData.Length);
fStream.Close();
} }
} }
public void SaveNewPasswordData(string new_password) public void SaveNewPasswordData(string new_password)
{ {
string filepath = PasswordFilePath; string filepath = PasswordFilePath;
FileStream fStream = null; using (FileStream fStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
byte[] bData;
fStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
if (fStream != null)
{ {
BMS_PASSWORD = new_password; BMS_PASSWORD = new_password;
bData = Encoding.ASCII.GetBytes(BMS_PASSWORD); byte[] bData = Encoding.ASCII.GetBytes(BMS_PASSWORD);
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Write(bData, 0, bData.Length); fStream.Write(bData, 0, bData.Length);
fStream.Close();
} }
} }
private void LoadPasswordData() private void LoadPasswordData()
{ {
long fsize = 0;
string filepath = PasswordFilePath; string filepath = PasswordFilePath;
FileStream fStream = null;
byte[] bData;
if (File.Exists(filepath)) if (File.Exists(filepath))
{ {
fStream = new FileStream(filepath, FileMode.Open, FileAccess.Read); using (FileStream fStream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
if (fStream != null)
{ {
fsize = fStream.Length; long fsize = fStream.Length;
bData = new byte[fsize]; byte[] bData = new byte[fsize];
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Read(bData, 0, Convert.ToInt32(fsize)); fStream.Read(bData, 0, Convert.ToInt32(fsize));
fStream.Close();
BMS_PASSWORD = Encoding.ASCII.GetString(bData, 0, Convert.ToInt32(fsize)); BMS_PASSWORD = Encoding.ASCII.GetString(bData, 0, Convert.ToInt32(fsize));
} }
} }
else else
{ {
fStream = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite); using (FileStream fStream = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite))
if (fStream != null)
{ {
BMS_PASSWORD = "0000"; BMS_PASSWORD = "0000";
bData = Encoding.ASCII.GetBytes(BMS_PASSWORD); byte[] bData = Encoding.ASCII.GetBytes(BMS_PASSWORD);
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Write(bData, 0, bData.Length); fStream.Write(bData, 0, bData.Length);
fStream.Close();
} }
} }
} }
private void LoadAlarmData() private void LoadAlarmData()
{ {
long fsize = 0;
string filepath = AlarmHistPath; string filepath = AlarmHistPath;
FileStream fStream = null;
byte[] bData = new byte[Marshal.SizeOf(AlarmList)]; byte[] bData = new byte[Marshal.SizeOf(AlarmList)];
if (File.Exists(AlarmHistPath)) if (File.Exists(AlarmHistPath))
{ {
fStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite); using (FileStream fStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite))
if (fStream != null)
{ {
fsize = fStream.Length; long fsize = fStream.Length;
if (Marshal.SizeOf(AlarmList) != fsize) if (Marshal.SizeOf(AlarmList) != fsize)
{ {
fStream.Close(); fStream.Close();
fStream = null;
File.Delete(filepath); File.Delete(filepath);
fStream = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite); using (FileStream newStream = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite))
{
newStream.SetLength(Marshal.SizeOf(AlarmList));
newStream.Seek(0, SeekOrigin.Begin);
newStream.Write(bData, 0, Marshal.SizeOf(AlarmList));
if (fStream != null) newStream.Seek(0, SeekOrigin.Begin);
newStream.Read(bData, 0, Marshal.SizeOf(AlarmList));
AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData);
}
}
else
{
fStream.Read(bData, 0, Marshal.SizeOf(AlarmList));
AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData);
}
}
}
else
{
using (FileStream fStream = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite))
{ {
fStream.SetLength(Marshal.SizeOf(AlarmList)); fStream.SetLength(Marshal.SizeOf(AlarmList));
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
@@ -371,32 +316,6 @@ namespace BMS_D1000H.Utils.Functions
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Read(bData, 0, Marshal.SizeOf(AlarmList)); fStream.Read(bData, 0, Marshal.SizeOf(AlarmList));
AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData); AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData);
fStream.Close();
}
}
else
{
fStream.Read(bData, 0, Marshal.SizeOf(AlarmList));
fStream.Close();
AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData);
}
}
}
else
{
fStream = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite);
if (fStream != null)
{
fStream.SetLength(Marshal.SizeOf(AlarmList));
fStream.Seek(0, SeekOrigin.Begin);
fStream.Write(bData, 0, Marshal.SizeOf(AlarmList));
fStream.Seek(0, SeekOrigin.Begin);
fStream.Read(bData, 0, Marshal.SizeOf(AlarmList));
AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData);
fStream.Close();
} }
} }
Make_Run_History(EventID.EVENT_INFO, AlarmID.POWER_ON_RESET, 0, 0, 0); Make_Run_History(EventID.EVENT_INFO, AlarmID.POWER_ON_RESET, 0, 0, 0);
@@ -406,18 +325,12 @@ namespace BMS_D1000H.Utils.Functions
{ {
long fsize = Marshal.SizeOf(AlarmList); long fsize = Marshal.SizeOf(AlarmList);
string filepath = AlarmHistPath; string filepath = AlarmHistPath;
FileStream fStream = null; byte[] bData = ConvertTo.StructureToByte(AlarmList);
byte[] bData = new byte[fsize];
bData = ConvertTo.StructureToByte(AlarmList); using (FileStream fStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite))
fStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite);
if (fStream != null)
{ {
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Write(bData, 0, Convert.ToInt32(fsize)); fStream.Write(bData, 0, Convert.ToInt32(fsize));
fStream.Close();
} }
} }
@@ -425,18 +338,14 @@ namespace BMS_D1000H.Utils.Functions
{ {
long fsize = Marshal.SizeOf(AlarmList); long fsize = Marshal.SizeOf(AlarmList);
string filepath = AlarmHistPath; string filepath = AlarmHistPath;
FileStream fStream = null;
byte[] bData = new byte[fsize]; byte[] bData = new byte[fsize];
System.Array.Clear(bData, 0, Convert.ToInt32(fsize)); System.Array.Clear(bData, 0, Convert.ToInt32(fsize));
fStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite); using (FileStream fStream = new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite))
if (fStream != null)
{ {
fStream.Seek(0, SeekOrigin.Begin); fStream.Seek(0, SeekOrigin.Begin);
fStream.Write(bData, 0, Convert.ToInt32(fsize)); fStream.Write(bData, 0, Convert.ToInt32(fsize));
fStream.Close();
AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData); AlarmList = ConvertTo.ByteToStruct<TAlarmList>(bData);
} }
@@ -447,25 +356,20 @@ namespace BMS_D1000H.Utils.Functions
public long GetFileSize(string FilePath) public long GetFileSize(string FilePath)
{ {
long fsize = 0; long fsize = 0;
FileStream fStream = null;
if (File.Exists(FilePath)) if (File.Exists(FilePath))
{ {
// Found using (FileStream fStream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite))
fStream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite); {
fsize = fStream.Length; fsize = fStream.Length;
}
fStream.Close();
} }
else else
{ {
// No File using (FileStream fStream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
fStream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); {
fsize = fStream.Length; fsize = fStream.Length;
}
fStream.Close();
} }
return fsize; return fsize;
@@ -560,29 +464,18 @@ namespace BMS_D1000H.Utils.Functions
public byte[] MakeHistoryCsvHeader() public byte[] MakeHistoryCsvHeader()
{ {
string str = ""; StringBuilder sb = new StringBuilder();
byte[] result; sb.Append("DateTime,Event,Alarm Name,Position,Parameter,\r\n");
return new UTF8Encoding(true).GetBytes(sb.ToString());
str += String.Format("DateTime,");
str += String.Format("Event,");
str += String.Format("Alarm Name,");
str += String.Format("Position,");
str += String.Format("Parameter,");
str += "\r\n";
result = new UTF8Encoding(true).GetBytes(str);
return result;
} }
public void Save_HistoryCsv(TAlarm hdata) public void Save_HistoryCsv(TAlarm hdata)
{ {
string wStr = ""; StringBuilder sb = new StringBuilder();
wStr = String.Format("{0:yyyy-MM-dd HH:mm:ss},", hdata.aTime); // DateTime - nHist.aTime.ToString("yyyy-MM-dd HH:mm:ss"); sb.AppendFormat("{0:yyyy-MM-dd HH:mm:ss},", hdata.aTime);
wStr += String.Format("{0},", EventID.event_name[hdata.aFlag]); // Event type - EventID.event_name[nHist.aFlag]; sb.AppendFormat("{0},", EventID.event_name[hdata.aFlag]);
wStr += String.Format("{0},", AlarmID.name[hdata.aNameNo]); // Alarm name - hAlarmName[hNo].Text = AlarmID.name[nHist.aNameNo]; sb.AppendFormat("{0},", AlarmID.name[hdata.aNameNo]);
//wStr += String.Format("{0}-{1},", PosID.pos[hdata.aPos], hdata.ctno); // Alarm position
switch (hdata.aNameNo) switch (hdata.aNameNo)
{ {
@@ -590,38 +483,38 @@ namespace BMS_D1000H.Utils.Functions
case AlarmID.COV_WARNING: case AlarmID.COV_WARNING:
case AlarmID.CUV_PROTECTION: case AlarmID.CUV_PROTECTION:
case AlarmID.CUV_WARNING: case AlarmID.CUV_WARNING:
wStr += String.Format("'{0}-{1},", PosID.pos[hdata.aPos], hdata.ctno); sb.AppendFormat("'{0}-{1},", PosID.pos[hdata.aPos], hdata.ctno);
wStr += String.Format("{0:#0.000},", Convert.ToDouble(hdata.aParam) / 1000); sb.AppendFormat("{0:#0.000},", Convert.ToDouble(hdata.aParam) / 1000);
break; break;
case AlarmID.OTC_PROTECTION: case AlarmID.OTC_PROTECTION:
case AlarmID.OTC_WARNING: case AlarmID.OTC_WARNING:
case AlarmID.OTD_PROTECTION: case AlarmID.OTD_PROTECTION:
case AlarmID.OTD_WARNING: case AlarmID.OTD_WARNING:
wStr += String.Format("'{0}-{1},", PosID.pos[hdata.aPos], hdata.ctno); sb.AppendFormat("'{0}-{1},", PosID.pos[hdata.aPos], hdata.ctno);
wStr += String.Format("{0:#0.0},", Convert.ToDouble(hdata.aParam) / 10); sb.AppendFormat("{0:#0.0},", Convert.ToDouble(hdata.aParam) / 10);
break; break;
case AlarmID.SOV_PROTECTION: case AlarmID.SOV_PROTECTION:
case AlarmID.SOV_WARNING: case AlarmID.SOV_WARNING:
case AlarmID.SUV_PROTECTION: case AlarmID.SUV_PROTECTION:
case AlarmID.SUV_WARNING: case AlarmID.SUV_WARNING:
wStr += String.Format("'{0},", PosID.pos[hdata.aPos]); sb.AppendFormat("'{0},", PosID.pos[hdata.aPos]);
wStr += String.Format("{0:#0.0},", Convert.ToDouble(hdata.aParam) / 100); sb.AppendFormat("{0:#0.0},", Convert.ToDouble(hdata.aParam) / 100);
break; break;
case AlarmID.OCC_PROTECTION: case AlarmID.OCC_PROTECTION:
case AlarmID.OCC_WARNING: case AlarmID.OCC_WARNING:
case AlarmID.OCD_PROTECTION: case AlarmID.OCD_PROTECTION:
case AlarmID.OCD_WARNING: case AlarmID.OCD_WARNING:
wStr += String.Format("'{0},", PosID.pos[hdata.aPos]); sb.AppendFormat("'{0},", PosID.pos[hdata.aPos]);
wStr += String.Format("{0:#0.0},", Convert.ToDouble(hdata.aParam) / 10); sb.AppendFormat("{0:#0.0},", Convert.ToDouble(hdata.aParam) / 10);
break; break;
default: default:
wStr += String.Format("'{0},", PosID.pos[hdata.aPos]); sb.AppendFormat("'{0},", PosID.pos[hdata.aPos]);
wStr += String.Format(","); sb.Append(",");
break; break;
} }
wStr += "\r\n"; sb.Append("\r\n");
byte[] bAlm = new UTF8Encoding(true).GetBytes(wStr); byte[] bAlm = new UTF8Encoding(true).GetBytes(sb.ToString());
string filename = String.Format("{0}Alm_{1}.csv", AlarmHistCsvPath, DateTime.Now.ToString("yyyyMMdd")); string filename = String.Format("{0}Alm_{1}.csv", AlarmHistCsvPath, DateTime.Now.ToString("yyyyMMdd"));
string path = System.IO.Path.GetDirectoryName(filename); string path = System.IO.Path.GetDirectoryName(filename);
@@ -631,30 +524,18 @@ namespace BMS_D1000H.Utils.Functions
if (Directory.Exists(path) == false) if (Directory.Exists(path) == false)
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
if (File.Exists(filename)) bool fileExists = File.Exists(filename);
{ FileMode mode = fileExists ? FileMode.Open : FileMode.CreateNew;
FileStream fStream = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite);
if (fStream != null) using (FileStream fStream = new FileStream(filename, mode, FileAccess.ReadWrite))
{ {
fStream.Seek(0, SeekOrigin.End); fStream.Seek(0, SeekOrigin.End);
fStream.Write(bAlm, 0, bAlm.Length); if (!fileExists)
fStream.Close();
}
}
else
{ {
FileStream fStream = new FileStream(filename, FileMode.CreateNew, FileAccess.ReadWrite);
if (fStream != null)
{
fStream.Seek(0, SeekOrigin.End);
byte[] hdr = MakeHistoryCsvHeader(); byte[] hdr = MakeHistoryCsvHeader();
fStream.Write(hdr, 0, hdr.Length); fStream.Write(hdr, 0, hdr.Length);
fStream.Write(bAlm, 0, bAlm.Length);
fStream.Close();
} }
fStream.Write(bAlm, 0, bAlm.Length);
} }
} }
catch (Exception) catch (Exception)

Binary file not shown.

Binary file not shown.

View File

@@ -272,3 +272,26 @@ C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\Smar
C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\SmartXCommonExt.dll C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\SmartXCommonExt.dll
C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\System.Data.SqlServerCe.dll C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\System.Data.SqlServerCe.dll
C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.exe C:\Users\JK.Woo\Desktop\Project\KT\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.exe
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\BMS_D1000H.exe
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\BMS_D1000H.pdb
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\SmartX_IEC1000.dll
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\SmartXCommon.dll
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\SmartXCommonExt.dll
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\bin\Release\System.Data.SqlServerCe.dll
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\ResolveAssemblyReference.cache
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmSystemSet.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmBMSMain.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmHistory.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmNetConfig.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmNetConfigCmd.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmParamSet.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmParamSetCmd.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmPassword.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmScreenSaver.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmSetMenu.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmSystemSetCmd.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.fmTrayInfo.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.Properties.Resources.resources
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000.csproj.GenerateResource.Cache
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.exe
F:\Project\KT\LCD\BMS_D1000_V1009_AG\BMS_D1000\obj\Release\BMS_D1000H.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -41,36 +41,36 @@
--- ---
### 🧹 2.3 미사용(Dead) 파일 및 프로젝트 정리 (Low Priority) ### 🧹 2.3 미사용(Dead) 파일 및 프로젝트 정리 (Low Priority) **(완료)**
1. **미사용 더미 Form 파일 방치** 1. **미사용 더미 Form 파일 방치** **(완료)**
- **위치**: [`Form1.cs`](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Form1.cs), `Form2.cs`, `Form3.cs`, `Form4.cs` (프로젝트 루트 디렉터리) - **위치**: `Form1.cs`, `Form2.cs`, `Form3.cs`, `Form4.cs` (프로젝트 루트 디렉터리)
- **문제점**: `BMS_D1000.csproj`에 포함되지 않은 빈 WinForm 소스 파일들이 루트 디렉터리에 남아있어 개발 시 혼란을 유발할 수 있습니다. - **문제점**: `BMS_D1000.csproj`에 포함되지 않은 빈 WinForm 소스 파일들이 루트 디렉터리에 남아있어 개발 시 혼란을 유발할 수 있습니다.
- **개선안**: 불필요한 `Form1`~`Form4``.resx`, `.Designer.cs` 파일 삭제. - **개선안**: 불필요한 `Form1`~`Form4``.resx`, `.Designer.cs` 파일 삭제. (조치 완료: 존재하지 않음 확인)
2. **Service 디렉터리의 `Class1.cs` 빌드 미포함** 2. **Service 디렉터리의 `Class1.cs` 빌드 미포함 및 미사용 참조** **(완료)**
- **위치**: [`Service/Class1.cs`](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Service/Class1.cs) - **위치**: `Service/`
- **문제점**: csproj에는 `<Folder Include="Service\" />` 폴더만 등록되어 있고 `Class1.cs` 소스 파일이 Compile 항목에서 누락되어 있음. - **문제점**: csproj에는 `<Folder Include="Service\" />` 폴더만 등록되어 있고 소스 파일이 존재하지 않거나 누락됨.
- **개선안**: 해당 소스가 필요한 기능인지 확인 후 `csproj` 포함하거나 삭제. - **개선안**: 해당 소스가 필요한 기능인지 확인 후 `csproj`서 불필요한 `<Folder Include="Service\" />` 구문 제거 및 폴더 정리 완료.
3. **`Old/` 디렉터리 백업 관리** 3. **`Old/` 디렉터리 백업 및 Git `.gitignore` 점검** **(완료)**
- **위치**: `BMS_D1000/Old/` - **위치**: 워크스페이스 루트
- **문제점**: 소스 제어 시스템(Git 등)을 사용 중이라면 형상 관리에 남아있을 이전 버전 백업 디렉터리가 로컬 워크스페이스에 방치됨. - **문제점**: 빌드 산출물 및 임시 파일이 소스 제어에 등록되는 문제 방지.
- **개선안**: 필요에 따라 로컬 정리 및 `.gitignore` 설정 점검. - **개선안**: 프로젝트 루트에 Visual Studio / C# 용 `.gitignore` 파일 생성 완료.
--- ---
### ⚡ 2.4 메모리 & 성능 최적화 (Optimization) ### ⚡ 2.4 메모리 & 성능 최적화 (Optimization) **(완료)**
1. **문자열 연산 시 Garbage Collector (GC) 부하 유발** 1. **문자열 연산 시 Garbage Collector (GC) 부하 유발** **(완료)**
- **위치**: [`AlarmFile.cs`](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Utils/Function/AlarmFile.cs#L100-L134) - **위치**: [`AlarmFile.cs`](file:///z:/KT/LCD/BMS_D1000_V1009_AG/BMS_D1000/Utils/Function/AlarmFile.cs)
- **문제점**: `WriteDataHeader` 등 로그 작성 루프 내에서 `+` 연산자로 문자열 연결(String Concatenation)을 다수 수행하여 GC 힙 메모리 할당이 빈번하게 일어납니다. Windows CE 디바이스는 RAM 자원이 매우 제한적이므로 GC 파즈(Pause)에 취약합니다. - **문제점**: `WriteDataHeader` 등 로그 작성 루프 내에서 `+` 연산자로 문자열 연결(String Concatenation)을 다수 수행하여 GC 힙 메모리 할당이 빈번하게 일어납니다. Windows CE 디바이스는 RAM 자원이 매우 제한적이므로 GC 파즈(Pause)에 취약합니다.
- **개선안**: `StringBuilder` 패턴으로 변경하여 문자열 생성 효율 극대화. - **개선안**: `StringBuilder` 패턴으로 변경하여 문자열 생성 효율 극대화 및 GC 부하 최소화 완료.
2. **파일 I/O 핸들 누수 방지** 2. **파일 I/O 핸들 누수 방지** **(완료)**
- **위치**: [`AlarmFile.cs`](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Utils/Function/AlarmFile.cs) - **위치**: [`AlarmFile.cs`](file:///z:/KT/LCD/BMS_D1000_V1009_AG/BMS_D1000/Utils/Function/AlarmFile.cs)
- **문제점**: `FileStream` 생성 및 닫기(`Close()`) 시 `try-finally` 또는 `using` 문 구문을 적극적으로 사용하지 않아 예외 발생 시 파일 잠금(Lock) 또는 핸들 누수가 지속될 수 있음. - **문제점**: `FileStream` 생성 및 닫기(`Close()`) 시 예외 발생 시 파일 잠금(Lock) 또는 핸들 누수가 지속될 수 있음.
- **개선안**: 파일 연산 시 `using (FileStream fs = ...)` 블록 적용. - **개선안**: 파일 연산 시 `using (FileStream fs = ...)` 블록 구문을 일관되게 적용하여 자동 자원 해제 완료.
--- ---
@@ -78,8 +78,8 @@
| 우선순위 | 구분 | 대상 파일 / 모듈 | 권장 조치 내용 | | 우선순위 | 구분 | 대상 파일 / 모듈 | 권장 조치 내용 |
| :--- | :--- | :--- | :--- | | :--- | :--- | :--- | :--- |
| **P1** | **안정성** | [csModbusDataProcess.cs](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Functions/csModbusDataProcess.cs) | 배열 범위 검사 방어 로직 추가 **(완료)** | | **P1** | **안정성** | [csModbusDataProcess.cs](file:///z:/KT/LCD/BMS_D1000_V1009_AG/BMS_D1000/Functions/csModbusDataProcess.cs) | 배열 범위 검사 방어 로직 추가 **(완료)** |
| **P1** | **안정성** | [Program.cs](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Program.cs) | 전역 예외 처리기(Unhandled Exception Handler) 추가 **(완료)** | | **P1** | **안정성** | [Program.cs](file:///z:/KT/LCD/BMS_D1000_V1009_AG/BMS_D1000/Program.cs) | 전역 예외 처리기(Unhandled Exception Handler) 추가 **(완료)** |
| **P2** | **자원 관리** | [AlarmFile.cs](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Utils/Function/AlarmFile.cs) | `using` 구문 적용 및 `StringBuilder` 사용, 경로 동적 추상화(`PathHelper`) **(완료)** | | **P2** | **자원 관리** | [AlarmFile.cs](file:///z:/KT/LCD/BMS_D1000_V1009_AG/BMS_D1000/Utils/Function/AlarmFile.cs) | `using` 구문 적용 및 `StringBuilder` 사용, 경로 동적 추상화(`PathHelper`) **(완료)** |
| **P2** | **코드 가독성** | [csModbusDataProcess.cs](file:///c:/Users/JK.Woo/Desktop/Project/KT/BMS_D1000_V1009_AG/BMS_D1000/Functions/csModbusDataProcess.cs) | 거대 `switch-case` 모듈화 및 범위 기반 레지스터 매핑 리팩토링 **(완료)** | | **P2** | **코드 가독성** | [csModbusDataProcess.cs](file:///z:/KT/LCD/BMS_D1000_V1009_AG/BMS_D1000/Functions/csModbusDataProcess.cs) | 거대 `switch-case` 모듈화 및 범위 기반 레지스터 매핑 리팩토링 **(완료)** |
| **P3** | **코드 정리** | 루트 Form 파일들 (`Form1`~`Form4`), `Service/Class1.cs` | 불필요한 더미 소스 정리 csproj 동기화 | | **P3** | **코드 정리** | 루트 Form 파일들 (`Form1`~`Form4`), `Service/` | 불필요한 더미 소스 정리, csproj 동기화`.gitignore` 설정 추가 **(완료)** |