Files
JP_KDDI_LFPS_48100/LFP_Manager/Forms/fmxMain.cs
2025-12-19 13:59:34 +09:00

1294 lines
45 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using LFP_Manager.Forms;
using LFP_Manager.Controls;
using LFP_Manager.DataStructure;
using LFP_Manager.Function;
using LFP_Manager.Threads;
using LFP_Manager.Utils;
using DevExpress.Utils.Drawing.Helpers;
using System.Threading.Tasks;
using static LFP_Manager.Threads.csDbThread;
namespace LFP_Manager.Forms
{
public partial class fmxMain : DevExpress.XtraEditors.XtraForm
{
#region VARIABLES
// Child form
private fmxInventoryConfig InventoryConfig = null;
private fmxModuleDetail ModuleDetailForm = null;
private fmxFwUpdate FwUpdateForm = null;
private fmxHistory HistoryForm = null;
// Static Variables
private CommConfig Config = new CommConfig();
private CsDeviceData DeviceData = new CsDeviceData();
// Thread Variables
private csUartThread uartThread = null;
private CsUartThreadSB rs485Thread = null;
private CsSnmpThread snmpThread = null;
private csDbThread dbThread = null;
private ucMainStatus MainStatus = null;
private ucShelfStatus ShelfStatus = null;
private int ModuleID = 1;
bool Active = false;
#endregion
#region CONSTRUCTORS
public fmxMain()
{
InitializeComponent();
IniLoad(ref Config);
uTarget.OnConfig += ConfigButtonClick;
uTarget.OnStart += StartButtonClick;
uDataLog.OnUpdate += LogStatusUpdate;
DisplaySystemFwVerModule();
}
private void IniLoad(ref CommConfig aConfig)
{
csIniControlFunction.IniLoad(Application.ExecutablePath, ref aConfig);
uTarget.UpdateConfig(ref aConfig);
TypeChangedUpdate(ref aConfig);
}
#endregion
#region BUTTON EVENT
private void ConfigButtonClick(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "fmxCommConfig")
{
frm.Activate();
return;
}
}
fmxCommConfig CommConfigForm = new fmxCommConfig
{
Owner = this
};
CommConfigForm.OnUpdate += UpdateConfig;
CommConfigForm.Show();
}
private void StartButtonClick(object sender, EventArgs e)
{
if (Active)
{
DeviceData.Reset();
switch (Config.CommType)
{
case csConstData.CommType.COMM_UART:
if (uartThread != null)
{
StopUart(); // 내부에서 UnwireUart → Dispose 순서 수행
edModuleID.Enabled = true;
chbPolling.Enabled = true;
}
break;
case csConstData.CommType.COMM_RS485:
// DELTA Protocol
if (rs485Thread != null)
{
StopRS485(); // 내부에서 UnwireRs485 → Dispose 순서 수행
edModuleID.Enabled = true;
chbPolling.Enabled = true;
}
break;
case csConstData.CommType.COMM_SNMP:
break;
default:
break;
}
if (snmpThread != null)
{
snmpThread.disposeThread();
snmpThread = null;
UpdateSnmpData(this, ref DeviceData.ModuleData[0]);
}
if (dbThread != null)
{
//dbThread.Stop();
dbThread.OnUpdateAlarmHistory -= UpdateAlarmHistory;
dbThread.OnPrint -= ErrorOnPrint;
dbThread.Dispose();
dbThread = null;
}
Active = false;
}
else
{
try
{
ModuleID = Convert.ToInt16(edModuleID.Text);
}
catch (Exception)
{
MessageBox.Show("Wrong Module ID - Please check module ID", "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
switch (Config.CommType)
{
case csConstData.CommType.COMM_UART:
// UART MODE - RS-232
CommUARTStart();
break;
case csConstData.CommType.COMM_RS485:
// UART MODE - RS-485
CommRS485Start();
break;
case csConstData.CommType.COMM_SNMP:
StartProcessSNMP();
break;
}
}
uTarget.UpdateStatus(Active);
uDataLog.UpdateActiveStatus(Active, Config, ref DeviceData);
DisplayCommStatus();
}
private void UartRecvData(byte[] data)
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate ()
{
FwUpdateForm?.RecvData(data);
HistoryForm?.RecvUardData(data);
}));
}
else
{
FwUpdateForm?.RecvData(data);
HistoryForm?.RecvUardData(data);
}
}
private void CommUARTStart()
{
try
{
int mId = string.IsNullOrEmpty(edModuleID.Text) ? 0 : Convert.ToInt32(edModuleID.Text);
if (mId == 0) { throw new Exception("System ID is zero."); }
// 혹시 기존 인스턴스가 남아 있다면 먼저 해제
StopUart();
if (dbThread != null)
{
dbThread.OnUpdateAlarmHistory -= UpdateAlarmHistory;
dbThread.OnPrint -= ErrorOnPrint;
dbThread.Dispose();
dbThread = null;
}
uartThread = new csUartThread(mId, Config, this, DeviceData.ModuleData[0]);
WireUart(uartThread); // ← 구독은 Start 전에
uartThread.SetPolling(chbPolling.Checked, mId, ref DeviceData.ModuleData[0]);
if (uartThread.Start(ref Config, mId, chbPolling.Checked))
{
Active = true;
chbPolling.Enabled = true;
edModuleID.Enabled = !chbPolling.Checked;
ShelfStatus?.UpdateSystemId(mId);
dbThread = new csDbThread(Config, this, DeviceData);
dbThread.OnUpdateAlarmHistory += UpdateAlarmHistory;
dbThread.OnPrint += ErrorOnPrint;
dbThread.Start(Config);
}
else
{
StopUart();
if (dbThread != null)
{
dbThread.OnUpdateAlarmHistory -= UpdateAlarmHistory;
dbThread.OnPrint -= ErrorOnPrint;
dbThread.Dispose();
dbThread = null;
}
}
}
catch (Exception ex)
{
// 예외 시에도 반드시 해제 + Dispose
StopUart();
dbThread?.Dispose();
dbThread = null;
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void StopUart()
{
if (uartThread != null)
{
UnwireUart(); // 1) 구독 해제
uartThread.Dispose(); // 2) 스레드/포트 정리(Stop 포함)
uartThread = null;
}
}
private void CommRS485Start()
{
try
{
int mId = string.IsNullOrEmpty(edModuleID.Text) ? 0 : Convert.ToInt32(edModuleID.Text);
if (mId == 0) { throw new Exception("System ID is zero."); }
StopRS485();
rs485Thread = new CsUartThreadSB(mId, Config, this, DeviceData.ModuleData);
WireRs485(rs485Thread); // ← 구독
rs485Thread.SetPolling(chbPolling.Checked, mId, ref DeviceData.ModuleData);
if (rs485Thread.Start(ref Config, ModuleID, chbPolling.Checked))
{
Active = true;
chbPolling.Enabled = true;
edModuleID.Enabled = !chbPolling.Checked;
//if (Config.ModuleQty > 1)
// MainStatus?.Start(Config, DeviceData);
//else
// ShelfStatus?.UpdateSystemId(ModuleID);
dbThread = new csDbThread(Config, this, DeviceData);
dbThread.OnUpdateAlarmHistory += UpdateAlarmHistory;
dbThread.OnPrint += ErrorOnPrint;
dbThread.Start(Config);
}
else
{
StopRS485();
if (dbThread != null)
{
dbThread.OnUpdateAlarmHistory -= UpdateAlarmHistory;
dbThread.OnPrint -= ErrorOnPrint;
dbThread.Dispose();
dbThread = null;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (rs485Thread != null)
{
rs485Thread.Dispose();
rs485Thread = null;
}
if (dbThread != null)
{
dbThread.Dispose();
dbThread = null;
}
}
}
private void StopRS485()
{
if (rs485Thread != null)
{
UnwireRs485(); // 1) 구독 해제
rs485Thread.Dispose(); // 2) 스레드/포트 정리(Stop 포함)
rs485Thread = null;
}
}
private void StartProcessSNMP()
{
try
{
snmpThread = new CsSnmpThread(Config, ref DeviceData.ModuleData[ModuleID - 1]);
snmpThread.OnUpdate += UpdateSnmpData;
snmpThread.OnSetResult += SnmpRecvData;
snmpThread.Start(Config.SnmpIP, chbPolling.Checked);
Active = true;
dbThread = new csDbThread(Config, this, DeviceData);
dbThread.OnUpdateAlarmHistory += UpdateAlarmHistory;
dbThread.OnPrint += ErrorOnPrint;
dbThread.Start(Config);
}
catch (Exception)
{
if (snmpThread == null)
{
snmpThread.disposeThread();
snmpThread = null;
}
if (dbThread != null)
{
dbThread.OnUpdateAlarmHistory -= UpdateAlarmHistory;
dbThread.OnPrint -= ErrorOnPrint;
dbThread.Dispose();
dbThread = null;
}
}
}
#endregion
#region UPDATE FUNCTIONS
private void TypeChangeUpdateUart(ref CommConfig aConfig)
{
tabStatus.TabPages[0].PageVisible = true;
for (int i = 1; i < tabStatus.TabPages.Count; i++)
{
tabStatus.TabPages[i].PageVisible = false;
}
tabStatus.TabPages[0].Text = String.Format("LFP Module [{0}.{1}.{2}.{3}]"
, 0
, 0
, 0
, 0
);
ShelfStatus = new ucShelfStatus();
ShelfStatus.OnCommand += SetCmdEvent;
ShelfStatus.Dock = DockStyle.Fill;
tabStatus.TabPages[0].PageVisible = true;
tabStatus.TabPages[0].Controls.Add(ShelfStatus);
ShelfStatus.Start(Convert.ToInt32(edModuleID.Text), ref aConfig, ref DeviceData.ModuleData);
edModuleID.Enabled = true;
chbPolling.Enabled = true;
}
private void TypeChangeUpdateRS485(ref CommConfig aConfig)
{
// Display Screen Delete
if (MainStatus != null)
{
MainStatus.Dispose();
MainStatus = null;
}
if (ShelfStatus != null)
{
ShelfStatus.Dispose();
ShelfStatus = null;
}
if (aConfig.ModuleQty > 1)
{
// All disable first
for (int i = 0; i < tabStatus.TabPages.Count; i++)
{
tabStatus.TabPages[i].PageVisible = false;
}
MainStatus = new ucMainStatus();
MainStatus.OnCommand += SetCmdEvent;
tabStatus.TabPages[0].Text = string.Format("LFP System");
tabStatus.TabPages[0].PageVisible = true;
tabStatus.TabPages[0].Controls.Add(MainStatus);
MainStatus.Dock = DockStyle.Fill;
MainStatus.UpdateMainConfig(Config, DeviceData);
MainStatus.Start(aConfig, DeviceData);
edModuleID.Enabled = false;
chbPolling.Enabled = false;
}
else
{
tabStatus.TabPages[0].PageVisible = true;
for (int i = 1; i < tabStatus.TabPages.Count; i++)
{
tabStatus.TabPages[i].PageVisible = false;
}
tabStatus.TabPages[0].Text = String.Format("LFP Module [{0}.{1}.{2}.{3}]"
, 0
, 0
, 0
, 0
);
ShelfStatus = new ucShelfStatus();
ShelfStatus.OnCommand += SetCmdEvent;
ShelfStatus.OnSendUartData += SetWriteData;
ShelfStatus.Dock = DockStyle.Fill;
tabStatus.TabPages[0].PageVisible = true;
tabStatus.TabPages[0].Controls.Add(ShelfStatus);
ShelfStatus.Start(ModuleID, ref aConfig, ref DeviceData.ModuleData);
edModuleID.Enabled = true;
chbPolling.Enabled = true;
}
}
private void TypeChangeUpdateSnmp(ref CommConfig aConfig)
{
tabStatus.TabPages[0].PageVisible = true;
for (int i = 1; i < tabStatus.TabPages.Count; i++)
{
tabStatus.TabPages[i].PageVisible = false;
}
tabStatus.TabPages[0].Text = String.Format("LFP Module [{0}.{1}.{2}.{3}]"
, 0
, 0
, 0
, 0
);
ShelfStatus = new ucShelfStatus();
ShelfStatus.OnCommand += SetCmdEvent;
ShelfStatus.Dock = DockStyle.Fill;
tabStatus.TabPages[0].PageVisible = true;
tabStatus.TabPages[0].Controls.Add(ShelfStatus);
ShelfStatus.Start(ModuleID, ref aConfig, ref DeviceData.ModuleData);
edModuleID.Enabled = false;
chbPolling.Enabled = true;
}
private void TypeChangedUpdate(ref CommConfig aConfig)
{
tabStatus.TabPages[0].Controls.Clear();
// Display Screen Deletes
if (ShelfStatus != null)
{
ShelfStatus.Dispose();
ShelfStatus = null;
}
SetCellTempQty(aConfig, ref DeviceData.ModuleData);
try
{
ModuleID = Convert.ToInt16(edModuleID.Text);
}
catch (Exception)
{
ModuleID = 1;
}
switch (aConfig.CommType)
{
case csConstData.CommType.COMM_UART:
TypeChangeUpdateUart(ref aConfig);
historyToolStripMenuItem.Visible = true;
inventoryViewToolStripMenuItem.Visible = true;
updateToolStripMenuItem.Visible = false;
break;
case csConstData.CommType.COMM_RS485:
TypeChangeUpdateRS485(ref aConfig);
historyToolStripMenuItem.Visible = true;
inventoryViewToolStripMenuItem.Visible = false;
updateToolStripMenuItem.Visible = true;
break;
case csConstData.CommType.COMM_SNMP:
TypeChangeUpdateSnmp(ref aConfig);
historyToolStripMenuItem.Visible = true;
inventoryViewToolStripMenuItem.Visible = false;
updateToolStripMenuItem.Visible = false;
break;
default:
break;
}
//DisplayCommStatus();
}
private void SetCellTempQty(CommConfig aConfig, ref CsDeviceData.DeviceModuleData[] mData)
{
switch (aConfig.CommType)
{
case csConstData.CommType.COMM_UART:
case csConstData.CommType.COMM_RS485:
switch (aConfig.UartModelIndex)
{
case csConstData.UART_MODEL_INDEX.LFPM_48100D:
case csConstData.UART_MODEL_INDEX.LFPM_48150D:
case csConstData.UART_MODEL_INDEX.LFPM_48200D:
case csConstData.UART_MODEL_INDEX.LFPM_48250D:
case csConstData.UART_MODEL_INDEX.LFPM_48300D:
for (int i = 0; i < mData.Length; i++)
{
mData[i].cellQty = 15;
mData[i].tempQty = 4;
}
break;
case csConstData.UART_MODEL_INDEX.LFPM_124050D:
for (int i = 0; i < mData.Length; i++)
{
mData[i].cellQty = csConstData.SystemInfo.MAX_MODULE_CELL_SIZE;
mData[i].tempQty = csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE;
}
break;
default:
break;
}
break;
case csConstData.CommType.COMM_SNMP:
switch (aConfig.SnmpModelIndex)
{
case csConstData.UART_MODEL_INDEX.LFPM_48100D:
case csConstData.UART_MODEL_INDEX.LFPM_48150D:
case csConstData.UART_MODEL_INDEX.LFPM_48200D:
case csConstData.UART_MODEL_INDEX.LFPM_48250D:
case csConstData.UART_MODEL_INDEX.LFPM_48300D:
for (int i = 0; i < mData.Length; i++)
{
mData[i].cellQty = 15;
mData[i].tempQty = 4;
}
break;
case csConstData.UART_MODEL_INDEX.LFPM_124050D:
for (int i = 0; i < mData.Length; i++)
{
mData[i].cellQty = csConstData.SystemInfo.MAX_MODULE_CELL_SIZE;
mData[i].tempQty = csConstData.SystemInfo.MAX_MODULE_TEMP_SIZE;
}
break;
default:
break;
}
break;
default:
for (int i = 0; i < mData.Length; i++)
{
mData[i].cellQty = 15;
mData[i].tempQty = 4;
}
break;
}
}
private void DisplaySystemFwVerModule()
{
switch (Config.ControlLevel)
{
case 0: // User Level
inventoryViewToolStripMenuItem.Visible = false;
break;
case 1: // Technician Level
inventoryViewToolStripMenuItem.Visible = false;
break;
case 2: // Engineer Level
inventoryViewToolStripMenuItem.Visible = false;
break;
case 3: // Master Level
inventoryViewToolStripMenuItem.Visible = true;
break;
default: // User Level
inventoryViewToolStripMenuItem.Visible = false;
break;
}
switch (Config.ControlLevel)
{
case 0: // User Level
this.Text = String.Format("LFP SYSTEM [{0}] -- SB - User Level", Application.ProductVersion);
break;
case 1: // Technician Level
this.Text = String.Format("LFP SYSTEM [{0}] -- SB - Technician Level", Application.ProductVersion);
break;
case 2: // Engineer Level
this.Text = String.Format("LFP SYSTEM [{0}] -- SB - Engineer Level", Application.ProductVersion);
break;
case 3: // Master Level
this.Text = String.Format("LFP SYSTEM [{0}] -- SB - Master Level", Application.ProductVersion);
break;
default:
this.Text = String.Format("LFP SYSTEM [{0}] -- SB - User Level", Application.ProductVersion);
break;
}
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate ()
{
if (DeviceData.ModuleData[0].ValueData.fw_ver[0] != 0x00)
{
byte[] sn = new byte[33];
for (int i = 0; i < 32; i++)
sn[i] = DeviceData.ModuleData[0].Information.BMS_SN[i];
sn[32] = 0;
tabStatus.TabPages[0].Text = String.Format("{0} [{1}] - {2}", "LFP MODULE"
, Encoding.UTF8.GetString(DeviceData.ModuleData[0].ValueData.fw_ver)
, Encoding.Default.GetString(sn).Trim('\0')
);
}
else
{
tabStatus.TabPages[0].Text = String.Format("LFP MODULE");
}
}));
}
else
{
if (DeviceData.ModuleData[0].ValueData.fw_ver[0] != 0x00)
{
byte[] sn = new byte[17];
for (int i = 0; i < 16; i++)
sn[i] = DeviceData.ModuleData[0].Information.BMS_SN[i]; //22.06.30 Byul 32->16
sn[16] = 0;
tabStatus.TabPages[0].Text = String.Format("{0} [{1}] - {2}", "LFP MODULE"
, Encoding.UTF8.GetString(DeviceData.ModuleData[0].ValueData.fw_ver).Trim('\0')
, Encoding.Default.GetString(sn).Trim('\0')
);
}
else
{
tabStatus.TabPages[0].Text = String.Format("LFP MODULE");
}
}
}
private void UpdateSnmpData(object sender, ref CsDeviceData.DeviceModuleData mData)
{
DeviceData.ModuleData[0] = mData;
uDataLog.UpdateData(DeviceData);
}
private void UpdateConfig(object aConfig)
{
Config = (CommConfig)aConfig;
IniLoad(ref Config);
}
#endregion
#region MENU EVENT
private void commConfigToolStripMenuItem_Click(object sender, EventArgs e)
{
ConfigButtonClick(sender, e);
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void testSendToolStripMenuItem_Click(object sender, EventArgs e)
{
csHistoryFunction.DbCreate(System.IO.Path.GetDirectoryName(Application.ExecutablePath));
}
private void firmwareUpdateToolStripMenuItem_Click(object sender, EventArgs e)
{
if (rs485Thread == null) return;
FwUpdateForm = new fmxFwUpdate(rs485Thread.ModuleID);
FwUpdateForm.OnAutoTxSet += SetAutoTx;
FwUpdateForm.OnSendUartData += SetWriteData;
FwUpdateForm.ShowDialog();
}
private void historyViewToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "fmxHistory")
{
frm.Activate();
return;
}
}
HistoryForm = new fmxHistory(Config, ModuleID);
HistoryForm.OnSendUartData += SetWriteData;
HistoryForm.ShowDialog();
}
private void inventoryViewToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "fmxInventoryConfig")
{
frm.Activate();
return;
}
}
InventoryConfig = new fmxInventoryConfig(ModuleID, ref Config, ref DeviceData.ModuleData[ModuleID - 1]);
InventoryConfig.OnSendUartData += SetWriteData;
InventoryConfig.Show();
}
#endregion
#region FORM EVENT
private void fmxMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (uartThread != null)
{
uartThread.Dispose();
uartThread = null;
}
if (rs485Thread != null)
{
rs485Thread.Dispose();
rs485Thread = null;
}
if (snmpThread != null)
{
snmpThread.disposeThread();
snmpThread = null;
}
if (dbThread != null)
{
dbThread.Dispose();
dbThread = null;
}
}
#endregion
#region STATUS BAR EVENT
void DisplayCommStatus()
{
if (Active == true)
CommStatusBar.Text = "Comm: On";
else
CommStatusBar.Text = "Comm: Off";
}
void DisplayCommStatus(string msg)
{
if (msg != "")
CommStatusBar.Text = String.Format("Comm: {0}", msg);
}
void LogStatusUpdate(object sender, string msg, bool active, int aLogTime)
{
LogStatusBar.Text = msg;
}
#endregion
#region COMMAND AND SET
private void CommDataPrint(object sender, int id, string msg)
{
if (msg != "")
{
uEventLog.EventUpdate(id, msg + "\r\n");
}
}
private void SetWriteData(ushort WriteAddr, byte[] WriteData, bool RelyFlag, int type)
{
uartThread?.SetWriteReg(WriteAddr, WriteData, RelyFlag, type);
rs485Thread?.SetWriteReg(WriteAddr, WriteData, RelyFlag, type);
}
private void SetCmdEvent(int sId, int cmd, int index, int flag,
ref CsDeviceData.DeviceModuleData.DeviceParamData aParam,
ref CsDeviceData.DeviceModuleData.DeviceCalibration aCalib)
{
if (MainStatus != null)
{
switch (cmd)
{
case 1: // Module quatity set
break;
case 2:
CreateModuleDetailForm(sId);
break;
}
}
uartThread?.SendProcessFromApp(sId, cmd, index, flag, ref aParam, ref aCalib);
}
private void CreateModuleDetailForm(int sID)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "fmxModuleDetail")
{
((fmxModuleDetail)frm).SetModuleID(sID);
frm.Activate();
return;
}
}
ModuleDetailForm = new fmxModuleDetail(sID, ref Config, ref DeviceData.ModuleData);
//ModuleDetailForm.OnAutoTxCanSet += SetAutoTxCan;
//ModuleDetailForm.OnSendDataCan += SendDataToCan;
ModuleDetailForm.Show();
}
private void chbPolling_CheckedChanged(object sender, EventArgs e)
{
if (edModuleID.Text != "")
{
ModuleID = Convert.ToInt32(edModuleID.Text);
if (uartThread != null)
{
uartThread.SetPolling(chbPolling.Checked, ModuleID, ref DeviceData.ModuleData[ModuleID - 1]);
ShelfStatus?.UpdateSystemId(ModuleID);
}
if (rs485Thread != null)
{
rs485Thread.SetPolling(chbPolling.Checked, ModuleID, ref DeviceData.ModuleData);
ShelfStatus?.UpdateSystemId(ModuleID);
}
snmpThread?.SetAutoTx(chbPolling.Checked);
uDataLog.UpdateActiveStatus(Active, Config, ref DeviceData);
edModuleID.Enabled = !chbPolling.Checked;
}
}
private void SnmpRecvData(string result, bool error)
{
if (result != "")
{
uEventLog.EventUpdate(0, result + "\r\n");
}
}
private void SetAutoTx(bool autoTx)
{
uartThread?.SetAutoTx(autoTx);
}
#endregion
#region KEYBOARD HOOK
private void edSystemId_KeyPress(object sender, KeyPressEventArgs e)
{
csUtils.TypingOnlyNumber(sender, e, false, false);
}
#endregion
#region MENU COMMAND
private void inventoryControlToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "fmxInventoryConfig")
{
frm.Activate();
return;
}
}
InventoryConfig = new fmxInventoryConfig(0, ref Config, ref DeviceData.ModuleData[0]);
InventoryConfig.OnUpdate += UpdateInformation;
InventoryConfig.OnCommand += InvDataSetCmd;
//InventoryConfig.OnCommandBySnmp += SetInvEventBySnmp;
InventoryConfig.Show();
}
private void InvDataSetCmd(int sId, int mode, int index, int flag, ref CsDeviceData.DeviceModuleData.DeviceInforation aInvData)
{
DeviceData.ModuleData[0].Information = aInvData;
//OnCommand?.Invoke(sId, mode, index, flag, ref DeviceData.ModuleData[0].ParamData, ref DeviceData.ModuleData[0].CalibriationData);
//SetCmdToCan(sId, mode, index, flag, ref DeviceData.ModuleData[0].ParamData, ref DeviceData.ModuleData[0].CalibriationData);
}
private void UpdateInformation(object sendor)
{
((fmxInventoryConfig)sendor).UpdateData(ref DeviceData.ModuleData[0]);
}
private void checkDBToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "fmxExcelFile")
{
frm.Activate();
return;
}
}
fmxExcelFile DbControl = new fmxExcelFile(Config);
DbControl.Show();
}
private void levelConfigToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void changeLeToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "FmxLevelConfig")
{
frm.Activate();
return;
}
}
FmxLevelConfig LevelControl = new FmxLevelConfig(Config);
LevelControl.ShowDialog();
}
private void changePasswordToolStripMenuItem_Click(object sender, EventArgs e)
{
foreach (Form frm in Application.OpenForms)
{
if (frm.Name == "FmxPasswordChange")
{
frm.Activate();
return;
}
}
FmxPasswordChange ChangePassword = new FmxPasswordChange(Config);
ChangePassword.ShowDialog();
}
#endregion
#region TIMER EVENT
private void tmrDisplay_Tick(object sender, EventArgs e)
{
uTarget.UpdateStatus(Active);
DisplaySystemFwVerModule();
}
#endregion
#region MAKE TOTAL DATA
private void MakeTotalDataAndStatus()
{
if (Config.CommType == csConstData.CommType.COMM_RS485)
{
MakeTotalDataRS485();
MakeTotalStatusRS485();
MakeTotalAlarmRS485();
}
}
private void MakeTotalDataRS485()
{
int j = 0;
int vsum, csum, ssum, hsum, tsum;
int mQty = csUtils.GetModuleQty(Config);
vsum = csum = ssum = hsum = tsum = 0;
for (int i = 0; i < mQty; i++)
{
if (DeviceData.ModuleData[i].ShelfCommFail == false)
{
vsum += DeviceData.ModuleData[i].ValueData.voltage;
csum += DeviceData.ModuleData[i].ValueData.current;
ssum += DeviceData.ModuleData[i].ValueData.SOC;
hsum += DeviceData.ModuleData[i].ValueData.SOH;
tsum += DeviceData.ModuleData[i].AvgData.avgTemp;
j++;
}
}
if (j > 0)
{
DeviceData.TotalData.ValueData.TotalVoltage = (short)(vsum / j);
DeviceData.TotalData.ValueData.TotalCurrent = (short)(csum);
DeviceData.TotalData.ValueData.TotalSOC = (short)(ssum / j);
DeviceData.TotalData.ValueData.TotalSOH = (short)(hsum / j);
DeviceData.TotalData.ValueData.TotalTemp = (short)(tsum / j);
}
else
{
DeviceData.TotalData.ValueData.TotalVoltage = 0;
DeviceData.TotalData.ValueData.TotalCurrent = 0;
DeviceData.TotalData.ValueData.TotalSOC = 0;
DeviceData.TotalData.ValueData.TotalSOH = 0;
DeviceData.TotalData.ValueData.TotalTemp = 0;
}
}
private void MakeTotalStatusRS485()
{
int mQty = csUtils.GetModuleQty(Config);
switch (DeviceData.TotalData.StatusData.status)
{
case 0: // Standby
if (DeviceData.TotalData.ValueData.TotalCurrent > 50) // Discharging 5.0A
{
DeviceData.TotalData.StatusData.status = 2; // Discharging
}
else if (DeviceData.TotalData.ValueData.TotalCurrent < -50) // Charging -5.0A
{
DeviceData.TotalData.StatusData.status = 1; // Charging
}
else
{
bool flag = true;
for (int i = 0; i < mQty; i++)
{
if (DeviceData.ModuleData[i].StatusData.status != 3)
{
flag = false;
break;
}
}
if (flag == true)
{
DeviceData.TotalData.StatusData.status = 3; // Floating
}
}
break;
case 1: // Charging
if (DeviceData.TotalData.ValueData.TotalCurrent > 50) // Discharge -5.0A
{
DeviceData.TotalData.StatusData.status = 2; // Discharging
}
else if (DeviceData.TotalData.ValueData.TotalCurrent > -30) // Charging > -3.0A
{
DeviceData.TotalData.StatusData.status = 0; // Standby
}
else
{
bool flag = true;
for (int i = 0; i < mQty; i++)
{
if (DeviceData.ModuleData[i].StatusData.status != 3)
{
flag = false;
break;
}
}
if (flag == true)
{
DeviceData.TotalData.StatusData.status = 3; // Floating
}
}
break;
case 2: // Discharging
if (DeviceData.TotalData.ValueData.TotalCurrent < -50) // Charging -5.0A
{
DeviceData.TotalData.StatusData.status = 1; // Charging
}
else if (DeviceData.TotalData.ValueData.TotalCurrent < 30) // Discharge 3.0A
{
DeviceData.TotalData.StatusData.status = 0; // Standby
}
else
{
bool flag = true;
for (int i = 0; i < mQty; i++)
{
if (DeviceData.ModuleData[i].StatusData.status != 3)
{
flag = false;
break;
}
}
if (flag == true)
{
DeviceData.TotalData.StatusData.status = 3; // Floating
}
}
break;
case 3: // Floating
if (DeviceData.TotalData.ValueData.TotalCurrent < -50) // Charging -5.0A
{
DeviceData.TotalData.StatusData.status = 1; // Charging
}
else if (DeviceData.TotalData.ValueData.TotalCurrent > 50) // Discharge 5.0A
{
DeviceData.TotalData.StatusData.status = 2; // Discharge
}
else
{
bool flag = true;
for (int i = 0; i < mQty; i++)
{
if (DeviceData.ModuleData[i].StatusData.status != 3)
{
flag = false;
break;
}
}
if (flag == false)
{
DeviceData.TotalData.StatusData.status = 0; // Standby
}
}
break;
}
}
private void MakeTotalAlarmRS485()
{
int mQty = csUtils.GetModuleQty(Config);
bool aTrip, aWarning;
aTrip = aWarning = false;
for (int i = 0; i < mQty; i++)
{
if (DeviceData.ModuleData[i].StatusData.batteryStatus == 2)
{
aTrip = true;
}
else if ((DeviceData.ModuleData[i].StatusData.batteryStatus == 1) || (DeviceData.ModuleData[i].ShelfCommFail))
{
aWarning = true;
}
}
if (aTrip)
{
DeviceData.TotalData.StatusData.batteryStatus = 2;
}
else if (aWarning)
{
DeviceData.TotalData.StatusData.batteryStatus = 1;
}
else
{
DeviceData.TotalData.StatusData.batteryStatus = 0;
}
}
#endregion
#region EVENT CONNECT AND DISCONNECT
// UART 이벤트 연결/해제
private void WireUart(csUartThread t)
{
if (t == null) return;
t.OnUpdate += UpdateDataUart; // EventHandler<ModuleDataEventArgs>
t.OnDataRecv += UartRecvData; // EventHandler<DataRecvEventArgs>
t.OnPrint += CommDataPrint; // EventHandler<PrintEventArgs>
}
private void UnwireUart()
{
if (uartThread == null) return;
uartThread.OnUpdate -= UpdateDataUart;
uartThread.OnDataRecv -= UartRecvData;
uartThread.OnPrint -= CommDataPrint;
}
// RS485(Delta) 이벤트 연결/해제
private void WireRs485(CsUartThreadSB t)
{
if (t == null) return;
t.OnUpdate += UpdateDataRS485; // EventHandler<ModuleDataEventArgs>
t.OnDataRecv += UartRecvData; // EventHandler<DataRecvEventArgs>
t.OnPrint += CommDataPrint; // EventHandler<PrintEventArgs>
}
private void UnwireRs485()
{
if (rs485Thread == null) return;
rs485Thread.OnUpdate -= UpdateDataRS485;
rs485Thread.OnDataRecv -= UartRecvData;
rs485Thread.OnPrint -= CommDataPrint;
}
#endregion
#region EVENT HANDLER
private void UpdateDataUart(object sender, csUartThread.ModuleDataEventArgs e)
{
// 필요시 깊은 복사(바인딩 대상이 스레드 모두에서 변경될 여지가 있으면)
// var snapshot = e.Modules.Select(m => m.DeepCopy()).ToArray();
// DeviceData.ModuleData = snapshot;
DeviceData.ModuleData[0] = e.Module; // 참조 재할당만으로 충분하면 이대로
// ref 제거: UpdateData 시그니처도 ref 없이 받도록 변경 권장
ShelfStatus?.UpdateData(DeviceData.ModuleData);
uDataLog.UpdateData(DeviceData);
}
private void UpdateDataRS485(object sender, CsUartThreadSB.ModuleDataEventArgs e)
{
// 필요시 깊은 복사(바인딩 대상이 스레드 모두에서 변경될 여지가 있으면)
// var snapshot = e.Modules.Select(m => m.DeepCopy()).ToArray();
// DeviceData.ModuleData = snapshot;
DeviceData.ModuleData = e.Modules; // 참조 재할당만으로 충분하면 이대로
// ref 제거: UpdateData 시그니처도 ref 없이 받도록 변경 권장
ShelfStatus?.UpdateData(DeviceData.ModuleData);
MakeTotalDataAndStatus();
MainStatus?.UpdateData(DeviceData);
uDataLog.UpdateData(DeviceData);
}
// 핸들러 (대응되는 형태)
private void UartRecvData(object sender, DataRecvEventArgs e)
{
// e.Data 사용
FwUpdateForm?.RecvData(e.Data);
//HistoryForm?.RecvUartData(e.Data); // 메서드명 확인 (오타 주의)
}
// 핸들러 (대응되는 형태)
private void CommDataPrint(object sender, PrintEventArgs e)
{
var id = e.Id;
var msg = e.Message;
if (!string.IsNullOrEmpty(msg))
uEventLog.EventUpdate(id, msg + "\r\n");
}
private void ErrorOnPrint(object sender, PrintEventArgs e)
{
var id = e.Id;
var msg = e.Message;
if (!string.IsNullOrEmpty(e.Message))
uEventLog.ErrorUpdate(id, msg + "\r\n");
}
#endregion
#region EVENT DB COMMAND TO THREAD
private void UpdateAlarmHistory(DataTable aAlarmHistory)
{
uEventLog.AlarmHistoryUpdate1(aAlarmHistory);
}
#endregion
}
}