1295 lines
45 KiB
C#
1295 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);
|
|
uEventLog.UpdateConfig(Config);
|
|
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
|
|
}
|
|
} |